From dbdc5bcc4afc88f1ba82f25ee3719f49af506187 Mon Sep 17 00:00:00 2001 From: proitlab Date: Wed, 19 Nov 2025 16:23:45 +0700 Subject: [PATCH] First Commit --- .clang-format | 75 + .clangd | 6 + .dockerignore | 2 + .drone.jsonnet | 256 + .drone.yml | 465 + .gitattributes | 4 + .github/ISSUE_TEMPLATE/bugs-and-issues.md | 31 + .github/ISSUE_TEMPLATE/feature_request.md | 13 + .../ISSUE_TEMPLATE/game-connection-issue.md | 15 + .github/workflows/build.yml | 123 + .github/workflows/validate-linux.sh | 497 + .github/workflows/validate-report.sh | 24 + .github/workflows/validate.yml | 56 + .gitignore | 140 + .kick | 14 + AUTHORS.md | 75 + CMakeLists.txt | 12 + COPYING | 12 + Dockerfile.ci | 28 + Dockerfile.release | 23 + LICENSE.txt | 149 + Makefile | 33 + OFFICIAL-RELEASE-STEPS.md | 33 + README.docker.md | 72 + README.md | 3 + RELEASE-NOTES.md | 499 + SECURITY.md | 93 + artwork/AppIcon.png | Bin 0 -> 40879 bytes artwork/AppIcon@2x.png | Bin 0 -> 75421 bytes artwork/AppIcon@3x.png | Bin 0 -> 147491 bytes artwork/AppIcon_1024x1024.png | Bin 0 -> 47728 bytes artwork/AppIcon_20x20.png | Bin 0 -> 621 bytes artwork/AppIcon_29x29.png | Bin 0 -> 21328 bytes artwork/AppIcon_40x40.png | Bin 0 -> 24375 bytes artwork/AppIcon_58x58.png | Bin 0 -> 31213 bytes artwork/AppIcon_60x60.png | Bin 0 -> 1597 bytes artwork/AppIcon_80x80.png | Bin 0 -> 43615 bytes artwork/AppIcon_87x87.png | Bin 0 -> 48062 bytes artwork/AppIcon_90x90.png | Bin 0 -> 4692 bytes artwork/AppIcon_iPad@2x.png | Bin 0 -> 110274 bytes artwork/AppIcon_iPadPro@2x.png | Bin 0 -> 129434 bytes artwork/ZeroTierIcon-WithBorder.png | Bin 0 -> 29866 bytes artwork/ZeroTierIcon.icns | Bin 0 -> 125598 bytes artwork/ZeroTierIcon.ico | Bin 0 -> 370070 bytes artwork/ZeroTierIcon.png | Bin 0 -> 26898 bytes artwork/ZeroTierIcon32x32.png | Bin 0 -> 7219 bytes artwork/ZeroTierIcon512x512.png | Bin 0 -> 51309 bytes artwork/logo.html | 37 + attic/WinUI/APIHandler.cs | 459 + attic/WinUI/AboutView.xaml | 35 + attic/WinUI/AboutView.xaml.cs | 35 + attic/WinUI/App.config | 6 + attic/WinUI/App.xaml | 14 + attic/WinUI/App.xaml.cs | 25 + attic/WinUI/CentralAPI.cs | 256 + attic/WinUI/CentralLogin.cs | 30 + attic/WinUI/CentralNetwork.cs | 48 + attic/WinUI/CentralServer.cs | 23 + attic/WinUI/CentralToken.cs | 21 + attic/WinUI/CentralUser.cs | 51 + attic/WinUI/Fonts/segoeui.ttf | Bin 0 -> 910308 bytes attic/WinUI/Fonts/segoeuib.ttf | Bin 0 -> 898564 bytes attic/WinUI/Fonts/segoeuii.ttf | Bin 0 -> 508344 bytes attic/WinUI/Fonts/segoeuiz.ttf | Bin 0 -> 522076 bytes attic/WinUI/ISwitchable.cs | 13 + attic/WinUI/JoinNetworkView.xaml | 17 + attic/WinUI/JoinNetworkView.xaml.cs | 127 + attic/WinUI/MainWindow.xaml.cs | 233 + attic/WinUI/NetworkInfoView.xaml | 88 + attic/WinUI/NetworkInfoView.xaml.cs | 183 + attic/WinUI/NetworkListView.xaml | 88 + attic/WinUI/NetworkListView.xaml.cs | 85 + attic/WinUI/NetworkMonitor.cs | 203 + attic/WinUI/NetworkNameGenerator.cs | 201 + attic/WinUI/NetworkRoute.cs | 42 + attic/WinUI/NetworksPage.xaml | 13 + attic/WinUI/NetworksPage.xaml.cs | 99 + attic/WinUI/PeersPage.xaml | 26 + attic/WinUI/PeersPage.xaml.cs | 54 + attic/WinUI/PreferencesView.xaml | 30 + attic/WinUI/PreferencesView.xaml.cs | 74 + attic/WinUI/Properties/AssemblyInfo.cs | 56 + attic/WinUI/Properties/Resources.Designer.cs | 73 + attic/WinUI/Properties/Resources.resx | 124 + attic/WinUI/Properties/Settings.Designer.cs | 30 + attic/WinUI/Properties/Settings.settings | 7 + attic/WinUI/Resources/ZeroTierIcon.ico | Bin 0 -> 45451 bytes attic/WinUI/Simple Styles.xaml | 1128 + attic/WinUI/Themes/Generic.xaml | 6 + attic/WinUI/ToolbarItem.xaml | 65 + attic/WinUI/ToolbarItem.xaml.cs | 353 + attic/WinUI/WinUI.csproj | 273 + attic/WinUI/ZeroTierIcon.ico | Bin 0 -> 370070 bytes attic/WinUI/ZeroTierNetwork.cs | 516 + attic/WinUI/ZeroTierPeer.cs | 116 + attic/WinUI/ZeroTierPeerPhysicalPath.cs | 27 + attic/WinUI/ZeroTierStatus.cs | 39 + attic/WinUI/app.manifest | 55 + attic/WinUI/packages.config | 5 + attic/historic/anode/LICENSE.txt | 674 + attic/historic/anode/config.mk.Darwin | 17 + attic/historic/anode/config.mk.Linux | 17 + attic/historic/anode/docs/anode_protocol.txt | 764 + attic/historic/anode/libanode/Makefile | 33 + attic/historic/anode/libanode/address.c | 98 + attic/historic/anode/libanode/aes_digest.c | 85 + attic/historic/anode/libanode/anode.h | 795 + attic/historic/anode/libanode/errors.c | 52 + attic/historic/anode/libanode/identity.c | 110 + attic/historic/anode/libanode/impl/aes.c | 72 + attic/historic/anode/libanode/impl/aes.h | 64 + .../historic/anode/libanode/impl/dictionary.c | 239 + .../historic/anode/libanode/impl/dictionary.h | 126 + attic/historic/anode/libanode/impl/dns_txt.c | 93 + attic/historic/anode/libanode/impl/dns_txt.h | 37 + attic/historic/anode/libanode/impl/ec.c | 219 + attic/historic/anode/libanode/impl/ec.h | 61 + .../anode/libanode/impl/environment.c | 118 + .../anode/libanode/impl/environment.h | 30 + .../anode/libanode/impl/http_client.c | 558 + .../anode/libanode/impl/http_client.h | 200 + attic/historic/anode/libanode/impl/misc.c | 190 + attic/historic/anode/libanode/impl/misc.h | 193 + attic/historic/anode/libanode/impl/mutex.h | 34 + attic/historic/anode/libanode/impl/thread.c | 58 + attic/historic/anode/libanode/impl/thread.h | 65 + attic/historic/anode/libanode/impl/types.h | 25 + .../historic/anode/libanode/network_address.c | 136 + attic/historic/anode/libanode/secure_random.c | 88 + .../anode/libanode/system_transport.c | 948 + attic/historic/anode/libanode/tests/Makefile | 25 + .../historic/anode/libanode/tests/aes-test.c | 191 + .../libanode/tests/anode-secure_random-test.c | 38 + .../anode/libanode/tests/anode-utils-test.c | 75 + .../anode/libanode/tests/anode-zone-test.c | 47 + .../anode/libanode/tests/dictionary-test.c | 149 + attic/historic/anode/libanode/tests/ec-test.c | 97 + .../anode/libanode/tests/environment-test.c | 28 + .../anode/libanode/tests/http_client-test.c | 233 + .../historic/anode/libanode/tests/misc-test.c | 137 + .../libanode/tests/system_transport-test.c | 70 + attic/historic/anode/libanode/uri.c | 185 + .../libanode/utils/anode-make-identity.c | 50 + attic/historic/anode/libanode/zone.c | 184 + attic/historic/anode/libspark/Makefile | 16 + .../experiments/FindGoodSegmentDelimiters.cpp | 161 + .../anode/libspark/experiments/Makefile | 5 + attic/historic/anode/libspark/streamencoder.h | 108 + attic/historic/anode/libspark/wrapper.h | 66 + attic/historic/anode_protocol.txt | 764 + .../ZeroTier One.xcodeproj/project.pbxproj | 391 + .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../macui/ZeroTier One/AboutViewController.h | 33 + .../macui/ZeroTier One/AboutViewController.m | 57 + .../ZeroTier One/AboutViewController.xib | 31 + attic/macui/ZeroTier One/AppDelegate.h | 61 + attic/macui/ZeroTier One/AppDelegate.m | 379 + .../AppIcon.appiconset/Contents.json | 59 + .../ZeroTierIcon512x512.png | Bin 0 -> 51309 bytes .../Assets.xcassets/Contents.json | 6 + .../MenuBarIconMac.imageset/Contents.json | 21 + .../MenuBarIconMac.imageset/MenuBar@2x.png | Bin 0 -> 22973 bytes .../MenuBarIconMac.imageset/Menubar.png | Bin 0 -> 17234 bytes .../Contents.json | 21 + .../MenubarWhite.png | Bin 0 -> 17234 bytes .../MenubarWhite@2x.png | Bin 0 -> 22973 bytes attic/macui/ZeroTier One/AuthtokenCopy.h | 26 + attic/macui/ZeroTier One/AuthtokenCopy.m | 97 + .../ZeroTier One/Base.lproj/MainMenu.xib | 680 + attic/macui/ZeroTier One/Info.plist | 41 + .../ZeroTier One/JoinNetworkViewController.h | 41 + .../ZeroTier One/JoinNetworkViewController.m | 186 + .../JoinNetworkViewController.xib | 91 + attic/macui/ZeroTier One/Network.h | 69 + attic/macui/ZeroTier One/Network.m | 352 + attic/macui/ZeroTier One/NetworkInfoCell.h | 51 + attic/macui/ZeroTier One/NetworkInfoCell.m | 86 + attic/macui/ZeroTier One/NetworkMonitor.h | 45 + attic/macui/ZeroTier One/NetworkMonitor.m | 253 + attic/macui/ZeroTier One/NodeStatus.h | 35 + attic/macui/ZeroTier One/NodeStatus.m | 40 + .../ZeroTier One/PreferencesViewController.h | 31 + .../ZeroTier One/PreferencesViewController.m | 112 + .../PreferencesViewController.xib | 33 + attic/macui/ZeroTier One/ServiceCom.h | 40 + attic/macui/ZeroTier One/ServiceCom.m | 522 + .../ZeroTier One/ShowNetworksViewController.h | 36 + .../ZeroTier One/ShowNetworksViewController.m | 184 + .../ShowNetworksViewController.xib | 394 + .../ZeroTier One/ZeroTier One.entitlements | 5 + attic/macui/ZeroTier One/ZeroTierIcon.icns | Bin 0 -> 125598 bytes attic/macui/ZeroTier One/about.html | 58 + attic/macui/ZeroTier One/main.m | 23 + attic/world/README.md | 7 + attic/world/build.sh | 3 + attic/world/mkworld.cpp | 173 + attic/world/world.bin | Bin 0 -> 570 bytes attic/world/world.c | 3 + backone-cli-completion.bash | 57 + backone.spec | 162 + ci/Dockerfile-build.el6 | 36 + ci/Dockerfile-test.el6 | 4 + ci/scripts/build.sh | 49 + ci/scripts/lib.sh | 63 + ci/scripts/munge_debian_changelog.sh | 37 + ci/scripts/munge_rpm_spec.sh | 36 + ci/scripts/publish.sh | 38 + ci/scripts/test.sh | 55 + controller/ConnectionPool.hpp | 175 + controller/DB.cpp | 422 + controller/DB.hpp | 197 + controller/DBMirrorSet.cpp | 246 + controller/DBMirrorSet.hpp | 73 + controller/EmbeddedNetworkController.cpp | 2139 ++ controller/EmbeddedNetworkController.hpp | 183 + controller/FileDB.cpp | 167 + controller/FileDB.hpp | 47 + controller/LFDB.cpp | 406 + controller/LFDB.hpp | 89 + controller/PostgreSQL.cpp | 1956 ++ controller/PostgreSQL.hpp | 196 + controller/README.md | 55 + controller/Redis.hpp | 15 + cycle_controllers.sh | 9 + debian/changelog | 312 + debian/compat | 1 + debian/control | 19 + debian/control.wheezy | 19 + debian/copyright | 18 + debian/postinst | 11 + debian/rules | 16 + debian/rules.static | 16 + debian/rules.wheezy | 11 + debian/rules.wheezy.static | 11 + debian/source/format | 1 + debian/ufw-zerotier-one | 4 + debian/zerotier-one.init | 49 + debian/zerotier-one.service | 12 + debian/zerotier-one.upstart | 14 + doc/README.md | 6 + doc/build.sh | 42 + doc/contact@zerotier.com.gpg | 52 + doc/manpage_encoding_declaration.UTF-8 | 1 + doc/zerotier-cli.1 | 83 + doc/zerotier-cli.1.md | 68 + doc/zerotier-idtool.1 | 84 + doc/zerotier-idtool.1.md | 65 + doc/zerotier-one.8 | 104 + doc/zerotier-one.8.md | 95 + entrypoint.sh.release | 124 + ext/README.md | 10 + ext/arm32-neon-salsa2012-asm/README.md | 6 + ext/arm32-neon-salsa2012-asm/salsa2012.h | 25 + ext/arm32-neon-salsa2012-asm/salsa2012.s | 2231 ++ ext/bin/tap-windows-ndis6/arm64/zttap300.cat | Bin 0 -> 11761 bytes ext/bin/tap-windows-ndis6/arm64/zttap300.inf | 145 + ext/bin/tap-windows-ndis6/arm64/zttap300.sys | Bin 0 -> 38400 bytes ext/bin/tap-windows-ndis6/x64/zttap300.cat | Bin 0 -> 10769 bytes ext/bin/tap-windows-ndis6/x64/zttap300.inf | 144 + ext/bin/tap-windows-ndis6/x64/zttap300.sys | Bin 0 -> 31744 bytes ext/bin/tap-windows-ndis6/x86/zttap300.cat | Bin 0 -> 10704 bytes ext/bin/tap-windows-ndis6/x86/zttap300.inf | 141 + ext/bin/tap-windows-ndis6/x86/zttap300.sys | Bin 0 -> 35584 bytes ext/central-controller-docker/Dockerfile | 15 + .../Dockerfile.builder | 26 + .../Dockerfile.run_base | 15 + ext/central-controller-docker/Makefile | 16 + ext/central-controller-docker/README.md | 3 + ext/central-controller-docker/main.sh | 115 + ext/cpp-httplib/httplib.h | 9441 ++++++ ext/ed25519-amd64-asm/batch.c | 94 + ext/ed25519-amd64-asm/choose_t.s | 1565 + ext/ed25519-amd64-asm/consts.s | 39 + ext/ed25519-amd64-asm/fe25519.h | 64 + ext/ed25519-amd64-asm/fe25519_add.s | 189 + ext/ed25519-amd64-asm/fe25519_freeze.s | 322 + ext/ed25519-amd64-asm/fe25519_getparity.c | 8 + ext/ed25519-amd64-asm/fe25519_invert.c | 60 + ext/ed25519-amd64-asm/fe25519_iseq.c | 14 + ext/ed25519-amd64-asm/fe25519_iszero.c | 12 + ext/ed25519-amd64-asm/fe25519_mul.s | 865 + ext/ed25519-amd64-asm/fe25519_neg.c | 8 + ext/ed25519-amd64-asm/fe25519_pack.c | 13 + ext/ed25519-amd64-asm/fe25519_pow2523.c | 55 + ext/ed25519-amd64-asm/fe25519_setint.c | 9 + ext/ed25519-amd64-asm/fe25519_square.s | 639 + ext/ed25519-amd64-asm/fe25519_sub.s | 189 + ext/ed25519-amd64-asm/fe25519_unpack.c | 11 + ext/ed25519-amd64-asm/ge25519.h | 95 + ext/ed25519-amd64-asm/ge25519_add.c | 8 + ext/ed25519-amd64-asm/ge25519_add_p1p1.s | 4554 +++ ext/ed25519-amd64-asm/ge25519_base.c | 7 + ext/ed25519-amd64-asm/ge25519_base_niels.data | 1536 + .../ge25519_base_niels_smalltables.data | 768 + .../ge25519_base_slide_multiples.data | 96 + ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s | 2975 ++ ext/ed25519-amd64-asm/ge25519_double.c | 8 + .../ge25519_double_scalarmult.c | 102 + ext/ed25519-amd64-asm/ge25519_isneutral.c | 9 + .../ge25519_multi_scalarmult.c | 102 + ext/ed25519-amd64-asm/ge25519_nielsadd2.s | 5791 ++++ ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s | 3072 ++ ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s | 2236 ++ ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s | 2926 ++ ext/ed25519-amd64-asm/ge25519_pack.c | 13 + .../ge25519_pnielsadd_p1p1.s | 3662 +++ .../ge25519_scalarmult_base.c | 68 + ext/ed25519-amd64-asm/ge25519_unpackneg.c | 60 + ext/ed25519-amd64-asm/heap_rootreplaced.s | 476 + .../heap_rootreplaced_1limb.s | 416 + .../heap_rootreplaced_2limbs.s | 436 + .../heap_rootreplaced_3limbs.s | 456 + ext/ed25519-amd64-asm/hram.c | 16 + ext/ed25519-amd64-asm/hram.h | 8 + ext/ed25519-amd64-asm/implementors | 5 + ext/ed25519-amd64-asm/index_heap.c | 58 + ext/ed25519-amd64-asm/index_heap.h | 31 + ext/ed25519-amd64-asm/keypair.c | 25 + ext/ed25519-amd64-asm/open.c | 49 + ext/ed25519-amd64-asm/sc25519.h | 66 + ext/ed25519-amd64-asm/sc25519_add.s | 232 + ext/ed25519-amd64-asm/sc25519_barrett.s | 1188 + ext/ed25519-amd64-asm/sc25519_from32bytes.c | 55 + ext/ed25519-amd64-asm/sc25519_from64bytes.c | 7 + ext/ed25519-amd64-asm/sc25519_from_shortsc.c | 9 + ext/ed25519-amd64-asm/sc25519_iszero.c | 10 + ext/ed25519-amd64-asm/sc25519_lt.s | 131 + ext/ed25519-amd64-asm/sc25519_mul.c | 12 + ext/ed25519-amd64-asm/sc25519_mul_shortsc.c | 9 + ext/ed25519-amd64-asm/sc25519_slide.c | 49 + ext/ed25519-amd64-asm/sc25519_sub_nored.s | 142 + ext/ed25519-amd64-asm/sc25519_to32bytes.c | 8 + ext/ed25519-amd64-asm/sc25519_window4.c | 27 + ext/ed25519-amd64-asm/sign.c | 162 + ext/ed25519-amd64-asm/ull4_mul.s | 716 + ext/hiredis-0.14.1/.gitignore | 6 + ext/hiredis-0.14.1/.travis.yml | 45 + ext/hiredis-0.14.1/CHANGELOG.md | 190 + ext/hiredis-0.14.1/COPYING | 29 + ext/hiredis-0.14.1/Makefile | 214 + ext/hiredis-0.14.1/README.md | 410 + ext/hiredis-0.14.1/adapters/ae.h | 127 + ext/hiredis-0.14.1/adapters/glib.h | 153 + ext/hiredis-0.14.1/adapters/ivykis.h | 81 + ext/hiredis-0.14.1/adapters/libev.h | 147 + ext/hiredis-0.14.1/adapters/libevent.h | 108 + ext/hiredis-0.14.1/adapters/libuv.h | 122 + ext/hiredis-0.14.1/adapters/macosx.h | 114 + ext/hiredis-0.14.1/adapters/qt.h | 135 + ext/hiredis-0.14.1/alloc.c | 65 + ext/hiredis-0.14.1/alloc.h | 53 + ext/hiredis-0.14.1/appveyor.yml | 23 + ext/hiredis-0.14.1/async.c | 717 + ext/hiredis-0.14.1/async.h | 130 + ext/hiredis-0.14.1/dict.c | 339 + ext/hiredis-0.14.1/dict.h | 126 + ext/hiredis-0.14.1/examples/example-ae.c | 62 + ext/hiredis-0.14.1/examples/example-glib.c | 73 + ext/hiredis-0.14.1/examples/example-ivykis.c | 58 + ext/hiredis-0.14.1/examples/example-libev.c | 52 + .../examples/example-libevent.c | 53 + ext/hiredis-0.14.1/examples/example-libuv.c | 53 + ext/hiredis-0.14.1/examples/example-macosx.c | 66 + ext/hiredis-0.14.1/examples/example-qt.cpp | 46 + ext/hiredis-0.14.1/examples/example-qt.h | 32 + ext/hiredis-0.14.1/examples/example.c | 78 + ext/hiredis-0.14.1/fmacros.h | 12 + ext/hiredis-0.14.1/hiredis.c | 1006 + ext/hiredis-0.14.1/hiredis.h | 200 + ext/hiredis-0.14.1/include/hiredis/alloc.h | 53 + ext/hiredis-0.14.1/include/hiredis/async.h | 130 + ext/hiredis-0.14.1/include/hiredis/dict.h | 126 + ext/hiredis-0.14.1/include/hiredis/fmacros.h | 12 + ext/hiredis-0.14.1/include/hiredis/hiredis.h | 200 + ext/hiredis-0.14.1/include/hiredis/net.h | 49 + ext/hiredis-0.14.1/include/hiredis/read.h | 111 + ext/hiredis-0.14.1/include/hiredis/sds.h | 273 + ext/hiredis-0.14.1/include/hiredis/sdsalloc.h | 42 + ext/hiredis-0.14.1/include/hiredis/win32.h | 42 + ext/hiredis-0.14.1/lib/centos8/libhiredis.a | Bin 0 -> 485314 bytes ext/hiredis-0.14.1/lib/macos/libhiredis.a | Bin 0 -> 532024 bytes ext/hiredis-0.14.1/net.c | 477 + ext/hiredis-0.14.1/net.h | 49 + ext/hiredis-0.14.1/read.c | 598 + ext/hiredis-0.14.1/read.h | 111 + ext/hiredis-0.14.1/sds.c | 1272 + ext/hiredis-0.14.1/sds.h | 273 + ext/hiredis-0.14.1/sdsalloc.h | 42 + ext/hiredis-0.14.1/test.c | 923 + ext/hiredis-0.14.1/win32.h | 42 + ext/hiredis-1.0.2/.gitignore | 9 + ext/hiredis-1.0.2/.travis.yml | 131 + ext/hiredis-1.0.2/CHANGELOG.md | 364 + ext/hiredis-1.0.2/CMakeLists.txt | 165 + ext/hiredis-1.0.2/COPYING | 29 + ext/hiredis-1.0.2/Makefile | 308 + ext/hiredis-1.0.2/README.md | 664 + ext/hiredis-1.0.2/adapters/ae.h | 130 + ext/hiredis-1.0.2/adapters/glib.h | 156 + ext/hiredis-1.0.2/adapters/ivykis.h | 84 + ext/hiredis-1.0.2/adapters/libev.h | 179 + ext/hiredis-1.0.2/adapters/libevent.h | 175 + ext/hiredis-1.0.2/adapters/libuv.h | 117 + ext/hiredis-1.0.2/adapters/macosx.h | 115 + ext/hiredis-1.0.2/adapters/qt.h | 135 + ext/hiredis-1.0.2/alloc.c | 86 + ext/hiredis-1.0.2/alloc.h | 91 + ext/hiredis-1.0.2/appveyor.yml | 24 + ext/hiredis-1.0.2/async.c | 887 + ext/hiredis-1.0.2/async.h | 147 + ext/hiredis-1.0.2/async_private.h | 75 + ext/hiredis-1.0.2/dict.c | 352 + ext/hiredis-1.0.2/dict.h | 126 + ext/hiredis-1.0.2/examples/CMakeLists.txt | 49 + ext/hiredis-1.0.2/examples/example-ae.c | 62 + ext/hiredis-1.0.2/examples/example-glib.c | 73 + ext/hiredis-1.0.2/examples/example-ivykis.c | 60 + ext/hiredis-1.0.2/examples/example-libev.c | 54 + .../examples/example-libevent-ssl.c | 90 + ext/hiredis-1.0.2/examples/example-libevent.c | 67 + ext/hiredis-1.0.2/examples/example-libuv.c | 56 + ext/hiredis-1.0.2/examples/example-macosx.c | 66 + ext/hiredis-1.0.2/examples/example-push.c | 160 + ext/hiredis-1.0.2/examples/example-qt.cpp | 46 + ext/hiredis-1.0.2/examples/example-qt.h | 32 + ext/hiredis-1.0.2/examples/example-ssl.c | 110 + ext/hiredis-1.0.2/examples/example.c | 91 + ext/hiredis-1.0.2/fmacros.h | 12 + ext/hiredis-1.0.2/hiredis-config.cmake.in | 13 + ext/hiredis-1.0.2/hiredis.c | 1174 + ext/hiredis-1.0.2/hiredis.h | 336 + ext/hiredis-1.0.2/hiredis.pc.in | 12 + ext/hiredis-1.0.2/hiredis_ssl-config.cmake.in | 13 + ext/hiredis-1.0.2/hiredis_ssl.h | 127 + ext/hiredis-1.0.2/hiredis_ssl.pc.in | 12 + ext/hiredis-1.0.2/include/hiredis/alloc.h | 91 + ext/hiredis-1.0.2/include/hiredis/async.h | 147 + .../include/hiredis/async_private.h | 75 + ext/hiredis-1.0.2/include/hiredis/dict.h | 126 + ext/hiredis-1.0.2/include/hiredis/fmacros.h | 12 + ext/hiredis-1.0.2/include/hiredis/hiredis.h | 336 + .../include/hiredis/hiredis_ssl.h | 127 + ext/hiredis-1.0.2/include/hiredis/net.h | 56 + ext/hiredis-1.0.2/include/hiredis/read.h | 129 + ext/hiredis-1.0.2/include/hiredis/sds.h | 278 + ext/hiredis-1.0.2/include/hiredis/sdsalloc.h | 44 + .../include/hiredis/sockcompat.h | 92 + ext/hiredis-1.0.2/include/hiredis/win32.h | 56 + .../lib/ubuntu22.04/amd64/libhiredis.a | Bin 0 -> 557016 bytes .../lib/ubuntu22.04/arm64/libhiredis.a | Bin 0 -> 495416 bytes ext/hiredis-1.0.2/net.c | 612 + ext/hiredis-1.0.2/net.h | 56 + ext/hiredis-1.0.2/read.c | 739 + ext/hiredis-1.0.2/read.h | 129 + ext/hiredis-1.0.2/sds.c | 1289 + ext/hiredis-1.0.2/sds.h | 278 + ext/hiredis-1.0.2/sdsalloc.h | 44 + ext/hiredis-1.0.2/sockcompat.c | 248 + ext/hiredis-1.0.2/sockcompat.h | 92 + ext/hiredis-1.0.2/ssl.c | 526 + ext/hiredis-1.0.2/test.c | 1401 + ext/hiredis-1.0.2/test.sh | 78 + ext/hiredis-1.0.2/win32.h | 56 + ext/http-parser/AUTHORS | 68 + ext/http-parser/LICENSE-MIT | 23 + ext/http-parser/README.md | 246 + ext/http-parser/http_parser.c | 2470 ++ ext/http-parser/http_parser.h | 432 + ext/inja/LICENSE | 21 + ext/inja/README.md | 391 + ext/inja/inja.hpp | 2949 ++ .../linux/zerotier-containerized/Dockerfile | 28 + .../linux/zerotier-containerized/main.sh | 10 + .../linux/zerotier-one.init.rhel6 | 138 + ext/installfiles/linux/zerotier-one.te | 14 + ext/installfiles/mac-update/updater.tmpl.sh | 49 + ext/installfiles/mac/BackOne.pkgproj | 1119 + ext/installfiles/mac/com.backone.plist | 22 + ext/installfiles/mac/get-proxy-settings.sh | 26 + ext/installfiles/mac/launch.sh | 4 + ext/installfiles/mac/postinst.sh | 51 + ext/installfiles/mac/preinst.sh | 39 + ext/installfiles/mac/uninstall.sh | 44 + ...r One Virtual Network Port (NDIS6_x64).aip | 187 + ...r One Virtual Network Port (NDIS6_x86).aip | 188 + ext/installfiles/windows/ZeroTier One.aip | 528 + .../windows/ZeroTier One.back.aip | 558 + ext/libnatpmp/Changelog.txt | 98 + ext/libnatpmp/JavaTest.java | 42 + ext/libnatpmp/LICENSE | 26 + ext/libnatpmp/Makefile | 177 + ext/libnatpmp/README | 7 + ext/libnatpmp/build.bat | 30 + ext/libnatpmp/declspec.h | 21 + .../miniupnp/libnatpmp/LibraryExtractor.java | 238 + .../fr/free/miniupnp/libnatpmp/NatPmp.java | 50 + .../miniupnp/libnatpmp/NatPmpResponse.java | 28 + .../fr/free/miniupnp/libnatpmp/URLUtils.java | 81 + ext/libnatpmp/getgateway.c | 575 + ext/libnatpmp/getgateway.h | 49 + ext/libnatpmp/libnatpmpmodule.c | 281 + ext/libnatpmp/msvc/libnatpmp.sln | 29 + ext/libnatpmp/msvc/libnatpmp.vcproj | 195 + ext/libnatpmp/msvc/natpmpc-static.vcproj | 195 + ext/libnatpmp/natpmp-jni.c | 157 + ext/libnatpmp/natpmp.c | 383 + ext/libnatpmp/natpmp.def | 11 + ext/libnatpmp/natpmp.h | 219 + ext/libnatpmp/natpmpc.1 | 19 + ext/libnatpmp/natpmpc.c | 244 + ext/libnatpmp/setup.py | 18 + ext/libnatpmp/setupmingw32.py | 17 + ext/libnatpmp/testgetgateway.c | 57 + ext/libnatpmp/wingettimeofday.c | 60 + ext/libnatpmp/wingettimeofday.h | 39 + ext/libpqxx-7.7.3/.circleci/config.yml | 60 + ext/libpqxx-7.7.3/.clang-format | 71 + ext/libpqxx-7.7.3/.cmake-format | 184 + ext/libpqxx-7.7.3/.github/workflows/stale.yml | 19 + ext/libpqxx-7.7.3/.gitignore | 49 + ext/libpqxx-7.7.3/.lgtm.yml | 9 + ext/libpqxx-7.7.3/.lift/ignoreFiles | 3 + ext/libpqxx-7.7.3/AUTHORS | 4 + ext/libpqxx-7.7.3/BUILDING-cmake.md | 272 + ext/libpqxx-7.7.3/BUILDING-configure.md | 275 + ext/libpqxx-7.7.3/CMakeLists.txt | 66 + ext/libpqxx-7.7.3/COPYING | 27 + ext/libpqxx-7.7.3/Makefile.am | 23 + ext/libpqxx-7.7.3/Makefile.in | 1253 + ext/libpqxx-7.7.3/NEWS | 1040 + ext/libpqxx-7.7.3/README.md | 199 + ext/libpqxx-7.7.3/VERSION | 1 + ext/libpqxx-7.7.3/aclocal.m4 | 1187 + ext/libpqxx-7.7.3/appveyor.yml | 30 + ext/libpqxx-7.7.3/autogen.sh | 44 + ext/libpqxx-7.7.3/cmake/config.cmake | 157 + ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake | 4 + ext/libpqxx-7.7.3/compile_flags.in | 1 + ext/libpqxx-7.7.3/config-tests/README.md | 22 + .../config-tests/charconv_float.cxx | 16 + .../config-tests/charconv_int.cxx | 16 + ext/libpqxx-7.7.3/config-tests/cmp.cxx | 8 + ext/libpqxx-7.7.3/config-tests/concepts.cxx | 21 + .../config-tests/cxa_demangle.cxx | 19 + ext/libpqxx-7.7.3/config-tests/fs.cxx | 9 + ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx | 10 + .../config-tests/gcc_visibility.cxx | 12 + ext/libpqxx-7.7.3/config-tests/likely.cxx | 15 + .../config-tests/multidim-subscript.cxx | 14 + ext/libpqxx-7.7.3/config-tests/need_fslib.cxx | 21 + ext/libpqxx-7.7.3/config-tests/poll.cxx | 7 + ext/libpqxx-7.7.3/config-tests/sleep_for.cxx | 28 + ext/libpqxx-7.7.3/config-tests/span.cxx | 8 + ext/libpqxx-7.7.3/config-tests/strerror_r.cxx | 14 + ext/libpqxx-7.7.3/config-tests/strerror_s.cxx | 11 + .../config-tests/thread_local.cxx | 15 + .../config-tests/year_month_day.cxx | 7 + ext/libpqxx-7.7.3/config/Makefile.am | 8 + ext/libpqxx-7.7.3/config/Makefile.in | 470 + ext/libpqxx-7.7.3/config/compile | 348 + ext/libpqxx-7.7.3/config/config.guess | 1462 + ext/libpqxx-7.7.3/config/config.sub | 1825 ++ ext/libpqxx-7.7.3/config/depcomp | 791 + ext/libpqxx-7.7.3/config/install-sh | 520 + ext/libpqxx-7.7.3/config/ltmain.sh | 11251 +++++++ ext/libpqxx-7.7.3/config/m4/Makefile.am | 3 + ext/libpqxx-7.7.3/config/m4/libtool.m4 | 8394 +++++ ext/libpqxx-7.7.3/config/m4/ltoptions.m4 | 437 + ext/libpqxx-7.7.3/config/m4/ltsugar.m4 | 124 + ext/libpqxx-7.7.3/config/m4/ltversion.m4 | 23 + ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 | 99 + ext/libpqxx-7.7.3/config/missing | 215 + ext/libpqxx-7.7.3/config/mkinstalldirs | 40 + ext/libpqxx-7.7.3/config/test-driver | 148 + ext/libpqxx-7.7.3/configitems | 26 + ext/libpqxx-7.7.3/configure | 20443 ++++++++++++ ext/libpqxx-7.7.3/configure.ac | 738 + ext/libpqxx-7.7.3/doc/CMakeLists.txt | 50 + ext/libpqxx-7.7.3/doc/Doxyfile.in | 1280 + ext/libpqxx-7.7.3/doc/Makefile.am | 51 + ext/libpqxx-7.7.3/doc/Makefile.in | 507 + ext/libpqxx-7.7.3/doc/conf.py | 199 + ext/libpqxx-7.7.3/doc/index.rst | 20 + ext/libpqxx-7.7.3/include/CMakeLists.txt | 68 + .../include/CMakeLists.txt.template | 23 + ext/libpqxx-7.7.3/include/Makefile.am | 79 + ext/libpqxx-7.7.3/include/Makefile.in | 802 + ext/libpqxx-7.7.3/include/pqxx/Makefile.am | 13 + ext/libpqxx-7.7.3/include/pqxx/Makefile.in | 556 + ext/libpqxx-7.7.3/include/pqxx/array | 6 + ext/libpqxx-7.7.3/include/pqxx/array.hxx | 103 + ext/libpqxx-7.7.3/include/pqxx/binarystring | 6 + .../include/pqxx/binarystring.hxx | 236 + ext/libpqxx-7.7.3/include/pqxx/blob | 6 + ext/libpqxx-7.7.3/include/pqxx/blob.hxx | 351 + ext/libpqxx-7.7.3/include/pqxx/composite | 6 + ext/libpqxx-7.7.3/include/pqxx/composite.hxx | 149 + ext/libpqxx-7.7.3/include/pqxx/config.h.in | 121 + ext/libpqxx-7.7.3/include/pqxx/connection | 8 + ext/libpqxx-7.7.3/include/pqxx/connection.hxx | 1261 + ext/libpqxx-7.7.3/include/pqxx/cursor | 8 + ext/libpqxx-7.7.3/include/pqxx/cursor.hxx | 483 + ext/libpqxx-7.7.3/include/pqxx/dbtransaction | 8 + .../include/pqxx/dbtransaction.hxx | 70 + .../include/pqxx/doc/accessing-results.md | 157 + .../include/pqxx/doc/binary-data.md | 56 + .../include/pqxx/doc/datatypes.md | 373 + .../include/pqxx/doc/escaping.md | 74 + .../include/pqxx/doc/getting-started.md | 142 + .../include/pqxx/doc/mainpage.md | 28 + .../include/pqxx/doc/mainpage.md.template | 28 + .../include/pqxx/doc/parameters.md | 90 + .../include/pqxx/doc/performance.md | 24 + .../include/pqxx/doc/prepared-statement.md | 125 + ext/libpqxx-7.7.3/include/pqxx/doc/streams.md | 107 + .../include/pqxx/doc/thread-safety.md | 29 + ext/libpqxx-7.7.3/include/pqxx/errorhandler | 8 + .../include/pqxx/errorhandler.hxx | 92 + ext/libpqxx-7.7.3/include/pqxx/except | 8 + ext/libpqxx-7.7.3/include/pqxx/except.hxx | 447 + ext/libpqxx-7.7.3/include/pqxx/field | 8 + ext/libpqxx-7.7.3/include/pqxx/field.hxx | 542 + .../include/pqxx/internal/array-composite.hxx | 305 + .../include/pqxx/internal/callgate.hxx | 70 + .../include/pqxx/internal/concat.hxx | 45 + .../include/pqxx/internal/conversions.hxx | 1188 + .../include/pqxx/internal/encoding_group.hxx | 60 + .../include/pqxx/internal/encodings.hxx | 90 + .../gates/connection-errorhandler.hxx | 26 + .../internal/gates/connection-largeobject.hxx | 35 + .../connection-notification_receiver.hxx | 29 + .../internal/gates/connection-pipeline.hxx | 23 + .../internal/gates/connection-sql_cursor.hxx | 19 + .../internal/gates/connection-stream_from.hxx | 15 + .../internal/gates/connection-stream_to.hxx | 17 + .../internal/gates/connection-transaction.hxx | 44 + .../gates/errorhandler-connection.hxx | 13 + .../gates/icursor_iterator-icursorstream.hxx | 24 + .../gates/icursorstream-icursor_iterator.hxx | 32 + .../pqxx/internal/gates/result-connection.hxx | 14 + .../pqxx/internal/gates/result-creation.hxx | 24 + .../pqxx/internal/gates/result-pipeline.hxx | 16 + .../pqxx/internal/gates/result-sql_cursor.hxx | 13 + .../internal/gates/transaction-sql_cursor.hxx | 10 + .../gates/transaction-transaction_focus.hxx | 30 + .../include/pqxx/internal/header-post.hxx | 22 + .../include/pqxx/internal/header-pre.hxx | 169 + .../pqxx/internal/ignore-deprecated-post.hxx | 15 + .../pqxx/internal/ignore-deprecated-pre.hxx | 28 + .../include/pqxx/internal/libpq-forward.hxx | 31 + .../include/pqxx/internal/result_iter.hxx | 124 + .../include/pqxx/internal/result_iterator.hxx | 389 + .../include/pqxx/internal/sql_cursor.hxx | 118 + .../pqxx/internal/statement_parameters.hxx | 131 + .../include/pqxx/internal/stream_iterator.hxx | 105 + .../include/pqxx/internal/wait.hxx | 18 + ext/libpqxx-7.7.3/include/pqxx/isolation | 8 + ext/libpqxx-7.7.3/include/pqxx/isolation.hxx | 75 + ext/libpqxx-7.7.3/include/pqxx/largeobject | 8 + .../include/pqxx/largeobject.hxx | 735 + ext/libpqxx-7.7.3/include/pqxx/nontransaction | 8 + .../include/pqxx/nontransaction.hxx | 76 + ext/libpqxx-7.7.3/include/pqxx/notification | 8 + .../include/pqxx/notification.hxx | 94 + ext/libpqxx-7.7.3/include/pqxx/params | 8 + ext/libpqxx-7.7.3/include/pqxx/params.hxx | 383 + ext/libpqxx-7.7.3/include/pqxx/pipeline | 8 + ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx | 237 + ext/libpqxx-7.7.3/include/pqxx/pqxx | 28 + .../include/pqxx/prepared_statement | 3 + .../include/pqxx/prepared_statement.hxx | 3 + ext/libpqxx-7.7.3/include/pqxx/range | 6 + ext/libpqxx-7.7.3/include/pqxx/range.hxx | 515 + ext/libpqxx-7.7.3/include/pqxx/result | 16 + ext/libpqxx-7.7.3/include/pqxx/result.hxx | 335 + .../include/pqxx/robusttransaction | 8 + .../include/pqxx/robusttransaction.hxx | 120 + ext/libpqxx-7.7.3/include/pqxx/row | 11 + ext/libpqxx-7.7.3/include/pqxx/row.hxx | 561 + ext/libpqxx-7.7.3/include/pqxx/separated_list | 6 + .../include/pqxx/separated_list.hxx | 142 + ext/libpqxx-7.7.3/include/pqxx/strconv | 6 + ext/libpqxx-7.7.3/include/pqxx/strconv.hxx | 468 + ext/libpqxx-7.7.3/include/pqxx/stream_from | 8 + .../include/pqxx/stream_from.hxx | 361 + ext/libpqxx-7.7.3/include/pqxx/stream_to | 8 + ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx | 455 + ext/libpqxx-7.7.3/include/pqxx/subtransaction | 8 + .../include/pqxx/subtransaction.hxx | 96 + ext/libpqxx-7.7.3/include/pqxx/time | 6 + ext/libpqxx-7.7.3/include/pqxx/time.hxx | 88 + ext/libpqxx-7.7.3/include/pqxx/transaction | 8 + .../include/pqxx/transaction.hxx | 108 + .../include/pqxx/transaction_base | 9 + .../include/pqxx/transaction_base.hxx | 810 + .../include/pqxx/transaction_focus | 7 + .../include/pqxx/transaction_focus.hxx | 89 + ext/libpqxx-7.7.3/include/pqxx/transactor | 8 + ext/libpqxx-7.7.3/include/pqxx/transactor.hxx | 147 + ext/libpqxx-7.7.3/include/pqxx/types | 7 + ext/libpqxx-7.7.3/include/pqxx/types.hxx | 173 + ext/libpqxx-7.7.3/include/pqxx/util | 6 + ext/libpqxx-7.7.3/include/pqxx/util.hxx | 521 + ext/libpqxx-7.7.3/include/pqxx/version | 7 + ext/libpqxx-7.7.3/include/pqxx/version.hxx | 55 + .../include/pqxx/version.hxx.template | 55 + ext/libpqxx-7.7.3/include/pqxx/zview | 6 + ext/libpqxx-7.7.3/include/pqxx/zview.hxx | 163 + .../ubuntu22.04/amd64/include/pqxx/array | 6 + .../ubuntu22.04/amd64/include/pqxx/array.hxx | 103 + .../amd64/include/pqxx/binarystring | 6 + .../amd64/include/pqxx/binarystring.hxx | 236 + .../ubuntu22.04/amd64/include/pqxx/blob | 6 + .../ubuntu22.04/amd64/include/pqxx/blob.hxx | 351 + .../ubuntu22.04/amd64/include/pqxx/composite | 6 + .../amd64/include/pqxx/composite.hxx | 149 + .../include/pqxx/config-public-compiler.h | 81 + .../ubuntu22.04/amd64/include/pqxx/connection | 8 + .../amd64/include/pqxx/connection.hxx | 1261 + .../ubuntu22.04/amd64/include/pqxx/cursor | 8 + .../ubuntu22.04/amd64/include/pqxx/cursor.hxx | 483 + .../amd64/include/pqxx/dbtransaction | 8 + .../amd64/include/pqxx/dbtransaction.hxx | 70 + .../amd64/include/pqxx/errorhandler | 8 + .../amd64/include/pqxx/errorhandler.hxx | 92 + .../ubuntu22.04/amd64/include/pqxx/except | 8 + .../ubuntu22.04/amd64/include/pqxx/except.hxx | 447 + .../ubuntu22.04/amd64/include/pqxx/field | 8 + .../ubuntu22.04/amd64/include/pqxx/field.hxx | 542 + .../include/pqxx/internal/array-composite.hxx | 305 + .../amd64/include/pqxx/internal/callgate.hxx | 70 + .../amd64/include/pqxx/internal/concat.hxx | 45 + .../include/pqxx/internal/conversions.hxx | 1188 + .../include/pqxx/internal/encoding_group.hxx | 60 + .../amd64/include/pqxx/internal/encodings.hxx | 90 + .../gates/connection-errorhandler.hxx | 26 + .../internal/gates/connection-largeobject.hxx | 35 + .../connection-notification_receiver.hxx | 29 + .../internal/gates/connection-pipeline.hxx | 23 + .../internal/gates/connection-sql_cursor.hxx | 19 + .../internal/gates/connection-stream_from.hxx | 15 + .../internal/gates/connection-stream_to.hxx | 17 + .../internal/gates/connection-transaction.hxx | 44 + .../gates/errorhandler-connection.hxx | 13 + .../gates/icursor_iterator-icursorstream.hxx | 24 + .../gates/icursorstream-icursor_iterator.hxx | 32 + .../pqxx/internal/gates/result-connection.hxx | 14 + .../pqxx/internal/gates/result-creation.hxx | 24 + .../pqxx/internal/gates/result-pipeline.hxx | 16 + .../pqxx/internal/gates/result-sql_cursor.hxx | 13 + .../internal/gates/transaction-sql_cursor.hxx | 10 + .../gates/transaction-transaction_focus.hxx | 30 + .../include/pqxx/internal/header-post.hxx | 22 + .../include/pqxx/internal/header-pre.hxx | 169 + .../pqxx/internal/ignore-deprecated-post.hxx | 15 + .../pqxx/internal/ignore-deprecated-pre.hxx | 28 + .../include/pqxx/internal/libpq-forward.hxx | 31 + .../include/pqxx/internal/result_iter.hxx | 124 + .../include/pqxx/internal/result_iterator.hxx | 389 + .../include/pqxx/internal/sql_cursor.hxx | 118 + .../pqxx/internal/statement_parameters.hxx | 131 + .../include/pqxx/internal/stream_iterator.hxx | 105 + .../amd64/include/pqxx/internal/wait.hxx | 18 + .../ubuntu22.04/amd64/include/pqxx/isolation | 8 + .../amd64/include/pqxx/isolation.hxx | 75 + .../amd64/include/pqxx/largeobject | 8 + .../amd64/include/pqxx/largeobject.hxx | 735 + .../amd64/include/pqxx/nontransaction | 8 + .../amd64/include/pqxx/nontransaction.hxx | 76 + .../amd64/include/pqxx/notification | 8 + .../amd64/include/pqxx/notification.hxx | 94 + .../ubuntu22.04/amd64/include/pqxx/params | 8 + .../ubuntu22.04/amd64/include/pqxx/params.hxx | 383 + .../ubuntu22.04/amd64/include/pqxx/pipeline | 8 + .../amd64/include/pqxx/pipeline.hxx | 237 + .../ubuntu22.04/amd64/include/pqxx/pqxx | 28 + .../amd64/include/pqxx/prepared_statement | 3 + .../amd64/include/pqxx/prepared_statement.hxx | 3 + .../ubuntu22.04/amd64/include/pqxx/range | 6 + .../ubuntu22.04/amd64/include/pqxx/range.hxx | 515 + .../ubuntu22.04/amd64/include/pqxx/result | 16 + .../ubuntu22.04/amd64/include/pqxx/result.hxx | 335 + .../amd64/include/pqxx/robusttransaction | 8 + .../amd64/include/pqxx/robusttransaction.hxx | 120 + .../ubuntu22.04/amd64/include/pqxx/row | 11 + .../ubuntu22.04/amd64/include/pqxx/row.hxx | 561 + .../amd64/include/pqxx/separated_list | 6 + .../amd64/include/pqxx/separated_list.hxx | 142 + .../ubuntu22.04/amd64/include/pqxx/strconv | 6 + .../amd64/include/pqxx/strconv.hxx | 468 + .../amd64/include/pqxx/stream_from | 8 + .../amd64/include/pqxx/stream_from.hxx | 361 + .../ubuntu22.04/amd64/include/pqxx/stream_to | 8 + .../amd64/include/pqxx/stream_to.hxx | 455 + .../amd64/include/pqxx/subtransaction | 8 + .../amd64/include/pqxx/subtransaction.hxx | 96 + .../ubuntu22.04/amd64/include/pqxx/time | 6 + .../ubuntu22.04/amd64/include/pqxx/time.hxx | 88 + .../amd64/include/pqxx/transaction | 8 + .../amd64/include/pqxx/transaction.hxx | 108 + .../amd64/include/pqxx/transaction_base | 9 + .../amd64/include/pqxx/transaction_base.hxx | 810 + .../amd64/include/pqxx/transaction_focus | 7 + .../amd64/include/pqxx/transaction_focus.hxx | 89 + .../ubuntu22.04/amd64/include/pqxx/transactor | 8 + .../amd64/include/pqxx/transactor.hxx | 147 + .../ubuntu22.04/amd64/include/pqxx/types | 7 + .../ubuntu22.04/amd64/include/pqxx/types.hxx | 173 + .../ubuntu22.04/amd64/include/pqxx/util | 6 + .../ubuntu22.04/amd64/include/pqxx/util.hxx | 521 + .../ubuntu22.04/amd64/include/pqxx/version | 7 + .../amd64/include/pqxx/version.hxx | 55 + .../ubuntu22.04/amd64/include/pqxx/zview | 6 + .../ubuntu22.04/amd64/include/pqxx/zview.hxx | 163 + .../libpqxx/libpqxx-config-version.cmake | 70 + .../lib/cmake/libpqxx/libpqxx-config.cmake | 4 + .../libpqxx/libpqxx-targets-noconfig.cmake | 19 + .../lib/cmake/libpqxx/libpqxx-targets.cmake | 99 + .../ubuntu22.04/amd64/lib/libpqxx-7.7.a | Bin 0 -> 4600578 bytes .../install/ubuntu22.04/amd64/lib/libpqxx.a | 1 + .../share/doc/libpqxx/accessing-results.md | 157 + .../amd64/share/doc/libpqxx/binary-data.md | 56 + .../amd64/share/doc/libpqxx/datatypes.md | 373 + .../amd64/share/doc/libpqxx/escaping.md | 74 + .../share/doc/libpqxx/getting-started.md | 142 + .../amd64/share/doc/libpqxx/mainpage.md | 28 + .../amd64/share/doc/libpqxx/parameters.md | 90 + .../amd64/share/doc/libpqxx/performance.md | 24 + .../share/doc/libpqxx/prepared-statement.md | 125 + .../amd64/share/doc/libpqxx/streams.md | 107 + .../amd64/share/doc/libpqxx/thread-safety.md | 29 + .../ubuntu22.04/arm64/include/pqxx/array | 6 + .../ubuntu22.04/arm64/include/pqxx/array.hxx | 103 + .../arm64/include/pqxx/binarystring | 6 + .../arm64/include/pqxx/binarystring.hxx | 236 + .../ubuntu22.04/arm64/include/pqxx/blob | 6 + .../ubuntu22.04/arm64/include/pqxx/blob.hxx | 351 + .../ubuntu22.04/arm64/include/pqxx/composite | 6 + .../arm64/include/pqxx/composite.hxx | 149 + .../include/pqxx/config-public-compiler.h | 81 + .../ubuntu22.04/arm64/include/pqxx/connection | 8 + .../arm64/include/pqxx/connection.hxx | 1261 + .../ubuntu22.04/arm64/include/pqxx/cursor | 8 + .../ubuntu22.04/arm64/include/pqxx/cursor.hxx | 483 + .../arm64/include/pqxx/dbtransaction | 8 + .../arm64/include/pqxx/dbtransaction.hxx | 70 + .../arm64/include/pqxx/errorhandler | 8 + .../arm64/include/pqxx/errorhandler.hxx | 92 + .../ubuntu22.04/arm64/include/pqxx/except | 8 + .../ubuntu22.04/arm64/include/pqxx/except.hxx | 447 + .../ubuntu22.04/arm64/include/pqxx/field | 8 + .../ubuntu22.04/arm64/include/pqxx/field.hxx | 542 + .../include/pqxx/internal/array-composite.hxx | 305 + .../arm64/include/pqxx/internal/callgate.hxx | 70 + .../arm64/include/pqxx/internal/concat.hxx | 45 + .../include/pqxx/internal/conversions.hxx | 1188 + .../include/pqxx/internal/encoding_group.hxx | 60 + .../arm64/include/pqxx/internal/encodings.hxx | 90 + .../gates/connection-errorhandler.hxx | 26 + .../internal/gates/connection-largeobject.hxx | 35 + .../connection-notification_receiver.hxx | 29 + .../internal/gates/connection-pipeline.hxx | 23 + .../internal/gates/connection-sql_cursor.hxx | 19 + .../internal/gates/connection-stream_from.hxx | 15 + .../internal/gates/connection-stream_to.hxx | 17 + .../internal/gates/connection-transaction.hxx | 44 + .../gates/errorhandler-connection.hxx | 13 + .../gates/icursor_iterator-icursorstream.hxx | 24 + .../gates/icursorstream-icursor_iterator.hxx | 32 + .../pqxx/internal/gates/result-connection.hxx | 14 + .../pqxx/internal/gates/result-creation.hxx | 24 + .../pqxx/internal/gates/result-pipeline.hxx | 16 + .../pqxx/internal/gates/result-sql_cursor.hxx | 13 + .../internal/gates/transaction-sql_cursor.hxx | 10 + .../gates/transaction-transaction_focus.hxx | 30 + .../include/pqxx/internal/header-post.hxx | 22 + .../include/pqxx/internal/header-pre.hxx | 169 + .../pqxx/internal/ignore-deprecated-post.hxx | 15 + .../pqxx/internal/ignore-deprecated-pre.hxx | 28 + .../include/pqxx/internal/libpq-forward.hxx | 31 + .../include/pqxx/internal/result_iter.hxx | 124 + .../include/pqxx/internal/result_iterator.hxx | 389 + .../include/pqxx/internal/sql_cursor.hxx | 118 + .../pqxx/internal/statement_parameters.hxx | 131 + .../include/pqxx/internal/stream_iterator.hxx | 105 + .../arm64/include/pqxx/internal/wait.hxx | 18 + .../ubuntu22.04/arm64/include/pqxx/isolation | 8 + .../arm64/include/pqxx/isolation.hxx | 75 + .../arm64/include/pqxx/largeobject | 8 + .../arm64/include/pqxx/largeobject.hxx | 735 + .../arm64/include/pqxx/nontransaction | 8 + .../arm64/include/pqxx/nontransaction.hxx | 76 + .../arm64/include/pqxx/notification | 8 + .../arm64/include/pqxx/notification.hxx | 94 + .../ubuntu22.04/arm64/include/pqxx/params | 8 + .../ubuntu22.04/arm64/include/pqxx/params.hxx | 383 + .../ubuntu22.04/arm64/include/pqxx/pipeline | 8 + .../arm64/include/pqxx/pipeline.hxx | 237 + .../ubuntu22.04/arm64/include/pqxx/pqxx | 28 + .../arm64/include/pqxx/prepared_statement | 3 + .../arm64/include/pqxx/prepared_statement.hxx | 3 + .../ubuntu22.04/arm64/include/pqxx/range | 6 + .../ubuntu22.04/arm64/include/pqxx/range.hxx | 515 + .../ubuntu22.04/arm64/include/pqxx/result | 16 + .../ubuntu22.04/arm64/include/pqxx/result.hxx | 335 + .../arm64/include/pqxx/robusttransaction | 8 + .../arm64/include/pqxx/robusttransaction.hxx | 120 + .../ubuntu22.04/arm64/include/pqxx/row | 11 + .../ubuntu22.04/arm64/include/pqxx/row.hxx | 561 + .../arm64/include/pqxx/separated_list | 6 + .../arm64/include/pqxx/separated_list.hxx | 142 + .../ubuntu22.04/arm64/include/pqxx/strconv | 6 + .../arm64/include/pqxx/strconv.hxx | 468 + .../arm64/include/pqxx/stream_from | 8 + .../arm64/include/pqxx/stream_from.hxx | 361 + .../ubuntu22.04/arm64/include/pqxx/stream_to | 8 + .../arm64/include/pqxx/stream_to.hxx | 455 + .../arm64/include/pqxx/subtransaction | 8 + .../arm64/include/pqxx/subtransaction.hxx | 96 + .../ubuntu22.04/arm64/include/pqxx/time | 6 + .../ubuntu22.04/arm64/include/pqxx/time.hxx | 88 + .../arm64/include/pqxx/transaction | 8 + .../arm64/include/pqxx/transaction.hxx | 108 + .../arm64/include/pqxx/transaction_base | 9 + .../arm64/include/pqxx/transaction_base.hxx | 810 + .../arm64/include/pqxx/transaction_focus | 7 + .../arm64/include/pqxx/transaction_focus.hxx | 89 + .../ubuntu22.04/arm64/include/pqxx/transactor | 8 + .../arm64/include/pqxx/transactor.hxx | 147 + .../ubuntu22.04/arm64/include/pqxx/types | 7 + .../ubuntu22.04/arm64/include/pqxx/types.hxx | 173 + .../ubuntu22.04/arm64/include/pqxx/util | 6 + .../ubuntu22.04/arm64/include/pqxx/util.hxx | 521 + .../ubuntu22.04/arm64/include/pqxx/version | 7 + .../arm64/include/pqxx/version.hxx | 55 + .../ubuntu22.04/arm64/include/pqxx/zview | 6 + .../ubuntu22.04/arm64/include/pqxx/zview.hxx | 163 + .../libpqxx/libpqxx-config-version.cmake | 70 + .../lib/cmake/libpqxx/libpqxx-config.cmake | 4 + .../libpqxx/libpqxx-targets-noconfig.cmake | 19 + .../lib/cmake/libpqxx/libpqxx-targets.cmake | 99 + .../ubuntu22.04/arm64/lib/libpqxx-7.7.a | Bin 0 -> 4997126 bytes .../install/ubuntu22.04/arm64/lib/libpqxx.a | 1 + .../share/doc/libpqxx/accessing-results.md | 157 + .../arm64/share/doc/libpqxx/binary-data.md | 56 + .../arm64/share/doc/libpqxx/datatypes.md | 373 + .../arm64/share/doc/libpqxx/escaping.md | 74 + .../share/doc/libpqxx/getting-started.md | 142 + .../arm64/share/doc/libpqxx/mainpage.md | 28 + .../arm64/share/doc/libpqxx/parameters.md | 90 + .../arm64/share/doc/libpqxx/performance.md | 24 + .../share/doc/libpqxx/prepared-statement.md | 125 + .../arm64/share/doc/libpqxx/streams.md | 107 + .../arm64/share/doc/libpqxx/thread-safety.md | 29 + ext/libpqxx-7.7.3/libpqxx.pc.in | 10 + ext/libpqxx-7.7.3/requirements.json | 9 + ext/libpqxx-7.7.3/src/CMakeLists.txt | 91 + ext/libpqxx-7.7.3/src/Makefile.am | 44 + ext/libpqxx-7.7.3/src/Makefile.in | 809 + ext/libpqxx-7.7.3/src/array.cxx | 240 + ext/libpqxx-7.7.3/src/binarystring.cxx | 108 + ext/libpqxx-7.7.3/src/blob.cxx | 337 + ext/libpqxx-7.7.3/src/connection.cxx | 1274 + ext/libpqxx-7.7.3/src/cursor.cxx | 339 + ext/libpqxx-7.7.3/src/encodings.cxx | 839 + ext/libpqxx-7.7.3/src/errorhandler.cxx | 43 + ext/libpqxx-7.7.3/src/except.cxx | 126 + ext/libpqxx-7.7.3/src/field.cxx | 80 + ext/libpqxx-7.7.3/src/largeobject.cxx | 322 + ext/libpqxx-7.7.3/src/notification.cxx | 35 + ext/libpqxx-7.7.3/src/params.cxx | 122 + ext/libpqxx-7.7.3/src/pipeline.cxx | 448 + ext/libpqxx-7.7.3/src/pqxx-source.hxx | 30 + ext/libpqxx-7.7.3/src/result.cxx | 536 + ext/libpqxx-7.7.3/src/robusttransaction.cxx | 221 + ext/libpqxx-7.7.3/src/row.cxx | 250 + ext/libpqxx-7.7.3/src/sql_cursor.cxx | 276 + ext/libpqxx-7.7.3/src/strconv.cxx | 785 + ext/libpqxx-7.7.3/src/stream_from.cxx | 327 + ext/libpqxx-7.7.3/src/stream_to.cxx | 170 + ext/libpqxx-7.7.3/src/subtransaction.cxx | 68 + ext/libpqxx-7.7.3/src/time.cxx | 226 + ext/libpqxx-7.7.3/src/transaction.cxx | 107 + ext/libpqxx-7.7.3/src/transaction_base.cxx | 539 + ext/libpqxx-7.7.3/src/util.cxx | 194 + ext/libpqxx-7.7.3/src/version.cxx | 27 + ext/libpqxx-7.7.3/src/wait.cxx | 136 + ext/libpqxx-7.7.3/test/CMakeLists.txt | 24 + ext/libpqxx-7.7.3/test/Makefile.am | 129 + ext/libpqxx-7.7.3/test/Makefile.am.template | 38 + ext/libpqxx-7.7.3/test/Makefile.in | 1302 + ext/libpqxx-7.7.3/test/runner.cxx | 203 + ext/libpqxx-7.7.3/test/test00.cxx | 114 + ext/libpqxx-7.7.3/test/test01.cxx | 33 + ext/libpqxx-7.7.3/test/test02.cxx | 76 + ext/libpqxx-7.7.3/test/test04.cxx | 77 + ext/libpqxx-7.7.3/test/test07.cxx | 133 + ext/libpqxx-7.7.3/test/test10.cxx | 106 + ext/libpqxx-7.7.3/test/test11.cxx | 76 + ext/libpqxx-7.7.3/test/test13.cxx | 86 + ext/libpqxx-7.7.3/test/test14.cxx | 36 + ext/libpqxx-7.7.3/test/test16.cxx | 46 + ext/libpqxx-7.7.3/test/test17.cxx | 29 + ext/libpqxx-7.7.3/test/test18.cxx | 80 + ext/libpqxx-7.7.3/test/test20.cxx | 95 + ext/libpqxx-7.7.3/test/test21.cxx | 70 + ext/libpqxx-7.7.3/test/test26.cxx | 86 + ext/libpqxx-7.7.3/test/test29.cxx | 108 + ext/libpqxx-7.7.3/test/test30.cxx | 73 + ext/libpqxx-7.7.3/test/test32.cxx | 78 + ext/libpqxx-7.7.3/test/test37.cxx | 78 + ext/libpqxx-7.7.3/test/test39.cxx | 89 + ext/libpqxx-7.7.3/test/test46.cxx | 74 + ext/libpqxx-7.7.3/test/test56.cxx | 24 + ext/libpqxx-7.7.3/test/test60.cxx | 85 + ext/libpqxx-7.7.3/test/test61.cxx | 61 + ext/libpqxx-7.7.3/test/test62.cxx | 61 + ext/libpqxx-7.7.3/test/test69.cxx | 55 + ext/libpqxx-7.7.3/test/test70.cxx | 101 + ext/libpqxx-7.7.3/test/test71.cxx | 74 + ext/libpqxx-7.7.3/test/test72.cxx | 53 + ext/libpqxx-7.7.3/test/test74.cxx | 72 + ext/libpqxx-7.7.3/test/test75.cxx | 108 + ext/libpqxx-7.7.3/test/test76.cxx | 52 + ext/libpqxx-7.7.3/test/test77.cxx | 28 + ext/libpqxx-7.7.3/test/test78.cxx | 69 + ext/libpqxx-7.7.3/test/test79.cxx | 70 + ext/libpqxx-7.7.3/test/test82.cxx | 154 + ext/libpqxx-7.7.3/test/test84.cxx | 109 + ext/libpqxx-7.7.3/test/test87.cxx | 83 + ext/libpqxx-7.7.3/test/test88.cxx | 91 + ext/libpqxx-7.7.3/test/test89.cxx | 44 + ext/libpqxx-7.7.3/test/test90.cxx | 23 + ext/libpqxx-7.7.3/test/test_helpers.hxx | 305 + ext/libpqxx-7.7.3/test/test_types.hxx | 242 + ext/libpqxx-7.7.3/test/unit/CMakeLists.txt | 25 + ext/libpqxx-7.7.3/test/unit/test_array.cxx | 548 + .../test/unit/test_binarystring.cxx | 211 + ext/libpqxx-7.7.3/test/unit/test_blob.cxx | 644 + .../test/unit/test_cancel_query.cxx | 25 + ext/libpqxx-7.7.3/test/unit/test_column.cxx | 61 + .../test/unit/test_composite.cxx | 98 + .../test/unit/test_connection.cxx | 212 + ext/libpqxx-7.7.3/test/unit/test_cursor.cxx | 50 + .../test/unit/test_encodings.cxx | 114 + .../test/unit/test_error_verbosity.cxx | 37 + .../test/unit/test_errorhandler.cxx | 223 + ext/libpqxx-7.7.3/test/unit/test_escape.cxx | 228 + .../test/unit/test_exceptions.cxx | 45 + ext/libpqxx-7.7.3/test/unit/test_field.cxx | 57 + ext/libpqxx-7.7.3/test/unit/test_float.cxx | 175 + .../test/unit/test_largeobject.cxx | 58 + .../test/unit/test_nonblocking_connect.cxx | 27 + .../test/unit/test_notification.cxx | 86 + ext/libpqxx-7.7.3/test/unit/test_pipeline.cxx | 64 + .../test/unit/test_prepared_statement.cxx | 334 + ext/libpqxx-7.7.3/test/unit/test_range.cxx | 555 + .../test/unit/test_read_transaction.cxx | 22 + .../test/unit/test_result_iteration.cxx | 137 + .../test/unit/test_result_slicing.cxx | 157 + ext/libpqxx-7.7.3/test/unit/test_row.cxx | 84 + .../test/unit/test_separated_list.cxx | 33 + .../unit/test_simultaneous_transactions.cxx | 20 + .../test/unit/test_sql_cursor.cxx | 270 + .../test/unit/test_stateless_cursor.cxx | 85 + ext/libpqxx-7.7.3/test/unit/test_strconv.cxx | 143 + .../test/unit/test_stream_from.cxx | 344 + .../test/unit/test_stream_to.cxx | 445 + .../test/unit/test_string_conversion.cxx | 178 + .../test/unit/test_subtransaction.cxx | 78 + .../test/unit/test_test_helpers.cxx | 214 + .../test/unit/test_thread_safety_model.cxx | 23 + ext/libpqxx-7.7.3/test/unit/test_time.cxx | 86 + .../test/unit/test_transaction.cxx | 113 + .../test/unit/test_transaction_base.cxx | 106 + .../test/unit/test_transaction_focus.cxx | 53 + .../test/unit/test_transactor.cxx | 130 + .../test/unit/test_type_name.cxx | 19 + ext/libpqxx-7.7.3/test/unit/test_zview.cxx | 16 + ext/libpqxx-7.7.3/tools/Makefile.am | 20 + ext/libpqxx-7.7.3/tools/Makefile.in | 638 + ext/libpqxx-7.7.3/tools/deprecations | 6 + ext/libpqxx-7.7.3/tools/extract_version | 73 + ext/libpqxx-7.7.3/tools/format | 20 + ext/libpqxx-7.7.3/tools/lint | 197 + ext/libpqxx-7.7.3/tools/m4esc.py | 70 + ext/libpqxx-7.7.3/tools/pqxxthreadsafety.cxx | 10 + ext/libpqxx-7.7.3/tools/rmlo.cxx | 39 + ext/libpqxx-7.7.3/tools/splitconfig | 244 + ext/libpqxx-7.7.3/tools/template2mak.py | 194 + ext/libpqxx-7.7.3/tools/test_all.py | 630 + ext/libpqxx-7.7.3/tools/todo | 31 + ext/libpqxx-7.7.3/tools/update-copyright | 29 + ext/miniupnpc/Changelog.txt | 691 + ext/miniupnpc/LICENSE | 27 + ext/miniupnpc/README | 63 + ext/miniupnpc/VERSION | 1 + ext/miniupnpc/codelength.h | 54 + ext/miniupnpc/connecthostport.c | 262 + ext/miniupnpc/connecthostport.h | 18 + ext/miniupnpc/igd_desc_parse.c | 123 + ext/miniupnpc/igd_desc_parse.h | 49 + ext/miniupnpc/listdevices.c | 110 + ext/miniupnpc/minisoap.c | 136 + ext/miniupnpc/minisoap.h | 15 + ext/miniupnpc/minissdpc.c | 893 + ext/miniupnpc/minissdpc.h | 58 + ext/miniupnpc/miniupnpc.c | 722 + ext/miniupnpc/miniupnpc.def | 45 + ext/miniupnpc/miniupnpc.h | 152 + ext/miniupnpc/miniupnpc_declspec.h | 21 + ext/miniupnpc/miniupnpcmodule.c | 703 + ext/miniupnpc/miniupnpcstrings.h.in | 23 + ext/miniupnpc/miniupnpctypes.h | 19 + ext/miniupnpc/miniwget.c | 675 + ext/miniupnpc/miniwget.h | 30 + ext/miniupnpc/minixml.c | 231 + ext/miniupnpc/minixml.h | 37 + ext/miniupnpc/minixmlvalid.c | 163 + ext/miniupnpc/portlistingparse.c | 172 + ext/miniupnpc/portlistingparse.h | 65 + ext/miniupnpc/receivedata.c | 105 + ext/miniupnpc/receivedata.h | 19 + ext/miniupnpc/updateminiupnpcstrings.sh | 53 + ext/miniupnpc/upnpc.c | 857 + ext/miniupnpc/upnpcommands.c | 1240 + ext/miniupnpc/upnpcommands.h | 348 + ext/miniupnpc/upnpdev.c | 23 + ext/miniupnpc/upnpdev.h | 36 + ext/miniupnpc/upnperrors.c | 107 + ext/miniupnpc/upnperrors.h | 26 + ext/miniupnpc/upnpreplyparse.c | 196 + ext/miniupnpc/upnpreplyparse.h | 63 + ext/miniupnpc/wingenminiupnpcstrings.c | 83 + ext/misc/linux-old-glibc-compat.c | 18 + ext/nlohmann/LICENSE.MIT | 21 + ext/nlohmann/README.md | 1123 + ext/nlohmann/json.hpp | 26640 ++++++++++++++++ ext/prometheus-cpp-lite-1.0/.gitignore | 3 + .../3rdpatry/http-client-lite/CMakeLists.txt | 36 + .../3rdpatry/http-client-lite/LICENSE | 22 + .../3rdpatry/http-client-lite/README.md | 30 + .../http-client-lite/examples/CMakeLists.txt | 5 + .../examples/simple_request.cpp | 43 + .../include/jdl/httpclientlite.h | 327 + ext/prometheus-cpp-lite-1.0/CMakeLists.txt | 34 + ext/prometheus-cpp-lite-1.0/LICENSE | 21 + ext/prometheus-cpp-lite-1.0/README.md | 201 + .../core/CMakeLists.txt | 20 + .../core/include/prometheus/atomic_floating.h | 40 + .../core/include/prometheus/benchmark.h | 72 + .../core/include/prometheus/builder.h | 35 + .../core/include/prometheus/ckms_quantiles.h | 194 + .../core/include/prometheus/client_metric.h | 94 + .../core/include/prometheus/collectable.h | 27 + .../core/include/prometheus/counter.h | 113 + .../core/include/prometheus/family.h | 356 + .../core/include/prometheus/gateway.h | 205 + .../core/include/prometheus/gauge.h | 129 + .../core/include/prometheus/hash.h | 50 + .../core/include/prometheus/histogram.h | 154 + .../core/include/prometheus/metric.h | 29 + .../core/include/prometheus/metric_family.h | 18 + .../core/include/prometheus/push_to_server.h | 86 + .../core/include/prometheus/registry.h | 123 + .../core/include/prometheus/save_to_file.h | 83 + .../core/include/prometheus/summary.h | 154 + .../core/include/prometheus/text_serializer.h | 211 + .../prometheus/time_window_quantiles.h | 62 + .../examples/CMakeLists.txt | 31 + .../examples/gateway_example.cpp | 64 + .../examples/modern_example.cpp | 65 + .../examples/original_example.cpp | 67 + .../examples/push_to_server_example.cpp | 44 + .../examples/save_to_file_example.cpp | 43 + .../examples/simpleapi_example.cpp | 26 + .../simpleapi_use_in_class_example.cpp | 57 + .../use_benchmark_in_class_example.cpp | 59 + .../use_counters_in_class_example.cpp | 79 + .../examples/use_gauge_in_class_example.cpp | 79 + .../simpleapi/CMakeLists.txt | 7 + .../simpleapi/include/prometheus/simpleapi.h | 157 + .../simpleapi/src/simpleapi.cpp | 13 + ext/redis-plus-plus-1.1.1/.gitignore | 32 + ext/redis-plus-plus-1.1.1/CMakeLists.txt | 51 + ext/redis-plus-plus-1.1.1/LICENSE | 201 + ext/redis-plus-plus-1.1.1/README.md | 1776 ++ .../centos8/include/sw/redis++/command.h | 2233 ++ .../centos8/include/sw/redis++/command_args.h | 180 + .../include/sw/redis++/command_options.h | 211 + .../centos8/include/sw/redis++/connection.h | 194 + .../include/sw/redis++/connection_pool.h | 115 + .../centos8/include/sw/redis++/errors.h | 159 + .../centos8/include/sw/redis++/pipeline.h | 49 + .../centos8/include/sw/redis++/queued_redis.h | 1844 ++ .../include/sw/redis++/queued_redis.hpp | 208 + .../centos8/include/sw/redis++/redis++.h | 25 + .../centos8/include/sw/redis++/redis.h | 1523 + .../centos8/include/sw/redis++/redis.hpp | 1365 + .../include/sw/redis++/redis_cluster.h | 1395 + .../include/sw/redis++/redis_cluster.hpp | 1415 + .../centos8/include/sw/redis++/reply.h | 363 + .../centos8/include/sw/redis++/sentinel.h | 138 + .../centos8/include/sw/redis++/shards.h | 115 + .../centos8/include/sw/redis++/shards_pool.h | 137 + .../centos8/include/sw/redis++/subscriber.h | 231 + .../centos8/include/sw/redis++/transaction.h | 77 + .../centos8/include/sw/redis++/utils.h | 269 + .../macos/include/sw/redis++/command.h | 2233 ++ .../macos/include/sw/redis++/command_args.h | 180 + .../include/sw/redis++/command_options.h | 211 + .../macos/include/sw/redis++/connection.h | 194 + .../include/sw/redis++/connection_pool.h | 115 + .../install/macos/include/sw/redis++/errors.h | 159 + .../macos/include/sw/redis++/pipeline.h | 49 + .../macos/include/sw/redis++/queued_redis.h | 1844 ++ .../macos/include/sw/redis++/queued_redis.hpp | 208 + .../macos/include/sw/redis++/redis++.h | 25 + .../install/macos/include/sw/redis++/redis.h | 1523 + .../macos/include/sw/redis++/redis.hpp | 1365 + .../macos/include/sw/redis++/redis_cluster.h | 1395 + .../include/sw/redis++/redis_cluster.hpp | 1415 + .../install/macos/include/sw/redis++/reply.h | 363 + .../macos/include/sw/redis++/sentinel.h | 138 + .../install/macos/include/sw/redis++/shards.h | 115 + .../macos/include/sw/redis++/shards_pool.h | 137 + .../macos/include/sw/redis++/subscriber.h | 231 + .../macos/include/sw/redis++/transaction.h | 77 + .../install/macos/include/sw/redis++/utils.h | 269 + .../src/sw/redis++/command.cpp | 376 + .../src/sw/redis++/command.h | 2233 ++ .../src/sw/redis++/command_args.h | 180 + .../src/sw/redis++/command_options.cpp | 201 + .../src/sw/redis++/command_options.h | 211 + .../src/sw/redis++/connection.cpp | 305 + .../src/sw/redis++/connection.h | 194 + .../src/sw/redis++/connection_pool.cpp | 249 + .../src/sw/redis++/connection_pool.h | 115 + .../src/sw/redis++/crc16.cpp | 96 + .../src/sw/redis++/errors.cpp | 136 + .../src/sw/redis++/errors.h | 159 + .../src/sw/redis++/pipeline.cpp | 35 + .../src/sw/redis++/pipeline.h | 49 + .../src/sw/redis++/queued_redis.h | 1844 ++ .../src/sw/redis++/queued_redis.hpp | 208 + .../src/sw/redis++/redis++.h | 25 + .../src/sw/redis++/redis.cpp | 882 + .../src/sw/redis++/redis.h | 1523 + .../src/sw/redis++/redis.hpp | 1365 + .../src/sw/redis++/redis_cluster.cpp | 769 + .../src/sw/redis++/redis_cluster.h | 1395 + .../src/sw/redis++/redis_cluster.hpp | 1415 + .../src/sw/redis++/reply.cpp | 150 + .../src/sw/redis++/reply.h | 363 + .../src/sw/redis++/sentinel.cpp | 361 + .../src/sw/redis++/sentinel.h | 138 + .../src/sw/redis++/shards.cpp | 50 + .../src/sw/redis++/shards.h | 115 + .../src/sw/redis++/shards_pool.cpp | 319 + .../src/sw/redis++/shards_pool.h | 137 + .../src/sw/redis++/subscriber.cpp | 222 + .../src/sw/redis++/subscriber.h | 231 + .../src/sw/redis++/transaction.cpp | 123 + .../src/sw/redis++/transaction.h | 77 + .../src/sw/redis++/utils.h | 269 + ext/redis-plus-plus-1.1.1/test/CMakeLists.txt | 33 + .../test/src/sw/redis++/benchmark_test.h | 83 + .../test/src/sw/redis++/benchmark_test.hpp | 178 + .../src/sw/redis++/connection_cmds_test.h | 49 + .../src/sw/redis++/connection_cmds_test.hpp | 50 + .../test/src/sw/redis++/geo_cmds_test.h | 47 + .../test/src/sw/redis++/geo_cmds_test.hpp | 149 + .../test/src/sw/redis++/hash_cmds_test.h | 55 + .../test/src/sw/redis++/hash_cmds_test.hpp | 177 + .../src/sw/redis++/hyperloglog_cmds_test.h | 47 + .../src/sw/redis++/hyperloglog_cmds_test.hpp | 67 + .../test/src/sw/redis++/keys_cmds_test.h | 55 + .../test/src/sw/redis++/keys_cmds_test.hpp | 166 + .../test/src/sw/redis++/list_cmds_test.h | 55 + .../test/src/sw/redis++/list_cmds_test.hpp | 154 + .../sw/redis++/pipeline_transaction_test.h | 57 + .../sw/redis++/pipeline_transaction_test.hpp | 184 + .../test/src/sw/redis++/pubsub_test.h | 53 + .../test/src/sw/redis++/pubsub_test.hpp | 244 + .../test/src/sw/redis++/sanity_test.h | 76 + .../test/src/sw/redis++/sanity_test.hpp | 299 + .../test/src/sw/redis++/script_cmds_test.h | 49 + .../test/src/sw/redis++/script_cmds_test.hpp | 97 + .../test/src/sw/redis++/set_cmds_test.h | 53 + .../test/src/sw/redis++/set_cmds_test.hpp | 184 + .../test/src/sw/redis++/stream_cmds_test.h | 54 + .../test/src/sw/redis++/stream_cmds_test.hpp | 225 + .../test/src/sw/redis++/string_cmds_test.h | 57 + .../test/src/sw/redis++/string_cmds_test.hpp | 247 + .../test/src/sw/redis++/test_main.cpp | 303 + .../test/src/sw/redis++/threads_test.h | 51 + .../test/src/sw/redis++/threads_test.hpp | 147 + .../test/src/sw/redis++/utils.h | 96 + .../test/src/sw/redis++/zset_cmds_test.h | 61 + .../test/src/sw/redis++/zset_cmds_test.hpp | 350 + .../.github/ISSUE_TEMPLATE/bug_report.md | 26 + .../.github/ISSUE_TEMPLATE/feature_request.md | 20 + .../.github/ISSUE_TEMPLATE/question.md | 27 + ext/redis-plus-plus-1.3.3/.gitignore | 32 + ext/redis-plus-plus-1.3.3/.travis.yml | 32 + ext/redis-plus-plus-1.3.3/CMakeLists.txt | 307 + ext/redis-plus-plus-1.3.3/LICENSE | 201 + ext/redis-plus-plus-1.3.3/README.md | 2604 ++ .../cmake/redis++-config.cmake.in | 12 + ext/redis-plus-plus-1.3.3/cmake/redis++.pc.in | 12 + .../amd64/include/sw/redis++/cmd_formatter.h | 775 + .../amd64/include/sw/redis++/command.h | 2271 ++ .../amd64/include/sw/redis++/command_args.h | 180 + .../include/sw/redis++/command_options.h | 211 + .../amd64/include/sw/redis++/connection.h | 237 + .../include/sw/redis++/connection_pool.h | 182 + .../amd64/include/sw/redis++/cxx_utils.h | 46 + .../amd64/include/sw/redis++/errors.h | 166 + .../amd64/include/sw/redis++/pipeline.h | 49 + .../amd64/include/sw/redis++/queued_redis.h | 2013 ++ .../amd64/include/sw/redis++/queued_redis.hpp | 275 + .../amd64/include/sw/redis++/redis++.h | 25 + .../amd64/include/sw/redis++/redis.h | 3631 +++ .../amd64/include/sw/redis++/redis.hpp | 1342 + .../amd64/include/sw/redis++/redis_cluster.h | 1439 + .../include/sw/redis++/redis_cluster.hpp | 1403 + .../amd64/include/sw/redis++/reply.h | 435 + .../amd64/include/sw/redis++/sentinel.h | 141 + .../amd64/include/sw/redis++/shards.h | 115 + .../amd64/include/sw/redis++/shards_pool.h | 121 + .../amd64/include/sw/redis++/subscriber.h | 231 + .../amd64/include/sw/redis++/tls.h | 47 + .../amd64/include/sw/redis++/transaction.h | 77 + .../amd64/include/sw/redis++/utils.h | 193 + .../amd64/lib/pkgconfig/redis++.pc | 12 + .../redis++/redis++-config-version.cmake | 48 + .../share/cmake/redis++/redis++-config.cmake | 36 + .../redis++/redis++-targets-release.cmake | 19 + .../share/cmake/redis++/redis++-targets.cmake | 94 + .../arm64/include/sw/redis++/cmd_formatter.h | 775 + .../arm64/include/sw/redis++/command.h | 2271 ++ .../arm64/include/sw/redis++/command_args.h | 180 + .../include/sw/redis++/command_options.h | 211 + .../arm64/include/sw/redis++/connection.h | 237 + .../include/sw/redis++/connection_pool.h | 182 + .../arm64/include/sw/redis++/cxx_utils.h | 46 + .../arm64/include/sw/redis++/errors.h | 166 + .../arm64/include/sw/redis++/pipeline.h | 49 + .../arm64/include/sw/redis++/queued_redis.h | 2013 ++ .../arm64/include/sw/redis++/queued_redis.hpp | 275 + .../arm64/include/sw/redis++/redis++.h | 25 + .../arm64/include/sw/redis++/redis.h | 3631 +++ .../arm64/include/sw/redis++/redis.hpp | 1342 + .../arm64/include/sw/redis++/redis_cluster.h | 1439 + .../include/sw/redis++/redis_cluster.hpp | 1403 + .../arm64/include/sw/redis++/reply.h | 435 + .../arm64/include/sw/redis++/sentinel.h | 141 + .../arm64/include/sw/redis++/shards.h | 115 + .../arm64/include/sw/redis++/shards_pool.h | 121 + .../arm64/include/sw/redis++/subscriber.h | 231 + .../arm64/include/sw/redis++/tls.h | 47 + .../arm64/include/sw/redis++/transaction.h | 77 + .../arm64/include/sw/redis++/utils.h | 193 + .../arm64/lib/pkgconfig/redis++.pc | 12 + .../redis++/redis++-config-version.cmake | 48 + .../share/cmake/redis++/redis++-config.cmake | 36 + .../redis++/redis++-targets-release.cmake | 19 + .../share/cmake/redis++/redis++-targets.cmake | 94 + .../src/sw/redis++/async_connection.cpp | 448 + .../src/sw/redis++/async_connection.h | 498 + .../src/sw/redis++/async_connection_pool.cpp | 347 + .../src/sw/redis++/async_connection_pool.h | 181 + .../src/sw/redis++/async_redis++.h | 23 + .../src/sw/redis++/async_redis.cpp | 52 + .../src/sw/redis++/async_redis.h | 789 + .../src/sw/redis++/async_redis_cluster.cpp | 37 + .../src/sw/redis++/async_redis_cluster.h | 819 + .../src/sw/redis++/async_sentinel.cpp | 110 + .../src/sw/redis++/async_sentinel.h | 89 + .../src/sw/redis++/async_shards_pool.cpp | 374 + .../src/sw/redis++/async_shards_pool.h | 127 + .../src/sw/redis++/cmd_formatter.h | 775 + .../src/sw/redis++/command.cpp | 376 + .../src/sw/redis++/command.h | 2271 ++ .../src/sw/redis++/command_args.h | 180 + .../src/sw/redis++/command_options.cpp | 201 + .../src/sw/redis++/command_options.h | 211 + .../src/sw/redis++/connection.cpp | 494 + .../src/sw/redis++/connection.h | 237 + .../src/sw/redis++/connection_pool.cpp | 276 + .../src/sw/redis++/connection_pool.h | 182 + .../src/sw/redis++/crc16.cpp | 96 + .../src/sw/redis++/cxx11/cxx_utils.h | 113 + .../src/sw/redis++/cxx17/cxx_utils.h | 46 + .../src/sw/redis++/errors.cpp | 142 + .../src/sw/redis++/errors.h | 166 + .../src/sw/redis++/event_loop.cpp | 273 + .../src/sw/redis++/event_loop.h | 119 + .../src/sw/redis++/future/boost/async_utils.h | 39 + .../src/sw/redis++/future/std/async_utils.h | 36 + .../src/sw/redis++/no_tls/tls.h | 47 + .../src/sw/redis++/pipeline.cpp | 35 + .../src/sw/redis++/pipeline.h | 49 + .../src/sw/redis++/queued_redis.h | 2013 ++ .../src/sw/redis++/queued_redis.hpp | 275 + .../src/sw/redis++/redis++.h | 25 + .../src/sw/redis++/redis.cpp | 929 + .../src/sw/redis++/redis.h | 3631 +++ .../src/sw/redis++/redis.hpp | 1342 + .../src/sw/redis++/redis_cluster.cpp | 802 + .../src/sw/redis++/redis_cluster.h | 1439 + .../src/sw/redis++/redis_cluster.hpp | 1403 + .../src/sw/redis++/reply.cpp | 158 + .../src/sw/redis++/reply.h | 435 + .../src/sw/redis++/sentinel.cpp | 362 + .../src/sw/redis++/sentinel.h | 141 + .../src/sw/redis++/shards.cpp | 52 + .../src/sw/redis++/shards.h | 115 + .../src/sw/redis++/shards_pool.cpp | 369 + .../src/sw/redis++/shards_pool.h | 121 + .../src/sw/redis++/subscriber.cpp | 222 + .../src/sw/redis++/subscriber.h | 231 + .../src/sw/redis++/tls/tls.cpp | 72 + .../src/sw/redis++/tls/tls.h | 77 + .../src/sw/redis++/transaction.cpp | 123 + .../src/sw/redis++/transaction.h | 77 + .../src/sw/redis++/utils.h | 193 + ext/redis-plus-plus-1.3.3/test/CMakeLists.txt | 58 + .../test/src/sw/redis++/benchmark_test.h | 83 + .../test/src/sw/redis++/benchmark_test.hpp | 178 + .../src/sw/redis++/connection_cmds_test.h | 49 + .../src/sw/redis++/connection_cmds_test.hpp | 50 + .../test/src/sw/redis++/geo_cmds_test.h | 47 + .../test/src/sw/redis++/geo_cmds_test.hpp | 187 + .../test/src/sw/redis++/hash_cmds_test.h | 55 + .../test/src/sw/redis++/hash_cmds_test.hpp | 183 + .../src/sw/redis++/hyperloglog_cmds_test.h | 47 + .../src/sw/redis++/hyperloglog_cmds_test.hpp | 67 + .../test/src/sw/redis++/keys_cmds_test.h | 55 + .../test/src/sw/redis++/keys_cmds_test.hpp | 166 + .../test/src/sw/redis++/list_cmds_test.h | 55 + .../test/src/sw/redis++/list_cmds_test.hpp | 154 + .../sw/redis++/pipeline_transaction_test.h | 61 + .../sw/redis++/pipeline_transaction_test.hpp | 293 + .../test/src/sw/redis++/pubsub_test.h | 53 + .../test/src/sw/redis++/pubsub_test.hpp | 244 + .../test/src/sw/redis++/sanity_test.h | 80 + .../test/src/sw/redis++/sanity_test.hpp | 481 + .../test/src/sw/redis++/script_cmds_test.h | 49 + .../test/src/sw/redis++/script_cmds_test.hpp | 126 + .../test/src/sw/redis++/set_cmds_test.h | 53 + .../test/src/sw/redis++/set_cmds_test.hpp | 184 + .../test/src/sw/redis++/stream_cmds_test.h | 54 + .../test/src/sw/redis++/stream_cmds_test.hpp | 255 + .../test/src/sw/redis++/string_cmds_test.h | 57 + .../test/src/sw/redis++/string_cmds_test.hpp | 247 + .../test/src/sw/redis++/test_main.cpp | 433 + .../test/src/sw/redis++/threads_test.h | 51 + .../test/src/sw/redis++/threads_test.hpp | 147 + .../test/src/sw/redis++/utils.h | 105 + .../test/src/sw/redis++/zset_cmds_test.h | 61 + .../test/src/sw/redis++/zset_cmds_test.hpp | 422 + ext/x64-salsa2012-asm/README.md | 6 + ext/x64-salsa2012-asm/salsa2012.h | 16 + ext/x64-salsa2012-asm/salsa2012.s | 4488 +++ include/README.md | 4 + include/ZeroTierDebug.h | 104 + include/ZeroTierOne.h | 2116 ++ java/CMakeLists.txt | 91 + java/README.md | 17 + java/build.xml | 118 + java/jni/ZT_jnicache.cpp | 236 + java/jni/ZT_jnicache.h | 92 + java/jni/ZT_jniutils.cpp | 625 + java/jni/ZT_jniutils.h | 169 + java/jni/com_zerotierone_sdk_Node.cpp | 1432 + java/jni/com_zerotierone_sdk_Node.h | 141 + .../zerotier/sdk/DataStoreGetListener.java | 55 + .../zerotier/sdk/DataStorePutListener.java | 60 + java/src/com/zerotier/sdk/Event.java | 154 + java/src/com/zerotier/sdk/EventListener.java | 50 + java/src/com/zerotier/sdk/Node.java | 456 + java/src/com/zerotier/sdk/NodeStatus.java | 90 + java/src/com/zerotier/sdk/PacketSender.java | 53 + java/src/com/zerotier/sdk/PathChecker.java | 47 + java/src/com/zerotier/sdk/Peer.java | 118 + .../com/zerotier/sdk/PeerPhysicalPath.java | 92 + java/src/com/zerotier/sdk/PeerRole.java | 71 + java/src/com/zerotier/sdk/ResultCode.java | 111 + java/src/com/zerotier/sdk/Version.java | 53 + .../zerotier/sdk/VirtualNetworkConfig.java | 412 + .../sdk/VirtualNetworkConfigListener.java | 60 + .../sdk/VirtualNetworkConfigOperation.java | 78 + .../com/zerotier/sdk/VirtualNetworkDNS.java | 78 + .../sdk/VirtualNetworkFrameListener.java | 49 + .../com/zerotier/sdk/VirtualNetworkRoute.java | 164 + .../zerotier/sdk/VirtualNetworkStatus.java | 99 + .../com/zerotier/sdk/VirtualNetworkType.java | 64 + .../com/zerotier/sdk/util/StringUtils.java | 52 + .../zerotier/sdk/util/StringUtilsTest.java | 73 + make-bsd.mk | 198 + make-linux.mk | 568 + make-mac.mk | 205 + make-netbsd.mk | 65 + node/AES.cpp | 697 + node/AES.hpp | 597 + node/AES_aesni.cpp | 677 + node/AES_armcrypto.cpp | 394 + node/Address.hpp | 160 + node/AtomicCounter.hpp | 73 + node/Bond.cpp | 2055 ++ node/Bond.hpp | 1573 + node/Buffer.hpp | 486 + node/C25519.cpp | 2642 ++ node/C25519.hpp | 171 + node/Capability.cpp | 65 + node/Capability.hpp | 505 + node/CertificateOfMembership.cpp | 138 + node/CertificateOfMembership.hpp | 318 + node/CertificateOfOwnership.cpp | 62 + node/CertificateOfOwnership.hpp | 251 + node/Constants.hpp | 767 + node/Credential.hpp | 52 + node/DNS.hpp | 57 + node/Dictionary.hpp | 479 + node/Hashtable.hpp | 435 + node/Identity.cpp | 204 + node/Identity.hpp | 332 + node/IncomingPacket.cpp | 1499 + node/IncomingPacket.hpp | 147 + node/InetAddress.cpp | 533 + node/InetAddress.hpp | 681 + node/MAC.hpp | 243 + node/Membership.cpp | 222 + node/Membership.hpp | 296 + node/Metrics.cpp | 272 + node/Metrics.hpp | 166 + node/MulticastGroup.hpp | 113 + node/Multicaster.cpp | 463 + node/Multicaster.hpp | 197 + node/Mutex.hpp | 162 + node/Network.cpp | 1723 + node/Network.hpp | 494 + node/NetworkConfig.cpp | 577 + node/NetworkConfig.hpp | 734 + node/NetworkController.hpp | 117 + node/Node.cpp | 1152 + node/Node.hpp | 341 + node/OutboundMulticast.cpp | 92 + node/OutboundMulticast.hpp | 158 + node/Packet.cpp | 1196 + node/Packet.hpp | 1436 + node/PacketMultiplexer.cpp | 122 + node/PacketMultiplexer.hpp | 65 + node/Path.cpp | 29 + node/Path.hpp | 408 + node/Peer.cpp | 702 + node/Peer.hpp | 702 + node/Poly1305.cpp | 525 + node/Poly1305.hpp | 49 + node/README.md | 14 + node/Revocation.cpp | 43 + node/Revocation.hpp | 209 + node/RingBuffer.hpp | 334 + node/RuntimeEnvironment.hpp | 91 + node/SHA512.cpp | 285 + node/SHA512.hpp | 88 + node/Salsa20.cpp | 1347 + node/Salsa20.hpp | 159 + node/SelfAwareness.cpp | 132 + node/SelfAwareness.hpp | 93 + node/SharedPtr.hpp | 140 + node/Switch.cpp | 1243 + node/Switch.hpp | 332 + node/Tag.cpp | 43 + node/Tag.hpp | 215 + node/Topology.cpp | 435 + node/Topology.hpp | 468 + node/Trace.cpp | 611 + node/Trace.hpp | 166 + node/Utils.cpp | 309 + node/Utils.hpp | 870 + node/World.hpp | 292 + objects.mk | 48 + one.cpp | 2366 ++ osdep/Arp.cpp | 121 + osdep/Arp.hpp | 143 + osdep/BSDEthernetTap.cpp | 502 + osdep/BSDEthernetTap.hpp | 86 + osdep/Binder.hpp | 544 + osdep/BlockingQueue.hpp | 132 + osdep/EthernetTap.cpp | 169 + osdep/EthernetTap.hpp | 66 + osdep/Http.cpp | 287 + osdep/Http.hpp | 182 + osdep/LinuxEthernetTap.cpp | 602 + osdep/LinuxEthernetTap.hpp | 83 + osdep/LinuxNetLink.cpp | 1206 + osdep/LinuxNetLink.hpp | 152 + osdep/MacDNSHelper.hpp | 23 + osdep/MacDNSHelper.mm | 347 + osdep/MacEthernetTap.cpp | 554 + osdep/MacEthernetTap.hpp | 87 + osdep/MacEthernetTapAgent.c | 436 + osdep/MacEthernetTapAgent.h | 28 + osdep/MacKextEthernetTap.cpp | 701 + osdep/MacKextEthernetTap.hpp | 84 + osdep/ManagedRoute.cpp | 628 + osdep/ManagedRoute.hpp | 83 + osdep/NeighborDiscovery.cpp | 259 + osdep/NeighborDiscovery.hpp | 71 + osdep/NetBSDEthernetTap.cpp | 479 + osdep/NetBSDEthernetTap.hpp | 77 + osdep/OSUtils.cpp | 582 + osdep/OSUtils.hpp | 305 + osdep/Phy.hpp | 1208 + osdep/PortMapper.cpp | 358 + osdep/PortMapper.hpp | 66 + osdep/README.md | 6 + osdep/Thread.hpp | 192 + osdep/WinDNSHelper.cpp | 353 + osdep/WinDNSHelper.hpp | 24 + osdep/WinFWHelper.cpp | 172 + osdep/WinFWHelper.hpp | 31 + osdep/WindowsEthernetTap.cpp | 1326 + osdep/WindowsEthernetTap.hpp | 162 + osdep/freebsd_getifmaddrs.c | 207 + osdep/freebsd_getifmaddrs.h | 75 + pkg/README.md | 4 + pkg/asustor/Dockerfile | 10 + pkg/asustor/build.sh | 13 + pkg/asustor/entrypoint.sh | 29 + pkg/asustor/zerotier/CONTROL/config.json | 15 + pkg/asustor/zerotier/CONTROL/description.txt | 1 + pkg/asustor/zerotier/CONTROL/icon.png | Bin 0 -> 147491 bytes pkg/asustor/zerotier/CONTROL/license.txt | 149 + pkg/asustor/zerotier/CONTROL/post-install.sh | 24 + .../zerotier/CONTROL/post-uninstall.sh | 3 + pkg/asustor/zerotier/CONTROL/pre-install.sh | 0 pkg/asustor/zerotier/CONTROL/pre-uninstall.sh | 0 pkg/asustor/zerotier/CONTROL/start-stop.sh | 26 + pkg/asustor/zerotier/apkg-version | 1 + pkg/asustor/zerotier/www/index.html | 58 + pkg/config.json | 6 + pkg/qnap/Dockerfile | 8 + pkg/qnap/build.sh | 13 + pkg/qnap/entrypoint.sh | 76 + pkg/qnap/qdk.conf | 3 + pkg/qnap/zerotier/Makefile | 7 + pkg/qnap/zerotier/arm_64/.gitkeep | 0 pkg/qnap/zerotier/arm_x09/.gitkeep | 0 pkg/qnap/zerotier/arm_x10/.gitkeep | 0 pkg/qnap/zerotier/arm_x12/.gitkeep | 0 pkg/qnap/zerotier/arm_x19/.gitkeep | 0 pkg/qnap/zerotier/arm_x31/.gitkeep | 0 pkg/qnap/zerotier/arm_x41/.gitkeep | 0 pkg/qnap/zerotier/config/.gitkeep | 0 pkg/qnap/zerotier/icons/.gitkeep | 0 pkg/qnap/zerotier/icons/ZeroTier.gif | Bin 0 -> 2765 bytes pkg/qnap/zerotier/icons/ZeroTier_80.gif | Bin 0 -> 2765 bytes pkg/qnap/zerotier/icons/ZeroTier_gray.gif | Bin 0 -> 1986 bytes pkg/qnap/zerotier/package_routines | 158 + pkg/qnap/zerotier/qpkg.cfg | 99 + pkg/qnap/zerotier/shared/.gitkeep | 0 pkg/qnap/zerotier/shared/.qpkg_icon.gif | Bin 0 -> 1853 bytes pkg/qnap/zerotier/shared/.qpkg_icon_80.gif | Bin 0 -> 1853 bytes pkg/qnap/zerotier/shared/.qpkg_icon_gray.gif | Bin 0 -> 2375 bytes pkg/qnap/zerotier/shared/zerotier.sh | 34 + pkg/qnap/zerotier/x86/.gitkeep | 0 pkg/qnap/zerotier/x86_64/.gitkeep | 0 pkg/qnap/zerotier/x86_ce53xx/.gitkeep | 0 pkg/snap/snapcraft.yaml | 90 + pkg/synology/Dockerfile.spksrc | 20 + pkg/synology/README.md | 8 + pkg/synology/build.sh | 139 + pkg/synology/dsm6-pkg/PACKAGE_ICON.png | Bin 0 -> 2274 bytes pkg/synology/dsm6-pkg/PACKAGE_ICON_256.png | Bin 0 -> 9134 bytes pkg/synology/dsm6-pkg/scripts/postinst | 3 + pkg/synology/dsm6-pkg/scripts/postuninst | 3 + pkg/synology/dsm6-pkg/scripts/postupgrade | 2 + pkg/synology/dsm6-pkg/scripts/preinst | 2 + pkg/synology/dsm6-pkg/scripts/preuninst | 3 + pkg/synology/dsm6-pkg/scripts/preupgrade | 2 + pkg/synology/dsm6-pkg/service-setup.sh | 30 + pkg/synology/dsm6-pkg/start-stop-status.sh | 162 + pkg/synology/dsm7-docker/Dockerfile | 30 + pkg/synology/dsm7-docker/README.md | 8 + pkg/synology/dsm7-docker/build.sh | 19 + pkg/synology/dsm7-docker/entrypoint.sh | 82 + pkg/synology/syn-pkg-entrypoint.sh | 38 + pkg/wd/Dockerfile | 9 + pkg/wd/build.sh | 13 + pkg/wd/entrypoint.sh | 98 + pkg/wd/zerotier/apkg.rc | 21 + pkg/wd/zerotier/apkg.xml | 37 + pkg/wd/zerotier/clean.sh | 7 + pkg/wd/zerotier/init.sh | 15 + pkg/wd/zerotier/install.sh | 5 + pkg/wd/zerotier/preinst.sh | 1 + pkg/wd/zerotier/remove.sh | 10 + pkg/wd/zerotier/start.sh | 3 + pkg/wd/zerotier/stop.sh | 3 + pkg/wd/zerotier/web/index.html | 58 + pkg/wd/zerotier/web/zerotier.png | Bin 0 -> 48062 bytes pkg/wd/zerotier/zerotier.png | Bin 0 -> 48062 bytes rule-compiler/README.md | 8 + rule-compiler/cli.js | 47 + .../examples/capabilities-and-tags.ztrules | 40 + rule-compiler/package.json | 18 + rule-compiler/rule-compiler.js | 917 + rustybits/Cargo.lock | 3782 +++ rustybits/Cargo.toml | 6 + rustybits/rustfmt.toml | 15 + rustybits/smeeclient/Cargo.toml | 21 + rustybits/smeeclient/build.rs | 36 + rustybits/smeeclient/rustfmt.toml | 1 + rustybits/smeeclient/src/ext.rs | 92 + rustybits/smeeclient/src/lib.rs | 108 + rustybits/zeroidc.vcxproj | 147 + rustybits/zeroidc.vcxproj.filters | 30 + rustybits/zeroidc/.cargo/config.toml | 11 + rustybits/zeroidc/.gitattributes | 3 + rustybits/zeroidc/Cargo.toml | 28 + rustybits/zeroidc/build.rs | 36 + rustybits/zeroidc/rustfmt.toml | 1 + rustybits/zeroidc/src/error.rs | 34 + rustybits/zeroidc/src/ext.rs | 329 + rustybits/zeroidc/src/lib.rs | 659 + selftest.cpp | 1161 + service/OneService.cpp | 4009 +++ service/OneService.hpp | 195 + service/README.md | 192 + service/SoftwareUpdater.cpp | 426 + service/SoftwareUpdater.hpp | 204 + tcp-proxy/Makefile | 9 + tcp-proxy/README.md | 39 + tcp-proxy/tcp-proxy.cpp | 319 + tcp-proxy/zerotier-proxy.service | 14 + update_controllers.sh | 26 + version.h | 48 + windows-clean.bat | 12 + windows/README.md | 29 + windows/TapDriver6/TapDriver6.vcxproj | 253 + windows/TapDriver6/TapDriver6.vcxproj.filters | 110 + windows/TapDriver6/adapter.c | 1717 + windows/TapDriver6/adapter.h | 352 + windows/TapDriver6/config.h | 9 + windows/TapDriver6/constants.h | 196 + windows/TapDriver6/device.c | 1209 + windows/TapDriver6/device.h | 50 + windows/TapDriver6/endian.h | 35 + windows/TapDriver6/error.c | 398 + windows/TapDriver6/error.h | 114 + windows/TapDriver6/hexdump.h | 63 + windows/TapDriver6/lock.h | 75 + windows/TapDriver6/macinfo.c | 164 + windows/TapDriver6/macinfo.h | 53 + windows/TapDriver6/mem.c | 401 + windows/TapDriver6/mem.h | 113 + windows/TapDriver6/oidrequest.c | 1028 + windows/TapDriver6/proto.h | 224 + windows/TapDriver6/prototypes.h | 91 + windows/TapDriver6/resource.h | 1573 + windows/TapDriver6/resource.rc | 88 + windows/TapDriver6/rxpath.c | 669 + windows/TapDriver6/tap-windows.h | 83 + windows/TapDriver6/tap.h | 89 + windows/TapDriver6/tapdrvr.c | 232 + windows/TapDriver6/txpath.c | 1175 + windows/TapDriver6/types.h | 90 + windows/TapDriver6/zttap300.inf | 145 + windows/ZeroTierOne.sln | 133 + windows/ZeroTierOne/ServiceBase.cpp | 563 + windows/ZeroTierOne/ServiceBase.h | 122 + windows/ZeroTierOne/ServiceInstaller.cpp | 197 + windows/ZeroTierOne/ServiceInstaller.h | 64 + windows/ZeroTierOne/ZeroTierOne.aps | Bin 0 -> 19308 bytes windows/ZeroTierOne/ZeroTierOne.rc | Bin 0 -> 2664 bytes windows/ZeroTierOne/ZeroTierOne.vcxproj | 660 + .../ZeroTierOne/ZeroTierOne.vcxproj.filters | 575 + windows/ZeroTierOne/ZeroTierOneService.cpp | 160 + windows/ZeroTierOne/ZeroTierOneService.h | 71 + windows/ZeroTierOne/resource.h | 14 + windows/ZeroTierOneSDK.sln | 28 + windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj | 257 + .../ZeroTierOneSDK.vcxproj.filters | 240 + windows/ZeroTierOneSDK/dllmain.cpp | 22 + windows/ZeroTierOneSDK/targetver.h | 8 + windows/packages/.gitignore | 3 + windows/packages/repositories.config | 4 + 1791 files changed, 489451 insertions(+) create mode 100644 .clang-format create mode 100644 .clangd create mode 100644 .dockerignore create mode 100644 .drone.jsonnet create mode 100644 .drone.yml create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/bugs-and-issues.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/game-connection-issue.md create mode 100644 .github/workflows/build.yml create mode 100755 .github/workflows/validate-linux.sh create mode 100755 .github/workflows/validate-report.sh create mode 100644 .github/workflows/validate.yml create mode 100755 .gitignore create mode 100644 .kick create mode 100644 AUTHORS.md create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 Dockerfile.ci create mode 100644 Dockerfile.release create mode 100644 LICENSE.txt create mode 100644 Makefile create mode 100644 OFFICIAL-RELEASE-STEPS.md create mode 100644 README.docker.md create mode 100644 README.md create mode 100644 RELEASE-NOTES.md create mode 100644 SECURITY.md create mode 100644 artwork/AppIcon.png create mode 100644 artwork/AppIcon@2x.png create mode 100644 artwork/AppIcon@3x.png create mode 100644 artwork/AppIcon_1024x1024.png create mode 100644 artwork/AppIcon_20x20.png create mode 100644 artwork/AppIcon_29x29.png create mode 100644 artwork/AppIcon_40x40.png create mode 100644 artwork/AppIcon_58x58.png create mode 100644 artwork/AppIcon_60x60.png create mode 100644 artwork/AppIcon_80x80.png create mode 100644 artwork/AppIcon_87x87.png create mode 100644 artwork/AppIcon_90x90.png create mode 100644 artwork/AppIcon_iPad@2x.png create mode 100644 artwork/AppIcon_iPadPro@2x.png create mode 100644 artwork/ZeroTierIcon-WithBorder.png create mode 100644 artwork/ZeroTierIcon.icns create mode 100644 artwork/ZeroTierIcon.ico create mode 100644 artwork/ZeroTierIcon.png create mode 100644 artwork/ZeroTierIcon32x32.png create mode 100644 artwork/ZeroTierIcon512x512.png create mode 100644 artwork/logo.html create mode 100644 attic/WinUI/APIHandler.cs create mode 100644 attic/WinUI/AboutView.xaml create mode 100644 attic/WinUI/AboutView.xaml.cs create mode 100644 attic/WinUI/App.config create mode 100644 attic/WinUI/App.xaml create mode 100644 attic/WinUI/App.xaml.cs create mode 100644 attic/WinUI/CentralAPI.cs create mode 100644 attic/WinUI/CentralLogin.cs create mode 100644 attic/WinUI/CentralNetwork.cs create mode 100644 attic/WinUI/CentralServer.cs create mode 100644 attic/WinUI/CentralToken.cs create mode 100644 attic/WinUI/CentralUser.cs create mode 100644 attic/WinUI/Fonts/segoeui.ttf create mode 100644 attic/WinUI/Fonts/segoeuib.ttf create mode 100644 attic/WinUI/Fonts/segoeuii.ttf create mode 100644 attic/WinUI/Fonts/segoeuiz.ttf create mode 100644 attic/WinUI/ISwitchable.cs create mode 100644 attic/WinUI/JoinNetworkView.xaml create mode 100644 attic/WinUI/JoinNetworkView.xaml.cs create mode 100644 attic/WinUI/MainWindow.xaml.cs create mode 100644 attic/WinUI/NetworkInfoView.xaml create mode 100644 attic/WinUI/NetworkInfoView.xaml.cs create mode 100644 attic/WinUI/NetworkListView.xaml create mode 100644 attic/WinUI/NetworkListView.xaml.cs create mode 100644 attic/WinUI/NetworkMonitor.cs create mode 100644 attic/WinUI/NetworkNameGenerator.cs create mode 100644 attic/WinUI/NetworkRoute.cs create mode 100644 attic/WinUI/NetworksPage.xaml create mode 100644 attic/WinUI/NetworksPage.xaml.cs create mode 100644 attic/WinUI/PeersPage.xaml create mode 100644 attic/WinUI/PeersPage.xaml.cs create mode 100644 attic/WinUI/PreferencesView.xaml create mode 100644 attic/WinUI/PreferencesView.xaml.cs create mode 100644 attic/WinUI/Properties/AssemblyInfo.cs create mode 100644 attic/WinUI/Properties/Resources.Designer.cs create mode 100644 attic/WinUI/Properties/Resources.resx create mode 100644 attic/WinUI/Properties/Settings.Designer.cs create mode 100644 attic/WinUI/Properties/Settings.settings create mode 100644 attic/WinUI/Resources/ZeroTierIcon.ico create mode 100644 attic/WinUI/Simple Styles.xaml create mode 100644 attic/WinUI/Themes/Generic.xaml create mode 100644 attic/WinUI/ToolbarItem.xaml create mode 100644 attic/WinUI/ToolbarItem.xaml.cs create mode 100644 attic/WinUI/WinUI.csproj create mode 100644 attic/WinUI/ZeroTierIcon.ico create mode 100644 attic/WinUI/ZeroTierNetwork.cs create mode 100644 attic/WinUI/ZeroTierPeer.cs create mode 100644 attic/WinUI/ZeroTierPeerPhysicalPath.cs create mode 100644 attic/WinUI/ZeroTierStatus.cs create mode 100644 attic/WinUI/app.manifest create mode 100644 attic/WinUI/packages.config create mode 100644 attic/historic/anode/LICENSE.txt create mode 100644 attic/historic/anode/config.mk.Darwin create mode 100644 attic/historic/anode/config.mk.Linux create mode 100644 attic/historic/anode/docs/anode_protocol.txt create mode 100644 attic/historic/anode/libanode/Makefile create mode 100644 attic/historic/anode/libanode/address.c create mode 100644 attic/historic/anode/libanode/aes_digest.c create mode 100644 attic/historic/anode/libanode/anode.h create mode 100644 attic/historic/anode/libanode/errors.c create mode 100644 attic/historic/anode/libanode/identity.c create mode 100644 attic/historic/anode/libanode/impl/aes.c create mode 100644 attic/historic/anode/libanode/impl/aes.h create mode 100644 attic/historic/anode/libanode/impl/dictionary.c create mode 100644 attic/historic/anode/libanode/impl/dictionary.h create mode 100644 attic/historic/anode/libanode/impl/dns_txt.c create mode 100644 attic/historic/anode/libanode/impl/dns_txt.h create mode 100644 attic/historic/anode/libanode/impl/ec.c create mode 100644 attic/historic/anode/libanode/impl/ec.h create mode 100644 attic/historic/anode/libanode/impl/environment.c create mode 100644 attic/historic/anode/libanode/impl/environment.h create mode 100644 attic/historic/anode/libanode/impl/http_client.c create mode 100644 attic/historic/anode/libanode/impl/http_client.h create mode 100644 attic/historic/anode/libanode/impl/misc.c create mode 100644 attic/historic/anode/libanode/impl/misc.h create mode 100644 attic/historic/anode/libanode/impl/mutex.h create mode 100644 attic/historic/anode/libanode/impl/thread.c create mode 100644 attic/historic/anode/libanode/impl/thread.h create mode 100644 attic/historic/anode/libanode/impl/types.h create mode 100644 attic/historic/anode/libanode/network_address.c create mode 100644 attic/historic/anode/libanode/secure_random.c create mode 100644 attic/historic/anode/libanode/system_transport.c create mode 100644 attic/historic/anode/libanode/tests/Makefile create mode 100644 attic/historic/anode/libanode/tests/aes-test.c create mode 100644 attic/historic/anode/libanode/tests/anode-secure_random-test.c create mode 100644 attic/historic/anode/libanode/tests/anode-utils-test.c create mode 100644 attic/historic/anode/libanode/tests/anode-zone-test.c create mode 100644 attic/historic/anode/libanode/tests/dictionary-test.c create mode 100644 attic/historic/anode/libanode/tests/ec-test.c create mode 100644 attic/historic/anode/libanode/tests/environment-test.c create mode 100644 attic/historic/anode/libanode/tests/http_client-test.c create mode 100644 attic/historic/anode/libanode/tests/misc-test.c create mode 100644 attic/historic/anode/libanode/tests/system_transport-test.c create mode 100644 attic/historic/anode/libanode/uri.c create mode 100644 attic/historic/anode/libanode/utils/anode-make-identity.c create mode 100644 attic/historic/anode/libanode/zone.c create mode 100644 attic/historic/anode/libspark/Makefile create mode 100644 attic/historic/anode/libspark/experiments/FindGoodSegmentDelimiters.cpp create mode 100644 attic/historic/anode/libspark/experiments/Makefile create mode 100644 attic/historic/anode/libspark/streamencoder.h create mode 100644 attic/historic/anode/libspark/wrapper.h create mode 100644 attic/historic/anode_protocol.txt create mode 100644 attic/macui/ZeroTier One.xcodeproj/project.pbxproj create mode 100644 attic/macui/ZeroTier One.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 attic/macui/ZeroTier One.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 attic/macui/ZeroTier One/AboutViewController.h create mode 100644 attic/macui/ZeroTier One/AboutViewController.m create mode 100644 attic/macui/ZeroTier One/AboutViewController.xib create mode 100644 attic/macui/ZeroTier One/AppDelegate.h create mode 100644 attic/macui/ZeroTier One/AppDelegate.m create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/AppIcon.appiconset/ZeroTierIcon512x512.png create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/Contents.json create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/Contents.json create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/MenuBar@2x.png create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/Menubar.png create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/MenuBarIconMacWhite.imageset/Contents.json create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/MenuBarIconMacWhite.imageset/MenubarWhite.png create mode 100644 attic/macui/ZeroTier One/Assets.xcassets/MenuBarIconMacWhite.imageset/MenubarWhite@2x.png create mode 100644 attic/macui/ZeroTier One/AuthtokenCopy.h create mode 100644 attic/macui/ZeroTier One/AuthtokenCopy.m create mode 100644 attic/macui/ZeroTier One/Base.lproj/MainMenu.xib create mode 100644 attic/macui/ZeroTier One/Info.plist create mode 100644 attic/macui/ZeroTier One/JoinNetworkViewController.h create mode 100644 attic/macui/ZeroTier One/JoinNetworkViewController.m create mode 100644 attic/macui/ZeroTier One/JoinNetworkViewController.xib create mode 100644 attic/macui/ZeroTier One/Network.h create mode 100644 attic/macui/ZeroTier One/Network.m create mode 100644 attic/macui/ZeroTier One/NetworkInfoCell.h create mode 100644 attic/macui/ZeroTier One/NetworkInfoCell.m create mode 100644 attic/macui/ZeroTier One/NetworkMonitor.h create mode 100644 attic/macui/ZeroTier One/NetworkMonitor.m create mode 100644 attic/macui/ZeroTier One/NodeStatus.h create mode 100644 attic/macui/ZeroTier One/NodeStatus.m create mode 100644 attic/macui/ZeroTier One/PreferencesViewController.h create mode 100644 attic/macui/ZeroTier One/PreferencesViewController.m create mode 100644 attic/macui/ZeroTier One/PreferencesViewController.xib create mode 100644 attic/macui/ZeroTier One/ServiceCom.h create mode 100644 attic/macui/ZeroTier One/ServiceCom.m create mode 100644 attic/macui/ZeroTier One/ShowNetworksViewController.h create mode 100644 attic/macui/ZeroTier One/ShowNetworksViewController.m create mode 100644 attic/macui/ZeroTier One/ShowNetworksViewController.xib create mode 100644 attic/macui/ZeroTier One/ZeroTier One.entitlements create mode 100644 attic/macui/ZeroTier One/ZeroTierIcon.icns create mode 100644 attic/macui/ZeroTier One/about.html create mode 100644 attic/macui/ZeroTier One/main.m create mode 100644 attic/world/README.md create mode 100755 attic/world/build.sh create mode 100644 attic/world/mkworld.cpp create mode 100644 attic/world/world.bin create mode 100644 attic/world/world.c create mode 100644 backone-cli-completion.bash create mode 100644 backone.spec create mode 100644 ci/Dockerfile-build.el6 create mode 100644 ci/Dockerfile-test.el6 create mode 100755 ci/scripts/build.sh create mode 100755 ci/scripts/lib.sh create mode 100755 ci/scripts/munge_debian_changelog.sh create mode 100755 ci/scripts/munge_rpm_spec.sh create mode 100755 ci/scripts/publish.sh create mode 100755 ci/scripts/test.sh create mode 100644 controller/ConnectionPool.hpp create mode 100644 controller/DB.cpp create mode 100644 controller/DB.hpp create mode 100644 controller/DBMirrorSet.cpp create mode 100644 controller/DBMirrorSet.hpp create mode 100644 controller/EmbeddedNetworkController.cpp create mode 100644 controller/EmbeddedNetworkController.hpp create mode 100644 controller/FileDB.cpp create mode 100644 controller/FileDB.hpp create mode 100644 controller/LFDB.cpp create mode 100644 controller/LFDB.hpp create mode 100644 controller/PostgreSQL.cpp create mode 100644 controller/PostgreSQL.hpp create mode 100644 controller/README.md create mode 100644 controller/Redis.hpp create mode 100755 cycle_controllers.sh create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/control.wheezy create mode 100644 debian/copyright create mode 100644 debian/postinst create mode 100644 debian/rules create mode 100644 debian/rules.static create mode 100644 debian/rules.wheezy create mode 100644 debian/rules.wheezy.static create mode 100644 debian/source/format create mode 100644 debian/ufw-zerotier-one create mode 100644 debian/zerotier-one.init create mode 100644 debian/zerotier-one.service create mode 100644 debian/zerotier-one.upstart create mode 100644 doc/README.md create mode 100755 doc/build.sh create mode 100644 doc/contact@zerotier.com.gpg create mode 100644 doc/manpage_encoding_declaration.UTF-8 create mode 100644 doc/zerotier-cli.1 create mode 100644 doc/zerotier-cli.1.md create mode 100644 doc/zerotier-idtool.1 create mode 100644 doc/zerotier-idtool.1.md create mode 100644 doc/zerotier-one.8 create mode 100644 doc/zerotier-one.8.md create mode 100644 entrypoint.sh.release create mode 100644 ext/README.md create mode 100644 ext/arm32-neon-salsa2012-asm/README.md create mode 100644 ext/arm32-neon-salsa2012-asm/salsa2012.h create mode 100644 ext/arm32-neon-salsa2012-asm/salsa2012.s create mode 100644 ext/bin/tap-windows-ndis6/arm64/zttap300.cat create mode 100644 ext/bin/tap-windows-ndis6/arm64/zttap300.inf create mode 100644 ext/bin/tap-windows-ndis6/arm64/zttap300.sys create mode 100644 ext/bin/tap-windows-ndis6/x64/zttap300.cat create mode 100644 ext/bin/tap-windows-ndis6/x64/zttap300.inf create mode 100644 ext/bin/tap-windows-ndis6/x64/zttap300.sys create mode 100644 ext/bin/tap-windows-ndis6/x86/zttap300.cat create mode 100644 ext/bin/tap-windows-ndis6/x86/zttap300.inf create mode 100644 ext/bin/tap-windows-ndis6/x86/zttap300.sys create mode 100644 ext/central-controller-docker/Dockerfile create mode 100644 ext/central-controller-docker/Dockerfile.builder create mode 100644 ext/central-controller-docker/Dockerfile.run_base create mode 100644 ext/central-controller-docker/Makefile create mode 100644 ext/central-controller-docker/README.md create mode 100755 ext/central-controller-docker/main.sh create mode 100644 ext/cpp-httplib/httplib.h create mode 100644 ext/ed25519-amd64-asm/batch.c create mode 100644 ext/ed25519-amd64-asm/choose_t.s create mode 100644 ext/ed25519-amd64-asm/consts.s create mode 100644 ext/ed25519-amd64-asm/fe25519.h create mode 100644 ext/ed25519-amd64-asm/fe25519_add.s create mode 100644 ext/ed25519-amd64-asm/fe25519_freeze.s create mode 100644 ext/ed25519-amd64-asm/fe25519_getparity.c create mode 100644 ext/ed25519-amd64-asm/fe25519_invert.c create mode 100644 ext/ed25519-amd64-asm/fe25519_iseq.c create mode 100644 ext/ed25519-amd64-asm/fe25519_iszero.c create mode 100644 ext/ed25519-amd64-asm/fe25519_mul.s create mode 100644 ext/ed25519-amd64-asm/fe25519_neg.c create mode 100644 ext/ed25519-amd64-asm/fe25519_pack.c create mode 100644 ext/ed25519-amd64-asm/fe25519_pow2523.c create mode 100644 ext/ed25519-amd64-asm/fe25519_setint.c create mode 100644 ext/ed25519-amd64-asm/fe25519_square.s create mode 100644 ext/ed25519-amd64-asm/fe25519_sub.s create mode 100644 ext/ed25519-amd64-asm/fe25519_unpack.c create mode 100644 ext/ed25519-amd64-asm/ge25519.h create mode 100644 ext/ed25519-amd64-asm/ge25519_add.c create mode 100644 ext/ed25519-amd64-asm/ge25519_add_p1p1.s create mode 100644 ext/ed25519-amd64-asm/ge25519_base.c create mode 100644 ext/ed25519-amd64-asm/ge25519_base_niels.data create mode 100644 ext/ed25519-amd64-asm/ge25519_base_niels_smalltables.data create mode 100644 ext/ed25519-amd64-asm/ge25519_base_slide_multiples.data create mode 100644 ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s create mode 100644 ext/ed25519-amd64-asm/ge25519_double.c create mode 100644 ext/ed25519-amd64-asm/ge25519_double_scalarmult.c create mode 100644 ext/ed25519-amd64-asm/ge25519_isneutral.c create mode 100644 ext/ed25519-amd64-asm/ge25519_multi_scalarmult.c create mode 100644 ext/ed25519-amd64-asm/ge25519_nielsadd2.s create mode 100644 ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s create mode 100644 ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s create mode 100644 ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s create mode 100644 ext/ed25519-amd64-asm/ge25519_pack.c create mode 100644 ext/ed25519-amd64-asm/ge25519_pnielsadd_p1p1.s create mode 100644 ext/ed25519-amd64-asm/ge25519_scalarmult_base.c create mode 100644 ext/ed25519-amd64-asm/ge25519_unpackneg.c create mode 100644 ext/ed25519-amd64-asm/heap_rootreplaced.s create mode 100644 ext/ed25519-amd64-asm/heap_rootreplaced_1limb.s create mode 100644 ext/ed25519-amd64-asm/heap_rootreplaced_2limbs.s create mode 100644 ext/ed25519-amd64-asm/heap_rootreplaced_3limbs.s create mode 100644 ext/ed25519-amd64-asm/hram.c create mode 100644 ext/ed25519-amd64-asm/hram.h create mode 100644 ext/ed25519-amd64-asm/implementors create mode 100644 ext/ed25519-amd64-asm/index_heap.c create mode 100644 ext/ed25519-amd64-asm/index_heap.h create mode 100644 ext/ed25519-amd64-asm/keypair.c create mode 100644 ext/ed25519-amd64-asm/open.c create mode 100644 ext/ed25519-amd64-asm/sc25519.h create mode 100644 ext/ed25519-amd64-asm/sc25519_add.s create mode 100644 ext/ed25519-amd64-asm/sc25519_barrett.s create mode 100644 ext/ed25519-amd64-asm/sc25519_from32bytes.c create mode 100644 ext/ed25519-amd64-asm/sc25519_from64bytes.c create mode 100644 ext/ed25519-amd64-asm/sc25519_from_shortsc.c create mode 100644 ext/ed25519-amd64-asm/sc25519_iszero.c create mode 100644 ext/ed25519-amd64-asm/sc25519_lt.s create mode 100644 ext/ed25519-amd64-asm/sc25519_mul.c create mode 100644 ext/ed25519-amd64-asm/sc25519_mul_shortsc.c create mode 100644 ext/ed25519-amd64-asm/sc25519_slide.c create mode 100644 ext/ed25519-amd64-asm/sc25519_sub_nored.s create mode 100644 ext/ed25519-amd64-asm/sc25519_to32bytes.c create mode 100644 ext/ed25519-amd64-asm/sc25519_window4.c create mode 100644 ext/ed25519-amd64-asm/sign.c create mode 100644 ext/ed25519-amd64-asm/ull4_mul.s create mode 100644 ext/hiredis-0.14.1/.gitignore create mode 100644 ext/hiredis-0.14.1/.travis.yml create mode 100644 ext/hiredis-0.14.1/CHANGELOG.md create mode 100644 ext/hiredis-0.14.1/COPYING create mode 100644 ext/hiredis-0.14.1/Makefile create mode 100644 ext/hiredis-0.14.1/README.md create mode 100644 ext/hiredis-0.14.1/adapters/ae.h create mode 100644 ext/hiredis-0.14.1/adapters/glib.h create mode 100644 ext/hiredis-0.14.1/adapters/ivykis.h create mode 100644 ext/hiredis-0.14.1/adapters/libev.h create mode 100644 ext/hiredis-0.14.1/adapters/libevent.h create mode 100644 ext/hiredis-0.14.1/adapters/libuv.h create mode 100644 ext/hiredis-0.14.1/adapters/macosx.h create mode 100644 ext/hiredis-0.14.1/adapters/qt.h create mode 100644 ext/hiredis-0.14.1/alloc.c create mode 100644 ext/hiredis-0.14.1/alloc.h create mode 100644 ext/hiredis-0.14.1/appveyor.yml create mode 100644 ext/hiredis-0.14.1/async.c create mode 100644 ext/hiredis-0.14.1/async.h create mode 100644 ext/hiredis-0.14.1/dict.c create mode 100644 ext/hiredis-0.14.1/dict.h create mode 100644 ext/hiredis-0.14.1/examples/example-ae.c create mode 100644 ext/hiredis-0.14.1/examples/example-glib.c create mode 100644 ext/hiredis-0.14.1/examples/example-ivykis.c create mode 100644 ext/hiredis-0.14.1/examples/example-libev.c create mode 100644 ext/hiredis-0.14.1/examples/example-libevent.c create mode 100644 ext/hiredis-0.14.1/examples/example-libuv.c create mode 100644 ext/hiredis-0.14.1/examples/example-macosx.c create mode 100644 ext/hiredis-0.14.1/examples/example-qt.cpp create mode 100644 ext/hiredis-0.14.1/examples/example-qt.h create mode 100644 ext/hiredis-0.14.1/examples/example.c create mode 100644 ext/hiredis-0.14.1/fmacros.h create mode 100644 ext/hiredis-0.14.1/hiredis.c create mode 100644 ext/hiredis-0.14.1/hiredis.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/alloc.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/async.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/dict.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/fmacros.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/hiredis.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/net.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/read.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/sds.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/sdsalloc.h create mode 100644 ext/hiredis-0.14.1/include/hiredis/win32.h create mode 100644 ext/hiredis-0.14.1/lib/centos8/libhiredis.a create mode 100644 ext/hiredis-0.14.1/lib/macos/libhiredis.a create mode 100644 ext/hiredis-0.14.1/net.c create mode 100644 ext/hiredis-0.14.1/net.h create mode 100644 ext/hiredis-0.14.1/read.c create mode 100644 ext/hiredis-0.14.1/read.h create mode 100644 ext/hiredis-0.14.1/sds.c create mode 100644 ext/hiredis-0.14.1/sds.h create mode 100644 ext/hiredis-0.14.1/sdsalloc.h create mode 100644 ext/hiredis-0.14.1/test.c create mode 100644 ext/hiredis-0.14.1/win32.h create mode 100644 ext/hiredis-1.0.2/.gitignore create mode 100644 ext/hiredis-1.0.2/.travis.yml create mode 100644 ext/hiredis-1.0.2/CHANGELOG.md create mode 100644 ext/hiredis-1.0.2/CMakeLists.txt create mode 100644 ext/hiredis-1.0.2/COPYING create mode 100644 ext/hiredis-1.0.2/Makefile create mode 100644 ext/hiredis-1.0.2/README.md create mode 100644 ext/hiredis-1.0.2/adapters/ae.h create mode 100644 ext/hiredis-1.0.2/adapters/glib.h create mode 100644 ext/hiredis-1.0.2/adapters/ivykis.h create mode 100644 ext/hiredis-1.0.2/adapters/libev.h create mode 100644 ext/hiredis-1.0.2/adapters/libevent.h create mode 100644 ext/hiredis-1.0.2/adapters/libuv.h create mode 100644 ext/hiredis-1.0.2/adapters/macosx.h create mode 100644 ext/hiredis-1.0.2/adapters/qt.h create mode 100644 ext/hiredis-1.0.2/alloc.c create mode 100644 ext/hiredis-1.0.2/alloc.h create mode 100644 ext/hiredis-1.0.2/appveyor.yml create mode 100644 ext/hiredis-1.0.2/async.c create mode 100644 ext/hiredis-1.0.2/async.h create mode 100644 ext/hiredis-1.0.2/async_private.h create mode 100644 ext/hiredis-1.0.2/dict.c create mode 100644 ext/hiredis-1.0.2/dict.h create mode 100644 ext/hiredis-1.0.2/examples/CMakeLists.txt create mode 100644 ext/hiredis-1.0.2/examples/example-ae.c create mode 100644 ext/hiredis-1.0.2/examples/example-glib.c create mode 100644 ext/hiredis-1.0.2/examples/example-ivykis.c create mode 100644 ext/hiredis-1.0.2/examples/example-libev.c create mode 100644 ext/hiredis-1.0.2/examples/example-libevent-ssl.c create mode 100644 ext/hiredis-1.0.2/examples/example-libevent.c create mode 100644 ext/hiredis-1.0.2/examples/example-libuv.c create mode 100644 ext/hiredis-1.0.2/examples/example-macosx.c create mode 100644 ext/hiredis-1.0.2/examples/example-push.c create mode 100644 ext/hiredis-1.0.2/examples/example-qt.cpp create mode 100644 ext/hiredis-1.0.2/examples/example-qt.h create mode 100644 ext/hiredis-1.0.2/examples/example-ssl.c create mode 100644 ext/hiredis-1.0.2/examples/example.c create mode 100644 ext/hiredis-1.0.2/fmacros.h create mode 100644 ext/hiredis-1.0.2/hiredis-config.cmake.in create mode 100644 ext/hiredis-1.0.2/hiredis.c create mode 100644 ext/hiredis-1.0.2/hiredis.h create mode 100644 ext/hiredis-1.0.2/hiredis.pc.in create mode 100644 ext/hiredis-1.0.2/hiredis_ssl-config.cmake.in create mode 100644 ext/hiredis-1.0.2/hiredis_ssl.h create mode 100644 ext/hiredis-1.0.2/hiredis_ssl.pc.in create mode 100644 ext/hiredis-1.0.2/include/hiredis/alloc.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/async.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/async_private.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/dict.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/fmacros.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/hiredis.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/hiredis_ssl.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/net.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/read.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/sds.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/sdsalloc.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/sockcompat.h create mode 100644 ext/hiredis-1.0.2/include/hiredis/win32.h create mode 100644 ext/hiredis-1.0.2/lib/ubuntu22.04/amd64/libhiredis.a create mode 100644 ext/hiredis-1.0.2/lib/ubuntu22.04/arm64/libhiredis.a create mode 100644 ext/hiredis-1.0.2/net.c create mode 100644 ext/hiredis-1.0.2/net.h create mode 100644 ext/hiredis-1.0.2/read.c create mode 100644 ext/hiredis-1.0.2/read.h create mode 100644 ext/hiredis-1.0.2/sds.c create mode 100644 ext/hiredis-1.0.2/sds.h create mode 100644 ext/hiredis-1.0.2/sdsalloc.h create mode 100644 ext/hiredis-1.0.2/sockcompat.c create mode 100644 ext/hiredis-1.0.2/sockcompat.h create mode 100644 ext/hiredis-1.0.2/ssl.c create mode 100644 ext/hiredis-1.0.2/test.c create mode 100755 ext/hiredis-1.0.2/test.sh create mode 100644 ext/hiredis-1.0.2/win32.h create mode 100644 ext/http-parser/AUTHORS create mode 100644 ext/http-parser/LICENSE-MIT create mode 100644 ext/http-parser/README.md create mode 100644 ext/http-parser/http_parser.c create mode 100644 ext/http-parser/http_parser.h create mode 100644 ext/inja/LICENSE create mode 100644 ext/inja/README.md create mode 100644 ext/inja/inja.hpp create mode 100644 ext/installfiles/linux/zerotier-containerized/Dockerfile create mode 100755 ext/installfiles/linux/zerotier-containerized/main.sh create mode 100755 ext/installfiles/linux/zerotier-one.init.rhel6 create mode 100644 ext/installfiles/linux/zerotier-one.te create mode 100644 ext/installfiles/mac-update/updater.tmpl.sh create mode 100755 ext/installfiles/mac/BackOne.pkgproj create mode 100644 ext/installfiles/mac/com.backone.plist create mode 100755 ext/installfiles/mac/get-proxy-settings.sh create mode 100755 ext/installfiles/mac/launch.sh create mode 100755 ext/installfiles/mac/postinst.sh create mode 100755 ext/installfiles/mac/preinst.sh create mode 100755 ext/installfiles/mac/uninstall.sh create mode 100644 ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x64).aip create mode 100644 ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x86).aip create mode 100644 ext/installfiles/windows/ZeroTier One.aip create mode 100644 ext/installfiles/windows/ZeroTier One.back.aip create mode 100644 ext/libnatpmp/Changelog.txt create mode 100644 ext/libnatpmp/JavaTest.java create mode 100644 ext/libnatpmp/LICENSE create mode 100644 ext/libnatpmp/Makefile create mode 100644 ext/libnatpmp/README create mode 100644 ext/libnatpmp/build.bat create mode 100644 ext/libnatpmp/declspec.h create mode 100644 ext/libnatpmp/fr/free/miniupnp/libnatpmp/LibraryExtractor.java create mode 100644 ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmp.java create mode 100644 ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmpResponse.java create mode 100644 ext/libnatpmp/fr/free/miniupnp/libnatpmp/URLUtils.java create mode 100644 ext/libnatpmp/getgateway.c create mode 100644 ext/libnatpmp/getgateway.h create mode 100644 ext/libnatpmp/libnatpmpmodule.c create mode 100644 ext/libnatpmp/msvc/libnatpmp.sln create mode 100644 ext/libnatpmp/msvc/libnatpmp.vcproj create mode 100644 ext/libnatpmp/msvc/natpmpc-static.vcproj create mode 100644 ext/libnatpmp/natpmp-jni.c create mode 100644 ext/libnatpmp/natpmp.c create mode 100644 ext/libnatpmp/natpmp.def create mode 100644 ext/libnatpmp/natpmp.h create mode 100644 ext/libnatpmp/natpmpc.1 create mode 100644 ext/libnatpmp/natpmpc.c create mode 100644 ext/libnatpmp/setup.py create mode 100644 ext/libnatpmp/setupmingw32.py create mode 100644 ext/libnatpmp/testgetgateway.c create mode 100644 ext/libnatpmp/wingettimeofday.c create mode 100644 ext/libnatpmp/wingettimeofday.h create mode 100644 ext/libpqxx-7.7.3/.circleci/config.yml create mode 100644 ext/libpqxx-7.7.3/.clang-format create mode 100644 ext/libpqxx-7.7.3/.cmake-format create mode 100644 ext/libpqxx-7.7.3/.github/workflows/stale.yml create mode 100644 ext/libpqxx-7.7.3/.gitignore create mode 100644 ext/libpqxx-7.7.3/.lgtm.yml create mode 100644 ext/libpqxx-7.7.3/.lift/ignoreFiles create mode 100644 ext/libpqxx-7.7.3/AUTHORS create mode 100644 ext/libpqxx-7.7.3/BUILDING-cmake.md create mode 100644 ext/libpqxx-7.7.3/BUILDING-configure.md create mode 100644 ext/libpqxx-7.7.3/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/COPYING create mode 100644 ext/libpqxx-7.7.3/Makefile.am create mode 100644 ext/libpqxx-7.7.3/Makefile.in create mode 100644 ext/libpqxx-7.7.3/NEWS create mode 100644 ext/libpqxx-7.7.3/README.md create mode 100644 ext/libpqxx-7.7.3/VERSION create mode 100644 ext/libpqxx-7.7.3/aclocal.m4 create mode 100644 ext/libpqxx-7.7.3/appveyor.yml create mode 100755 ext/libpqxx-7.7.3/autogen.sh create mode 100644 ext/libpqxx-7.7.3/cmake/config.cmake create mode 100644 ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake create mode 100644 ext/libpqxx-7.7.3/compile_flags.in create mode 100644 ext/libpqxx-7.7.3/config-tests/README.md create mode 100644 ext/libpqxx-7.7.3/config-tests/charconv_float.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/charconv_int.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/cmp.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/concepts.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/fs.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/likely.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/need_fslib.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/poll.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/sleep_for.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/span.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/strerror_r.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/strerror_s.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/thread_local.cxx create mode 100644 ext/libpqxx-7.7.3/config-tests/year_month_day.cxx create mode 100644 ext/libpqxx-7.7.3/config/Makefile.am create mode 100644 ext/libpqxx-7.7.3/config/Makefile.in create mode 100755 ext/libpqxx-7.7.3/config/compile create mode 100755 ext/libpqxx-7.7.3/config/config.guess create mode 100755 ext/libpqxx-7.7.3/config/config.sub create mode 100755 ext/libpqxx-7.7.3/config/depcomp create mode 100755 ext/libpqxx-7.7.3/config/install-sh create mode 100755 ext/libpqxx-7.7.3/config/ltmain.sh create mode 100644 ext/libpqxx-7.7.3/config/m4/Makefile.am create mode 100644 ext/libpqxx-7.7.3/config/m4/libtool.m4 create mode 100644 ext/libpqxx-7.7.3/config/m4/ltoptions.m4 create mode 100644 ext/libpqxx-7.7.3/config/m4/ltsugar.m4 create mode 100644 ext/libpqxx-7.7.3/config/m4/ltversion.m4 create mode 100644 ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 create mode 100755 ext/libpqxx-7.7.3/config/missing create mode 100755 ext/libpqxx-7.7.3/config/mkinstalldirs create mode 100755 ext/libpqxx-7.7.3/config/test-driver create mode 100644 ext/libpqxx-7.7.3/configitems create mode 100755 ext/libpqxx-7.7.3/configure create mode 100644 ext/libpqxx-7.7.3/configure.ac create mode 100644 ext/libpqxx-7.7.3/doc/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/doc/Doxyfile.in create mode 100644 ext/libpqxx-7.7.3/doc/Makefile.am create mode 100644 ext/libpqxx-7.7.3/doc/Makefile.in create mode 100644 ext/libpqxx-7.7.3/doc/conf.py create mode 100644 ext/libpqxx-7.7.3/doc/index.rst create mode 100644 ext/libpqxx-7.7.3/include/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/include/CMakeLists.txt.template create mode 100644 ext/libpqxx-7.7.3/include/Makefile.am create mode 100644 ext/libpqxx-7.7.3/include/Makefile.in create mode 100644 ext/libpqxx-7.7.3/include/pqxx/Makefile.am create mode 100644 ext/libpqxx-7.7.3/include/pqxx/Makefile.in create mode 100644 ext/libpqxx-7.7.3/include/pqxx/array create mode 100644 ext/libpqxx-7.7.3/include/pqxx/array.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/binarystring create mode 100644 ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/blob create mode 100644 ext/libpqxx-7.7.3/include/pqxx/blob.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/composite create mode 100644 ext/libpqxx-7.7.3/include/pqxx/composite.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/config.h.in create mode 100644 ext/libpqxx-7.7.3/include/pqxx/connection create mode 100644 ext/libpqxx-7.7.3/include/pqxx/connection.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/cursor create mode 100644 ext/libpqxx-7.7.3/include/pqxx/cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/dbtransaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/performance.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/streams.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md create mode 100644 ext/libpqxx-7.7.3/include/pqxx/errorhandler create mode 100644 ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/except create mode 100644 ext/libpqxx-7.7.3/include/pqxx/except.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/field create mode 100644 ext/libpqxx-7.7.3/include/pqxx/field.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/isolation create mode 100644 ext/libpqxx-7.7.3/include/pqxx/isolation.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/largeobject create mode 100644 ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/nontransaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/notification create mode 100644 ext/libpqxx-7.7.3/include/pqxx/notification.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/params create mode 100644 ext/libpqxx-7.7.3/include/pqxx/params.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/pipeline create mode 100644 ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/pqxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/prepared_statement create mode 100644 ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/range create mode 100644 ext/libpqxx-7.7.3/include/pqxx/range.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/result create mode 100644 ext/libpqxx-7.7.3/include/pqxx/result.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/robusttransaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/row create mode 100644 ext/libpqxx-7.7.3/include/pqxx/row.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/separated_list create mode 100644 ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/strconv create mode 100644 ext/libpqxx-7.7.3/include/pqxx/strconv.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/stream_from create mode 100644 ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/stream_to create mode 100644 ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/subtransaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/time create mode 100644 ext/libpqxx-7.7.3/include/pqxx/time.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction_base create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction_focus create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transactor create mode 100644 ext/libpqxx-7.7.3/include/pqxx/transactor.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/types create mode 100644 ext/libpqxx-7.7.3/include/pqxx/types.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/util create mode 100644 ext/libpqxx-7.7.3/include/pqxx/util.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/version create mode 100644 ext/libpqxx-7.7.3/include/pqxx/version.hxx create mode 100644 ext/libpqxx-7.7.3/include/pqxx/version.hxx.template create mode 100644 ext/libpqxx-7.7.3/include/pqxx/zview create mode 100644 ext/libpqxx-7.7.3/include/pqxx/zview.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/config-public-compiler.h create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/array-composite.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/callgate.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/concat.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/conversions.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encoding_group.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encodings.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-notification_receiver.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-transaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/errorhandler-connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-creation.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-post.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-pre.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-post.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-pre.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/libpq-forward.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iter.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/statement_parameters.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/stream_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/wait.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pqxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config-version.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/libpqxx-7.7.a create mode 120000 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/libpqxx.a create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/accessing-results.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/binary-data.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/datatypes.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/escaping.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/getting-started.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/mainpage.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/parameters.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/performance.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/prepared-statement.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/streams.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/thread-safety.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/config-public-compiler.h create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/array-composite.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/callgate.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/concat.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/conversions.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encoding_group.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encodings.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-errorhandler.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-notification_receiver.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-transaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/errorhandler-connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-connection.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-creation.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-post.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-pre.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-post.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-pre.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/libpq-forward.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iter.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/sql_cursor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/statement_parameters.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/stream_iterator.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/wait.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pqxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview.hxx create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config-version.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets.cmake create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/libpqxx-7.7.a create mode 120000 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/libpqxx.a create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/accessing-results.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/binary-data.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/datatypes.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/escaping.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/getting-started.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/mainpage.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/parameters.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/performance.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/prepared-statement.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/streams.md create mode 100644 ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/share/doc/libpqxx/thread-safety.md create mode 100644 ext/libpqxx-7.7.3/libpqxx.pc.in create mode 100644 ext/libpqxx-7.7.3/requirements.json create mode 100644 ext/libpqxx-7.7.3/src/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/src/Makefile.am create mode 100644 ext/libpqxx-7.7.3/src/Makefile.in create mode 100644 ext/libpqxx-7.7.3/src/array.cxx create mode 100644 ext/libpqxx-7.7.3/src/binarystring.cxx create mode 100644 ext/libpqxx-7.7.3/src/blob.cxx create mode 100644 ext/libpqxx-7.7.3/src/connection.cxx create mode 100644 ext/libpqxx-7.7.3/src/cursor.cxx create mode 100644 ext/libpqxx-7.7.3/src/encodings.cxx create mode 100644 ext/libpqxx-7.7.3/src/errorhandler.cxx create mode 100644 ext/libpqxx-7.7.3/src/except.cxx create mode 100644 ext/libpqxx-7.7.3/src/field.cxx create mode 100644 ext/libpqxx-7.7.3/src/largeobject.cxx create mode 100644 ext/libpqxx-7.7.3/src/notification.cxx create mode 100644 ext/libpqxx-7.7.3/src/params.cxx create mode 100644 ext/libpqxx-7.7.3/src/pipeline.cxx create mode 100644 ext/libpqxx-7.7.3/src/pqxx-source.hxx create mode 100644 ext/libpqxx-7.7.3/src/result.cxx create mode 100644 ext/libpqxx-7.7.3/src/robusttransaction.cxx create mode 100644 ext/libpqxx-7.7.3/src/row.cxx create mode 100644 ext/libpqxx-7.7.3/src/sql_cursor.cxx create mode 100644 ext/libpqxx-7.7.3/src/strconv.cxx create mode 100644 ext/libpqxx-7.7.3/src/stream_from.cxx create mode 100644 ext/libpqxx-7.7.3/src/stream_to.cxx create mode 100644 ext/libpqxx-7.7.3/src/subtransaction.cxx create mode 100644 ext/libpqxx-7.7.3/src/time.cxx create mode 100644 ext/libpqxx-7.7.3/src/transaction.cxx create mode 100644 ext/libpqxx-7.7.3/src/transaction_base.cxx create mode 100644 ext/libpqxx-7.7.3/src/util.cxx create mode 100644 ext/libpqxx-7.7.3/src/version.cxx create mode 100644 ext/libpqxx-7.7.3/src/wait.cxx create mode 100644 ext/libpqxx-7.7.3/test/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/test/Makefile.am create mode 100644 ext/libpqxx-7.7.3/test/Makefile.am.template create mode 100644 ext/libpqxx-7.7.3/test/Makefile.in create mode 100644 ext/libpqxx-7.7.3/test/runner.cxx create mode 100644 ext/libpqxx-7.7.3/test/test00.cxx create mode 100644 ext/libpqxx-7.7.3/test/test01.cxx create mode 100644 ext/libpqxx-7.7.3/test/test02.cxx create mode 100644 ext/libpqxx-7.7.3/test/test04.cxx create mode 100644 ext/libpqxx-7.7.3/test/test07.cxx create mode 100644 ext/libpqxx-7.7.3/test/test10.cxx create mode 100644 ext/libpqxx-7.7.3/test/test11.cxx create mode 100644 ext/libpqxx-7.7.3/test/test13.cxx create mode 100644 ext/libpqxx-7.7.3/test/test14.cxx create mode 100644 ext/libpqxx-7.7.3/test/test16.cxx create mode 100644 ext/libpqxx-7.7.3/test/test17.cxx create mode 100644 ext/libpqxx-7.7.3/test/test18.cxx create mode 100644 ext/libpqxx-7.7.3/test/test20.cxx create mode 100644 ext/libpqxx-7.7.3/test/test21.cxx create mode 100644 ext/libpqxx-7.7.3/test/test26.cxx create mode 100644 ext/libpqxx-7.7.3/test/test29.cxx create mode 100644 ext/libpqxx-7.7.3/test/test30.cxx create mode 100644 ext/libpqxx-7.7.3/test/test32.cxx create mode 100644 ext/libpqxx-7.7.3/test/test37.cxx create mode 100644 ext/libpqxx-7.7.3/test/test39.cxx create mode 100644 ext/libpqxx-7.7.3/test/test46.cxx create mode 100644 ext/libpqxx-7.7.3/test/test56.cxx create mode 100644 ext/libpqxx-7.7.3/test/test60.cxx create mode 100644 ext/libpqxx-7.7.3/test/test61.cxx create mode 100644 ext/libpqxx-7.7.3/test/test62.cxx create mode 100644 ext/libpqxx-7.7.3/test/test69.cxx create mode 100644 ext/libpqxx-7.7.3/test/test70.cxx create mode 100644 ext/libpqxx-7.7.3/test/test71.cxx create mode 100644 ext/libpqxx-7.7.3/test/test72.cxx create mode 100644 ext/libpqxx-7.7.3/test/test74.cxx create mode 100644 ext/libpqxx-7.7.3/test/test75.cxx create mode 100644 ext/libpqxx-7.7.3/test/test76.cxx create mode 100644 ext/libpqxx-7.7.3/test/test77.cxx create mode 100644 ext/libpqxx-7.7.3/test/test78.cxx create mode 100644 ext/libpqxx-7.7.3/test/test79.cxx create mode 100644 ext/libpqxx-7.7.3/test/test82.cxx create mode 100644 ext/libpqxx-7.7.3/test/test84.cxx create mode 100644 ext/libpqxx-7.7.3/test/test87.cxx create mode 100644 ext/libpqxx-7.7.3/test/test88.cxx create mode 100644 ext/libpqxx-7.7.3/test/test89.cxx create mode 100644 ext/libpqxx-7.7.3/test/test90.cxx create mode 100644 ext/libpqxx-7.7.3/test/test_helpers.hxx create mode 100644 ext/libpqxx-7.7.3/test/test_types.hxx create mode 100644 ext/libpqxx-7.7.3/test/unit/CMakeLists.txt create mode 100644 ext/libpqxx-7.7.3/test/unit/test_array.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_binarystring.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_blob.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_cancel_query.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_column.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_composite.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_connection.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_cursor.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_encodings.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_error_verbosity.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_errorhandler.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_escape.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_exceptions.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_field.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_float.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_largeobject.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_nonblocking_connect.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_notification.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_pipeline.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_prepared_statement.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_range.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_read_transaction.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_result_iteration.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_result_slicing.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_row.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_separated_list.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_simultaneous_transactions.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_sql_cursor.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_stateless_cursor.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_strconv.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_stream_from.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_stream_to.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_string_conversion.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_subtransaction.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_test_helpers.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_thread_safety_model.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_time.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_transaction.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_transaction_base.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_transaction_focus.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_transactor.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_type_name.cxx create mode 100644 ext/libpqxx-7.7.3/test/unit/test_zview.cxx create mode 100644 ext/libpqxx-7.7.3/tools/Makefile.am create mode 100644 ext/libpqxx-7.7.3/tools/Makefile.in create mode 100755 ext/libpqxx-7.7.3/tools/deprecations create mode 100755 ext/libpqxx-7.7.3/tools/extract_version create mode 100755 ext/libpqxx-7.7.3/tools/format create mode 100755 ext/libpqxx-7.7.3/tools/lint create mode 100755 ext/libpqxx-7.7.3/tools/m4esc.py create mode 100644 ext/libpqxx-7.7.3/tools/pqxxthreadsafety.cxx create mode 100644 ext/libpqxx-7.7.3/tools/rmlo.cxx create mode 100755 ext/libpqxx-7.7.3/tools/splitconfig create mode 100755 ext/libpqxx-7.7.3/tools/template2mak.py create mode 100755 ext/libpqxx-7.7.3/tools/test_all.py create mode 100755 ext/libpqxx-7.7.3/tools/todo create mode 100755 ext/libpqxx-7.7.3/tools/update-copyright create mode 100644 ext/miniupnpc/Changelog.txt create mode 100644 ext/miniupnpc/LICENSE create mode 100644 ext/miniupnpc/README create mode 100644 ext/miniupnpc/VERSION create mode 100644 ext/miniupnpc/codelength.h create mode 100644 ext/miniupnpc/connecthostport.c create mode 100644 ext/miniupnpc/connecthostport.h create mode 100644 ext/miniupnpc/igd_desc_parse.c create mode 100644 ext/miniupnpc/igd_desc_parse.h create mode 100644 ext/miniupnpc/listdevices.c create mode 100644 ext/miniupnpc/minisoap.c create mode 100644 ext/miniupnpc/minisoap.h create mode 100644 ext/miniupnpc/minissdpc.c create mode 100644 ext/miniupnpc/minissdpc.h create mode 100644 ext/miniupnpc/miniupnpc.c create mode 100644 ext/miniupnpc/miniupnpc.def create mode 100644 ext/miniupnpc/miniupnpc.h create mode 100644 ext/miniupnpc/miniupnpc_declspec.h create mode 100644 ext/miniupnpc/miniupnpcmodule.c create mode 100644 ext/miniupnpc/miniupnpcstrings.h.in create mode 100644 ext/miniupnpc/miniupnpctypes.h create mode 100644 ext/miniupnpc/miniwget.c create mode 100644 ext/miniupnpc/miniwget.h create mode 100644 ext/miniupnpc/minixml.c create mode 100644 ext/miniupnpc/minixml.h create mode 100644 ext/miniupnpc/minixmlvalid.c create mode 100644 ext/miniupnpc/portlistingparse.c create mode 100644 ext/miniupnpc/portlistingparse.h create mode 100644 ext/miniupnpc/receivedata.c create mode 100644 ext/miniupnpc/receivedata.h create mode 100755 ext/miniupnpc/updateminiupnpcstrings.sh create mode 100644 ext/miniupnpc/upnpc.c create mode 100644 ext/miniupnpc/upnpcommands.c create mode 100644 ext/miniupnpc/upnpcommands.h create mode 100644 ext/miniupnpc/upnpdev.c create mode 100644 ext/miniupnpc/upnpdev.h create mode 100644 ext/miniupnpc/upnperrors.c create mode 100644 ext/miniupnpc/upnperrors.h create mode 100644 ext/miniupnpc/upnpreplyparse.c create mode 100644 ext/miniupnpc/upnpreplyparse.h create mode 100644 ext/miniupnpc/wingenminiupnpcstrings.c create mode 100644 ext/misc/linux-old-glibc-compat.c create mode 100644 ext/nlohmann/LICENSE.MIT create mode 100644 ext/nlohmann/README.md create mode 100644 ext/nlohmann/json.hpp create mode 100644 ext/prometheus-cpp-lite-1.0/.gitignore create mode 100644 ext/prometheus-cpp-lite-1.0/3rdpatry/http-client-lite/CMakeLists.txt create mode 100644 ext/prometheus-cpp-lite-1.0/3rdpatry/http-client-lite/LICENSE create mode 100644 ext/prometheus-cpp-lite-1.0/3rdpatry/http-client-lite/README.md create mode 100644 ext/prometheus-cpp-lite-1.0/3rdpatry/http-client-lite/examples/CMakeLists.txt create mode 100644 ext/prometheus-cpp-lite-1.0/3rdpatry/http-client-lite/examples/simple_request.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/3rdpatry/http-client-lite/include/jdl/httpclientlite.h create mode 100644 ext/prometheus-cpp-lite-1.0/CMakeLists.txt create mode 100644 ext/prometheus-cpp-lite-1.0/LICENSE create mode 100644 ext/prometheus-cpp-lite-1.0/README.md create mode 100644 ext/prometheus-cpp-lite-1.0/core/CMakeLists.txt create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/atomic_floating.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/benchmark.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/builder.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/ckms_quantiles.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/client_metric.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/collectable.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/counter.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/family.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/gateway.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/gauge.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/hash.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/histogram.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/metric.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/metric_family.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/push_to_server.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/registry.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/save_to_file.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/summary.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/text_serializer.h create mode 100644 ext/prometheus-cpp-lite-1.0/core/include/prometheus/time_window_quantiles.h create mode 100644 ext/prometheus-cpp-lite-1.0/examples/CMakeLists.txt create mode 100644 ext/prometheus-cpp-lite-1.0/examples/gateway_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/modern_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/original_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/push_to_server_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/save_to_file_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/simpleapi_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/simpleapi_use_in_class_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/use_benchmark_in_class_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/use_counters_in_class_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/examples/use_gauge_in_class_example.cpp create mode 100644 ext/prometheus-cpp-lite-1.0/simpleapi/CMakeLists.txt create mode 100644 ext/prometheus-cpp-lite-1.0/simpleapi/include/prometheus/simpleapi.h create mode 100644 ext/prometheus-cpp-lite-1.0/simpleapi/src/simpleapi.cpp create mode 100644 ext/redis-plus-plus-1.1.1/.gitignore create mode 100644 ext/redis-plus-plus-1.1.1/CMakeLists.txt create mode 100644 ext/redis-plus-plus-1.1.1/LICENSE create mode 100644 ext/redis-plus-plus-1.1.1/README.md create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/command.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/command_args.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/command_options.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/connection.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/connection_pool.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/errors.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/pipeline.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/queued_redis.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/queued_redis.hpp create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/redis++.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/redis.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/redis.hpp create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/redis_cluster.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/redis_cluster.hpp create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/reply.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/sentinel.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/shards.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/shards_pool.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/subscriber.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/transaction.h create mode 100644 ext/redis-plus-plus-1.1.1/install/centos8/include/sw/redis++/utils.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/command.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/command_args.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/command_options.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/connection.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/connection_pool.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/errors.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/pipeline.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/queued_redis.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/queued_redis.hpp create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/redis++.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/redis.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/redis.hpp create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/redis_cluster.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/redis_cluster.hpp create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/reply.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/sentinel.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/shards.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/shards_pool.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/subscriber.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/transaction.h create mode 100644 ext/redis-plus-plus-1.1.1/install/macos/include/sw/redis++/utils.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/command.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/command.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/command_args.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/command_options.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/command_options.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/connection.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/connection.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/connection_pool.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/connection_pool.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/crc16.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/errors.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/errors.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/pipeline.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/pipeline.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/queued_redis.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/queued_redis.hpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/redis++.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/redis.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/redis.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/redis.hpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/redis_cluster.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/redis_cluster.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/redis_cluster.hpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/reply.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/reply.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/sentinel.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/sentinel.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/shards.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/shards.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/shards_pool.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/shards_pool.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/subscriber.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/subscriber.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/transaction.cpp create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/transaction.h create mode 100644 ext/redis-plus-plus-1.1.1/src/sw/redis++/utils.h create mode 100644 ext/redis-plus-plus-1.1.1/test/CMakeLists.txt create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/benchmark_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/benchmark_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/connection_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/connection_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/geo_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/geo_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/hash_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/hash_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/hyperloglog_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/hyperloglog_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/keys_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/keys_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/list_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/list_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/pipeline_transaction_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/pipeline_transaction_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/pubsub_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/pubsub_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/sanity_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/sanity_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/script_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/script_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/set_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/set_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/stream_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/stream_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/string_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/string_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/test_main.cpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/threads_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/threads_test.hpp create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/utils.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/zset_cmds_test.h create mode 100644 ext/redis-plus-plus-1.1.1/test/src/sw/redis++/zset_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 ext/redis-plus-plus-1.3.3/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 ext/redis-plus-plus-1.3.3/.github/ISSUE_TEMPLATE/question.md create mode 100644 ext/redis-plus-plus-1.3.3/.gitignore create mode 100644 ext/redis-plus-plus-1.3.3/.travis.yml create mode 100644 ext/redis-plus-plus-1.3.3/CMakeLists.txt create mode 100644 ext/redis-plus-plus-1.3.3/LICENSE create mode 100644 ext/redis-plus-plus-1.3.3/README.md create mode 100644 ext/redis-plus-plus-1.3.3/cmake/redis++-config.cmake.in create mode 100644 ext/redis-plus-plus-1.3.3/cmake/redis++.pc.in create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/cmd_formatter.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/command.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/command_args.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/command_options.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/connection.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/connection_pool.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/cxx_utils.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/errors.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/pipeline.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/queued_redis.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/queued_redis.hpp create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/redis++.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/redis.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/redis.hpp create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/redis_cluster.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/redis_cluster.hpp create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/reply.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/sentinel.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/shards.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/shards_pool.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/subscriber.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/tls.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/transaction.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/include/sw/redis++/utils.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/lib/pkgconfig/redis++.pc create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/share/cmake/redis++/redis++-config-version.cmake create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/share/cmake/redis++/redis++-config.cmake create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/share/cmake/redis++/redis++-targets-release.cmake create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/amd64/share/cmake/redis++/redis++-targets.cmake create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/cmd_formatter.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/command.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/command_args.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/command_options.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/connection.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/connection_pool.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/cxx_utils.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/errors.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/pipeline.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/queued_redis.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/queued_redis.hpp create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/redis++.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/redis.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/redis.hpp create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/redis_cluster.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/redis_cluster.hpp create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/reply.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/sentinel.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/shards.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/shards_pool.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/subscriber.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/tls.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/transaction.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/include/sw/redis++/utils.h create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/lib/pkgconfig/redis++.pc create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/share/cmake/redis++/redis++-config-version.cmake create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/share/cmake/redis++/redis++-config.cmake create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/share/cmake/redis++/redis++-targets-release.cmake create mode 100644 ext/redis-plus-plus-1.3.3/install/ubuntu22.04/arm64/share/cmake/redis++/redis++-targets.cmake create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_connection.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_connection.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_connection_pool.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_connection_pool.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_redis++.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_redis.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_redis.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_redis_cluster.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_redis_cluster.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_sentinel.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_sentinel.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_shards_pool.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/async_shards_pool.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/cmd_formatter.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/command.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/command.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/command_args.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/command_options.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/command_options.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/connection.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/connection.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/connection_pool.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/connection_pool.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/crc16.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/cxx11/cxx_utils.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/cxx17/cxx_utils.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/errors.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/errors.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/event_loop.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/event_loop.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/future/boost/async_utils.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/future/std/async_utils.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/no_tls/tls.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/pipeline.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/pipeline.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/queued_redis.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/queued_redis.hpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/redis++.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/redis.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/redis.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/redis.hpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/redis_cluster.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/redis_cluster.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/redis_cluster.hpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/reply.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/reply.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/sentinel.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/sentinel.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/shards.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/shards.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/shards_pool.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/shards_pool.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/subscriber.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/subscriber.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/tls/tls.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/tls/tls.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/transaction.cpp create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/transaction.h create mode 100644 ext/redis-plus-plus-1.3.3/src/sw/redis++/utils.h create mode 100644 ext/redis-plus-plus-1.3.3/test/CMakeLists.txt create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/benchmark_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/benchmark_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/connection_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/connection_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/geo_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/geo_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/hash_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/hash_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/hyperloglog_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/hyperloglog_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/keys_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/keys_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/list_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/list_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/pipeline_transaction_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/pipeline_transaction_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/pubsub_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/pubsub_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/sanity_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/sanity_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/script_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/script_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/set_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/set_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/stream_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/stream_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/string_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/string_cmds_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/test_main.cpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/threads_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/threads_test.hpp create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/utils.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/zset_cmds_test.h create mode 100644 ext/redis-plus-plus-1.3.3/test/src/sw/redis++/zset_cmds_test.hpp create mode 100644 ext/x64-salsa2012-asm/README.md create mode 100644 ext/x64-salsa2012-asm/salsa2012.h create mode 100644 ext/x64-salsa2012-asm/salsa2012.s create mode 100644 include/README.md create mode 100644 include/ZeroTierDebug.h create mode 100644 include/ZeroTierOne.h create mode 100644 java/CMakeLists.txt create mode 100644 java/README.md create mode 100644 java/build.xml create mode 100644 java/jni/ZT_jnicache.cpp create mode 100644 java/jni/ZT_jnicache.h create mode 100644 java/jni/ZT_jniutils.cpp create mode 100644 java/jni/ZT_jniutils.h create mode 100644 java/jni/com_zerotierone_sdk_Node.cpp create mode 100644 java/jni/com_zerotierone_sdk_Node.h create mode 100644 java/src/com/zerotier/sdk/DataStoreGetListener.java create mode 100644 java/src/com/zerotier/sdk/DataStorePutListener.java create mode 100644 java/src/com/zerotier/sdk/Event.java create mode 100644 java/src/com/zerotier/sdk/EventListener.java create mode 100644 java/src/com/zerotier/sdk/Node.java create mode 100644 java/src/com/zerotier/sdk/NodeStatus.java create mode 100644 java/src/com/zerotier/sdk/PacketSender.java create mode 100644 java/src/com/zerotier/sdk/PathChecker.java create mode 100644 java/src/com/zerotier/sdk/Peer.java create mode 100644 java/src/com/zerotier/sdk/PeerPhysicalPath.java create mode 100644 java/src/com/zerotier/sdk/PeerRole.java create mode 100644 java/src/com/zerotier/sdk/ResultCode.java create mode 100644 java/src/com/zerotier/sdk/Version.java create mode 100644 java/src/com/zerotier/sdk/VirtualNetworkConfig.java create mode 100644 java/src/com/zerotier/sdk/VirtualNetworkConfigListener.java create mode 100644 java/src/com/zerotier/sdk/VirtualNetworkConfigOperation.java create mode 100644 java/src/com/zerotier/sdk/VirtualNetworkDNS.java create mode 100644 java/src/com/zerotier/sdk/VirtualNetworkFrameListener.java create mode 100644 java/src/com/zerotier/sdk/VirtualNetworkRoute.java create mode 100644 java/src/com/zerotier/sdk/VirtualNetworkStatus.java create mode 100644 java/src/com/zerotier/sdk/VirtualNetworkType.java create mode 100644 java/src/com/zerotier/sdk/util/StringUtils.java create mode 100644 java/test/com/zerotier/sdk/util/StringUtilsTest.java create mode 100644 make-bsd.mk create mode 100644 make-linux.mk create mode 100644 make-mac.mk create mode 100644 make-netbsd.mk create mode 100644 node/AES.cpp create mode 100644 node/AES.hpp create mode 100644 node/AES_aesni.cpp create mode 100644 node/AES_armcrypto.cpp create mode 100644 node/Address.hpp create mode 100644 node/AtomicCounter.hpp create mode 100644 node/Bond.cpp create mode 100644 node/Bond.hpp create mode 100644 node/Buffer.hpp create mode 100644 node/C25519.cpp create mode 100644 node/C25519.hpp create mode 100644 node/Capability.cpp create mode 100644 node/Capability.hpp create mode 100644 node/CertificateOfMembership.cpp create mode 100644 node/CertificateOfMembership.hpp create mode 100644 node/CertificateOfOwnership.cpp create mode 100644 node/CertificateOfOwnership.hpp create mode 100644 node/Constants.hpp create mode 100644 node/Credential.hpp create mode 100644 node/DNS.hpp create mode 100644 node/Dictionary.hpp create mode 100644 node/Hashtable.hpp create mode 100644 node/Identity.cpp create mode 100644 node/Identity.hpp create mode 100644 node/IncomingPacket.cpp create mode 100644 node/IncomingPacket.hpp create mode 100644 node/InetAddress.cpp create mode 100644 node/InetAddress.hpp create mode 100644 node/MAC.hpp create mode 100644 node/Membership.cpp create mode 100644 node/Membership.hpp create mode 100644 node/Metrics.cpp create mode 100644 node/Metrics.hpp create mode 100644 node/MulticastGroup.hpp create mode 100644 node/Multicaster.cpp create mode 100644 node/Multicaster.hpp create mode 100644 node/Mutex.hpp create mode 100644 node/Network.cpp create mode 100644 node/Network.hpp create mode 100644 node/NetworkConfig.cpp create mode 100644 node/NetworkConfig.hpp create mode 100644 node/NetworkController.hpp create mode 100644 node/Node.cpp create mode 100644 node/Node.hpp create mode 100644 node/OutboundMulticast.cpp create mode 100644 node/OutboundMulticast.hpp create mode 100644 node/Packet.cpp create mode 100644 node/Packet.hpp create mode 100644 node/PacketMultiplexer.cpp create mode 100644 node/PacketMultiplexer.hpp create mode 100644 node/Path.cpp create mode 100644 node/Path.hpp create mode 100644 node/Peer.cpp create mode 100644 node/Peer.hpp create mode 100644 node/Poly1305.cpp create mode 100644 node/Poly1305.hpp create mode 100644 node/README.md create mode 100644 node/Revocation.cpp create mode 100644 node/Revocation.hpp create mode 100644 node/RingBuffer.hpp create mode 100644 node/RuntimeEnvironment.hpp create mode 100644 node/SHA512.cpp create mode 100644 node/SHA512.hpp create mode 100644 node/Salsa20.cpp create mode 100644 node/Salsa20.hpp create mode 100644 node/SelfAwareness.cpp create mode 100644 node/SelfAwareness.hpp create mode 100644 node/SharedPtr.hpp create mode 100644 node/Switch.cpp create mode 100644 node/Switch.hpp create mode 100644 node/Tag.cpp create mode 100644 node/Tag.hpp create mode 100644 node/Topology.cpp create mode 100644 node/Topology.hpp create mode 100644 node/Trace.cpp create mode 100644 node/Trace.hpp create mode 100644 node/Utils.cpp create mode 100644 node/Utils.hpp create mode 100644 node/World.hpp create mode 100644 objects.mk create mode 100644 one.cpp create mode 100644 osdep/Arp.cpp create mode 100644 osdep/Arp.hpp create mode 100644 osdep/BSDEthernetTap.cpp create mode 100644 osdep/BSDEthernetTap.hpp create mode 100644 osdep/Binder.hpp create mode 100644 osdep/BlockingQueue.hpp create mode 100644 osdep/EthernetTap.cpp create mode 100644 osdep/EthernetTap.hpp create mode 100644 osdep/Http.cpp create mode 100644 osdep/Http.hpp create mode 100644 osdep/LinuxEthernetTap.cpp create mode 100644 osdep/LinuxEthernetTap.hpp create mode 100644 osdep/LinuxNetLink.cpp create mode 100644 osdep/LinuxNetLink.hpp create mode 100644 osdep/MacDNSHelper.hpp create mode 100644 osdep/MacDNSHelper.mm create mode 100644 osdep/MacEthernetTap.cpp create mode 100644 osdep/MacEthernetTap.hpp create mode 100644 osdep/MacEthernetTapAgent.c create mode 100644 osdep/MacEthernetTapAgent.h create mode 100644 osdep/MacKextEthernetTap.cpp create mode 100644 osdep/MacKextEthernetTap.hpp create mode 100644 osdep/ManagedRoute.cpp create mode 100644 osdep/ManagedRoute.hpp create mode 100644 osdep/NeighborDiscovery.cpp create mode 100644 osdep/NeighborDiscovery.hpp create mode 100644 osdep/NetBSDEthernetTap.cpp create mode 100644 osdep/NetBSDEthernetTap.hpp create mode 100644 osdep/OSUtils.cpp create mode 100644 osdep/OSUtils.hpp create mode 100644 osdep/Phy.hpp create mode 100644 osdep/PortMapper.cpp create mode 100644 osdep/PortMapper.hpp create mode 100644 osdep/README.md create mode 100644 osdep/Thread.hpp create mode 100644 osdep/WinDNSHelper.cpp create mode 100644 osdep/WinDNSHelper.hpp create mode 100644 osdep/WinFWHelper.cpp create mode 100644 osdep/WinFWHelper.hpp create mode 100644 osdep/WindowsEthernetTap.cpp create mode 100644 osdep/WindowsEthernetTap.hpp create mode 100644 osdep/freebsd_getifmaddrs.c create mode 100644 osdep/freebsd_getifmaddrs.h create mode 100644 pkg/README.md create mode 100644 pkg/asustor/Dockerfile create mode 100755 pkg/asustor/build.sh create mode 100755 pkg/asustor/entrypoint.sh create mode 100644 pkg/asustor/zerotier/CONTROL/config.json create mode 100644 pkg/asustor/zerotier/CONTROL/description.txt create mode 100644 pkg/asustor/zerotier/CONTROL/icon.png create mode 100644 pkg/asustor/zerotier/CONTROL/license.txt create mode 100755 pkg/asustor/zerotier/CONTROL/post-install.sh create mode 100755 pkg/asustor/zerotier/CONTROL/post-uninstall.sh create mode 100755 pkg/asustor/zerotier/CONTROL/pre-install.sh create mode 100755 pkg/asustor/zerotier/CONTROL/pre-uninstall.sh create mode 100755 pkg/asustor/zerotier/CONTROL/start-stop.sh create mode 100644 pkg/asustor/zerotier/apkg-version create mode 100644 pkg/asustor/zerotier/www/index.html create mode 100644 pkg/config.json create mode 100644 pkg/qnap/Dockerfile create mode 100755 pkg/qnap/build.sh create mode 100755 pkg/qnap/entrypoint.sh create mode 100644 pkg/qnap/qdk.conf create mode 100644 pkg/qnap/zerotier/Makefile create mode 100644 pkg/qnap/zerotier/arm_64/.gitkeep create mode 100644 pkg/qnap/zerotier/arm_x09/.gitkeep create mode 100644 pkg/qnap/zerotier/arm_x10/.gitkeep create mode 100644 pkg/qnap/zerotier/arm_x12/.gitkeep create mode 100644 pkg/qnap/zerotier/arm_x19/.gitkeep create mode 100644 pkg/qnap/zerotier/arm_x31/.gitkeep create mode 100644 pkg/qnap/zerotier/arm_x41/.gitkeep create mode 100644 pkg/qnap/zerotier/config/.gitkeep create mode 100644 pkg/qnap/zerotier/icons/.gitkeep create mode 100644 pkg/qnap/zerotier/icons/ZeroTier.gif create mode 100644 pkg/qnap/zerotier/icons/ZeroTier_80.gif create mode 100644 pkg/qnap/zerotier/icons/ZeroTier_gray.gif create mode 100644 pkg/qnap/zerotier/package_routines create mode 100644 pkg/qnap/zerotier/qpkg.cfg create mode 100644 pkg/qnap/zerotier/shared/.gitkeep create mode 100644 pkg/qnap/zerotier/shared/.qpkg_icon.gif create mode 100644 pkg/qnap/zerotier/shared/.qpkg_icon_80.gif create mode 100644 pkg/qnap/zerotier/shared/.qpkg_icon_gray.gif create mode 100755 pkg/qnap/zerotier/shared/zerotier.sh create mode 100644 pkg/qnap/zerotier/x86/.gitkeep create mode 100644 pkg/qnap/zerotier/x86_64/.gitkeep create mode 100644 pkg/qnap/zerotier/x86_ce53xx/.gitkeep create mode 100644 pkg/snap/snapcraft.yaml create mode 100644 pkg/synology/Dockerfile.spksrc create mode 100644 pkg/synology/README.md create mode 100755 pkg/synology/build.sh create mode 100644 pkg/synology/dsm6-pkg/PACKAGE_ICON.png create mode 100644 pkg/synology/dsm6-pkg/PACKAGE_ICON_256.png create mode 100644 pkg/synology/dsm6-pkg/scripts/postinst create mode 100644 pkg/synology/dsm6-pkg/scripts/postuninst create mode 100644 pkg/synology/dsm6-pkg/scripts/postupgrade create mode 100644 pkg/synology/dsm6-pkg/scripts/preinst create mode 100644 pkg/synology/dsm6-pkg/scripts/preuninst create mode 100644 pkg/synology/dsm6-pkg/scripts/preupgrade create mode 100644 pkg/synology/dsm6-pkg/service-setup.sh create mode 100755 pkg/synology/dsm6-pkg/start-stop-status.sh create mode 100644 pkg/synology/dsm7-docker/Dockerfile create mode 100644 pkg/synology/dsm7-docker/README.md create mode 100755 pkg/synology/dsm7-docker/build.sh create mode 100755 pkg/synology/dsm7-docker/entrypoint.sh create mode 100755 pkg/synology/syn-pkg-entrypoint.sh create mode 100644 pkg/wd/Dockerfile create mode 100755 pkg/wd/build.sh create mode 100755 pkg/wd/entrypoint.sh create mode 100644 pkg/wd/zerotier/apkg.rc create mode 100644 pkg/wd/zerotier/apkg.xml create mode 100755 pkg/wd/zerotier/clean.sh create mode 100755 pkg/wd/zerotier/init.sh create mode 100755 pkg/wd/zerotier/install.sh create mode 100755 pkg/wd/zerotier/preinst.sh create mode 100755 pkg/wd/zerotier/remove.sh create mode 100755 pkg/wd/zerotier/start.sh create mode 100755 pkg/wd/zerotier/stop.sh create mode 100644 pkg/wd/zerotier/web/index.html create mode 100644 pkg/wd/zerotier/web/zerotier.png create mode 100644 pkg/wd/zerotier/zerotier.png create mode 100644 rule-compiler/README.md create mode 100644 rule-compiler/cli.js create mode 100644 rule-compiler/examples/capabilities-and-tags.ztrules create mode 100644 rule-compiler/package.json create mode 100644 rule-compiler/rule-compiler.js create mode 100644 rustybits/Cargo.lock create mode 100644 rustybits/Cargo.toml create mode 100644 rustybits/rustfmt.toml create mode 100644 rustybits/smeeclient/Cargo.toml create mode 100644 rustybits/smeeclient/build.rs create mode 120000 rustybits/smeeclient/rustfmt.toml create mode 100644 rustybits/smeeclient/src/ext.rs create mode 100644 rustybits/smeeclient/src/lib.rs create mode 100644 rustybits/zeroidc.vcxproj create mode 100644 rustybits/zeroidc.vcxproj.filters create mode 100644 rustybits/zeroidc/.cargo/config.toml create mode 100644 rustybits/zeroidc/.gitattributes create mode 100644 rustybits/zeroidc/Cargo.toml create mode 100644 rustybits/zeroidc/build.rs create mode 120000 rustybits/zeroidc/rustfmt.toml create mode 100644 rustybits/zeroidc/src/error.rs create mode 100644 rustybits/zeroidc/src/ext.rs create mode 100644 rustybits/zeroidc/src/lib.rs create mode 100644 selftest.cpp create mode 100644 service/OneService.cpp create mode 100644 service/OneService.hpp create mode 100644 service/README.md create mode 100644 service/SoftwareUpdater.cpp create mode 100644 service/SoftwareUpdater.hpp create mode 100644 tcp-proxy/Makefile create mode 100644 tcp-proxy/README.md create mode 100644 tcp-proxy/tcp-proxy.cpp create mode 100644 tcp-proxy/zerotier-proxy.service create mode 100755 update_controllers.sh create mode 100644 version.h create mode 100644 windows-clean.bat create mode 100644 windows/README.md create mode 100644 windows/TapDriver6/TapDriver6.vcxproj create mode 100644 windows/TapDriver6/TapDriver6.vcxproj.filters create mode 100644 windows/TapDriver6/adapter.c create mode 100644 windows/TapDriver6/adapter.h create mode 100644 windows/TapDriver6/config.h create mode 100644 windows/TapDriver6/constants.h create mode 100644 windows/TapDriver6/device.c create mode 100644 windows/TapDriver6/device.h create mode 100644 windows/TapDriver6/endian.h create mode 100644 windows/TapDriver6/error.c create mode 100644 windows/TapDriver6/error.h create mode 100644 windows/TapDriver6/hexdump.h create mode 100644 windows/TapDriver6/lock.h create mode 100644 windows/TapDriver6/macinfo.c create mode 100644 windows/TapDriver6/macinfo.h create mode 100644 windows/TapDriver6/mem.c create mode 100644 windows/TapDriver6/mem.h create mode 100644 windows/TapDriver6/oidrequest.c create mode 100644 windows/TapDriver6/proto.h create mode 100644 windows/TapDriver6/prototypes.h create mode 100644 windows/TapDriver6/resource.h create mode 100644 windows/TapDriver6/resource.rc create mode 100644 windows/TapDriver6/rxpath.c create mode 100644 windows/TapDriver6/tap-windows.h create mode 100644 windows/TapDriver6/tap.h create mode 100644 windows/TapDriver6/tapdrvr.c create mode 100644 windows/TapDriver6/txpath.c create mode 100644 windows/TapDriver6/types.h create mode 100644 windows/TapDriver6/zttap300.inf create mode 100644 windows/ZeroTierOne.sln create mode 100644 windows/ZeroTierOne/ServiceBase.cpp create mode 100644 windows/ZeroTierOne/ServiceBase.h create mode 100644 windows/ZeroTierOne/ServiceInstaller.cpp create mode 100644 windows/ZeroTierOne/ServiceInstaller.h create mode 100644 windows/ZeroTierOne/ZeroTierOne.aps create mode 100644 windows/ZeroTierOne/ZeroTierOne.rc create mode 100644 windows/ZeroTierOne/ZeroTierOne.vcxproj create mode 100644 windows/ZeroTierOne/ZeroTierOne.vcxproj.filters create mode 100644 windows/ZeroTierOne/ZeroTierOneService.cpp create mode 100644 windows/ZeroTierOne/ZeroTierOneService.h create mode 100644 windows/ZeroTierOne/resource.h create mode 100644 windows/ZeroTierOneSDK.sln create mode 100644 windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj create mode 100644 windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj.filters create mode 100644 windows/ZeroTierOneSDK/dllmain.cpp create mode 100644 windows/ZeroTierOneSDK/targetver.h create mode 100644 windows/packages/.gitignore create mode 100644 windows/packages/repositories.config diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..400349f --- /dev/null +++ b/.clang-format @@ -0,0 +1,75 @@ +--- +BasedOnStyle: LLVM +BreakBeforeBraces: Stroustrup +IndentWidth: 4 +TabWidth: 4 +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveMacros: 'true' +AlignConsecutiveAssignments: 'false' +AlignConsecutiveDeclarations: 'false' +AlignEscapedNewlines: Right +AlignOperands: 'true' +AlignTrailingComments: 'true' +AllowAllArgumentsOnNextLine: 'false' +AllowAllConstructorInitializersOnNextLine: 'false' +AllowAllParametersOfDeclarationOnNextLine: 'false' +AllowShortBlocksOnASingleLine: 'true' +AllowShortCaseLabelsOnASingleLine: 'false' +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AlwaysBreakAfterReturnType: None +BinPackArguments: 'false' +BinPackParameters: 'false' +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeTernaryOperators: 'true' +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma +CompactNamespaces: 'false' +ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' +ConstructorInitializerIndentWidth: '4' +ContinuationIndentWidth: '4' +Cpp11BracedListStyle: 'false' +FixNamespaceComments: 'true' +IncludeBlocks: Regroup +IndentCaseLabels: 'true' +IndentPPDirectives: None +IndentWrappedFunctionNames: 'false' +KeepEmptyLinesAtTheStartOfBlocks: 'false' +MaxEmptyLinesToKeep: '1' +NamespaceIndentation: None +PointerAlignment: Left +ReflowComments: 'true' +SortIncludes: 'true' +SortUsingDeclarations: 'true' +SpaceAfterCStyleCast: 'false' +SpaceAfterLogicalNot: 'true' +SpaceAfterTemplateKeyword: 'true' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeCpp11BracedList: 'true' +SpaceBeforeCtorInitializerColon: 'true' +SpaceBeforeInheritanceColon: 'true' +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: 'true' +SpaceInEmptyParentheses: 'false' +SpacesBeforeTrailingComments: '3' +SpacesInAngles: 'false' +SpacesInCStyleCastParentheses: 'false' +SpacesInContainerLiterals: 'true' +SpacesInParentheses: 'false' +SpacesInSquareBrackets: 'false' +UseTab: 'Always' + +--- +Language: Cpp +Standard: Cpp03 +ColumnLimit: '240' +--- +Language: ObjC +ColumnLimit: '240' +--- +Language: Java +ColumnLimit: '240' +--- +Language: CSharp +ColumnLimit: '240' +... diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..0605ccd --- /dev/null +++ b/.clangd @@ -0,0 +1,6 @@ +CompileFlags: + Add: + - "-std=c++17" + - "-I../ext" + - "-I../ext/prometheus-cpp-lite-1.0/core/include" + - "-I../ext/prometheus-cpp-lite-1.0/simpleapi/include" diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4acef40 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +.git/ +workspace/ diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 0000000..7daef37 --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,256 @@ +// +// tweakables +// + +local registry = "084037375216.dkr.ecr.us-east-2.amazonaws.com"; +local build_channel = "zerotier-builds"; +local release_channel = "zerotier-releases"; + +local targets = [ + { "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag", "custom" ] }, + { "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, + { "os": "linux", distro: "redhat", "name": "el7", "isas": [ "386", "amd64", "ppc64le"], "events": [ "tag" ] }, + { "os": "linux", distro: "amazon", "name": "amzn2", "isas": [ "amd64", "arm64" ], "events": [ "tag" ] }, + { "os": "linux", distro: "amazon", "name": "amzn2022", "isas": [ "amd64", "arm64" ], "events": [ "tag" ] }, + { "os": "linux", distro: "fedora", "name": "fc38", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, + { "os": "linux", distro: "fedora", "name": "fc37", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, + { "os": "linux", distro: "fedora", "name": "fc36", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, + { "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "tag" ] }, + { "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "tag" ] }, + { "os": "linux", distro: "ubuntu", "name": "bionic", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, + { "os": "linux", distro: "ubuntu", "name": "xenial", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, + { "os": "linux", distro: "ubuntu", "name": "trusty", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] }, + { "os": "linux", distro: "debian", "name": "bookworm", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "tag"] }, + { "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "debian", "name": "buster", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] }, + { "os": "linux", distro: "debian", "name": "stretch", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] }, + { "os": "linux", distro: "debian", "name": "jessie", "isas": [ "386", "armv7", "amd64" ], "events": [ "tag" ] }, + +// { "os": "windows", distro: "windows", "name": "windows", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] }, +// { "os": "darwin", distro: "darwin", "name": "darwin", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] }, + +]; + +local less_targets = [ + { "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, +]; + + +local native_targets = [ + { "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, +]; + +local master_targets = [ + // + // copypasta from here + // + { "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "redhat", "name": "el7", "isas": [ "386", "amd64", "ppc64le"], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "amazon", "name": "amzn2", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "amazon", "name": "amzn2022", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "fedora", "name": "fc38", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "fedora", "name": "fc37", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "fedora", "name": "fc36", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "ubuntu", "name": "bionic", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "ubuntu", "name": "xenial", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "ubuntu", "name": "trusty", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "debian", "name": "sid", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "debian", "name": "bookworm", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "debian", "name": "buster", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "debian", "name": "stretch", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "linux", distro: "debian", "name": "jessie", "isas": [ "386", "armv7", "amd64" ], "events": [ "push", "tag", "custom" ] }, + { "os": "windows", distro: "windows", "name": "win2k22", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] } +]; + +// +// functions +// + +local pipeline_type(os) = if os == "darwin" then "exec" else "docker"; +local builder_image(os) = if os == "linux" then registry + "/honda-builder" else registry + "/windows-builder"; +local tester_image(os) = if os == "linux" then registry + "/honda-builder" else registry + "/windows-tester"; +local build_step_volumes(os) = if os == "linux" then [ { name: "zerotier-builds", path: "/zerotier-builds" } ] else []; +local release_step_volumes(os) = if os == "linux" then [ { name: "zerotier-releases", path: "/zerotier-releases" } ] else []; +local host_volumes(os) = if os == "linux" then [ + { name: "zerotier-builds", host: { path: "/zerotier-builds" } }, + { name: "zerotier-releases", host: { path: "/zerotier-releases" } }, +] else []; + +local index_image(distro) = + if distro == "debian" || distro == "ubuntu" then + registry + "/apt-builder" + else if distro == "redhat" || distro == "fedora" || distro == "amazon" then + registry + "/dnf-builder" + else if distro == "windows" then + registry + "/msi-builder" +; + +local copy_commands(os, distro, name, isa, version) = + if os == "linux" then [ + std.join(" ", [ "./ci/scripts/publish.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ]) + ] + else if os == "windows" then [ + "C:\\scripts\\fix-ec2-metadata.ps1", + "Get-ChildItem windows", + // "aws s3 cp windows\\bytey-SetupFiles\\bytey.msi s3://zerotier-builds/windows/" + version + "/bytey.msi", + ] else if os == "darwin" then [ + "echo hello" + ] +; + +local index_commands(os, channel, distro, name, isas) = + if os == "linux" then + [ "/usr/local/bin/index " + channel + " " + distro + " " + name + " " + std.join(" ", isas) ] + else if os == "windows" then + [ "Get-ChildItem -Recurse windows" ] +; + +local build_commands(os, distro, name, isa, version) = + if os == "linux" then + [ std.join(" ", [ "./ci/scripts/build.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ]) ] + else + if os == "windows" then + [ "windows/build.ps1", "windows/package.ps1" ] + else + if os == "darwin" then + [ "whoami" ] +; + +local test_commands(os, distro, name, isa, version) = + if os == "linux" then + [ std.join(" ", [ "./ci/scripts/test.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ]) ] + else + if os == "windows" then + [ "windows/testpackage.ps1 " + version ] +; + +// +// render +// + +local Build(os, distro, name, isa, events) = { + "kind": "pipeline", + "type": pipeline_type(os), + "name": std.join(" ", [ name, isa, "build" ]), + "pull": "always", + "clone": { "depth": 1, [ if os == "darwin" then "disable" ]: true }, + "steps": [ + { + "name": "build", + "image": builder_image(os), + "commands": build_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"), + "when": { "event": [ "push" ]}, + }, + { + "name": "release", + "image": builder_image(os), + "commands": build_commands(os, distro, name, isa, "${DRONE_TAG}"), + "when": { "event": [ "tag" ]}, + }, + { + "name": "copy build", + "image": builder_image(os), + "commands": copy_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"), + "volumes": build_step_volumes(os), + "when": { "event": [ "push" ]}, + }, + { + "name": "copy relase", + "image": builder_image(os), + "commands": copy_commands(os, distro, name, isa, "${DRONE_TAG}"), + "volumes": release_step_volumes(os), + "when": { "event": [ "tag" ]}, + }, + ], + "volumes": host_volumes(os), + "platform": { "os": os, [ if isa == "arm64" || isa == "armv7" then "arch" ]: "arm64" }, + "trigger": { "event": events } +}; + +local Test(os, distro, name, isa, events) = { + "kind": "pipeline", + "type": pipeline_type(os), + "name": std.join(" ", [ name, isa, "test"]), + "pull": "always", + "clone": { "depth": 1 }, + "steps": [ + { + "name": "test build", + "image": tester_image(os), + "volumes": build_step_volumes(os), + "commands": test_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"), + "when": { "event": [ "push" ]}, + }, + { + "name": "test release", + "image": tester_image(os), + "volumes": release_step_volumes(os), + "commands": test_commands(os, distro, name, isa, "${DRONE_TAG}"), + "when": { "event": [ "tag" ]}, + }, + ], + "volumes": host_volumes(os), + "platform": { "os": os, [ if isa == "arm64" || isa == "armv7" then "arch" ]: "arm64" }, + "depends_on": [ std.join(" ", [ name, "index" ]) ], + "trigger": { "event": events } +}; + +local Index(p) = { + "kind": "pipeline", + "type": pipeline_type(p.os), + "name": std.join(" ", [ p.name, "index" ]), + "pull": "always", + "clone": { "depth": 1 }, + "steps": [ + { + "name": "index build", + "image": index_image(p.distro), + "commands": index_commands(p.os, "zerotier-builds", p.distro, p.name, p.isas), + "volumes": build_step_volumes(p.os), + "environment":{ "GPG_PRIVATE_KEY": { from_secret: "gpg-private-key" }}, + "when": { "event": [ "push" ]}, + }, + { + "name": "index release", + "image": index_image(p.distro), + "commands": index_commands(p.os, "zerotier-releases", p.distro, p.name, p.isas), + "volumes": release_step_volumes(p.os), + "environment":{ "GPG_PRIVATE_KEY": { from_secret: "gpg-private-key" }}, + "when": { "event": [ "tag" ]}, + }, + ], + "volumes": host_volumes(p.os), + "platform": { "os": p.os }, + depends_on: std.flattenArrays([ [ std.join(" ", [ p.name, isa, "build" ]) ] for isa in p.isas ]), + "trigger": { "event": p.events } +}; + +// +// print +// + +std.flattenArrays([ + [ + Build(p.os, p.distro, p.name, isa, p.events) + for isa in p.isas + ] + + [ + Index(p) + ] + for p in native_targets + ]) + + std.flattenArrays([ + [ + Test(p.os, p.distro, p.name, isa, p.events) + for isa in p.isas + ] + for p in native_targets + ]) + \ No newline at end of file diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..b837b1b --- /dev/null +++ b/.drone.yml @@ -0,0 +1,465 @@ +--- +clone: + depth: 1 +kind: pipeline +name: bullseye 386 build +platform: + os: linux +pull: always +steps: +- commands: + - ./ci/scripts/build.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: build + when: + event: + - push +- commands: + - ./ci/scripts/build.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: release + when: + event: + - tag +- commands: + - ./ci/scripts/publish.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: copy build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - ./ci/scripts/publish.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: copy relase + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +clone: + depth: 1 +kind: pipeline +name: bullseye armv7 build +platform: + arch: arm64 + os: linux +pull: always +steps: +- commands: + - ./ci/scripts/build.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: build + when: + event: + - push +- commands: + - ./ci/scripts/build.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: release + when: + event: + - tag +- commands: + - ./ci/scripts/publish.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} + ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: copy build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - ./ci/scripts/publish.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: copy relase + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +clone: + depth: 1 +kind: pipeline +name: bullseye amd64 build +platform: + os: linux +pull: always +steps: +- commands: + - ./ci/scripts/build.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: build + when: + event: + - push +- commands: + - ./ci/scripts/build.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: release + when: + event: + - tag +- commands: + - ./ci/scripts/publish.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} + ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: copy build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - ./ci/scripts/publish.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: copy relase + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +clone: + depth: 1 +kind: pipeline +name: bullseye arm64 build +platform: + arch: arm64 + os: linux +pull: always +steps: +- commands: + - ./ci/scripts/build.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: build + when: + event: + - push +- commands: + - ./ci/scripts/build.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: release + when: + event: + - tag +- commands: + - ./ci/scripts/publish.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} + ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: copy build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - ./ci/scripts/publish.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: copy relase + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +clone: + depth: 1 +depends_on: +- bullseye 386 build +- bullseye armv7 build +- bullseye amd64 build +- bullseye arm64 build +kind: pipeline +name: bullseye index +platform: + os: linux +pull: always +steps: +- commands: + - /usr/local/bin/index zerotier-builds debian bullseye 386 armv7 amd64 arm64 + environment: + GPG_PRIVATE_KEY: + from_secret: gpg-private-key + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/apt-builder + name: index build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - /usr/local/bin/index zerotier-releases debian bullseye 386 armv7 amd64 arm64 + environment: + GPG_PRIVATE_KEY: + from_secret: gpg-private-key + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/apt-builder + name: index release + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +clone: + depth: 1 +depends_on: +- bullseye index +kind: pipeline +name: bullseye 386 test +platform: + os: linux +pull: always +steps: +- commands: + - ./ci/scripts/test.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: test build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - ./ci/scripts/test.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: test release + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +clone: + depth: 1 +depends_on: +- bullseye index +kind: pipeline +name: bullseye armv7 test +platform: + arch: arm64 + os: linux +pull: always +steps: +- commands: + - ./ci/scripts/test.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: test build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - ./ci/scripts/test.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: test release + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +clone: + depth: 1 +depends_on: +- bullseye index +kind: pipeline +name: bullseye amd64 test +platform: + os: linux +pull: always +steps: +- commands: + - ./ci/scripts/test.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: test build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - ./ci/scripts/test.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: test release + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +clone: + depth: 1 +depends_on: +- bullseye index +kind: pipeline +name: bullseye arm64 test +platform: + arch: arm64 + os: linux +pull: always +steps: +- commands: + - ./ci/scripts/test.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: test build + volumes: + - name: zerotier-builds + path: /zerotier-builds + when: + event: + - push +- commands: + - ./ci/scripts/test.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} + image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder + name: test release + volumes: + - name: zerotier-releases + path: /zerotier-releases + when: + event: + - tag +trigger: + event: + - push + - tag + - custom +type: docker +volumes: +- host: + path: /zerotier-builds + name: zerotier-builds +- host: + path: /zerotier-releases + name: zerotier-releases +--- +kind: signature +hmac: 887a3ef78d3fe8f0149911e1e4876401dd7dd313b36eb893e791fa42f45d7768 + +... diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dbe5330 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +ext/bin/tap-windows-ndis6/x64/zttap300.inf eol=crlf +ext/bin/tap-windows-ndis6/x64.old/zttap300.inf eol=crlf +ext/bin/tap-windows-ndis6/x86/zttap300.inf eol=crlf +windows/TapDriver6/zttap300.inf eol=crlf diff --git a/.github/ISSUE_TEMPLATE/bugs-and-issues.md b/.github/ISSUE_TEMPLATE/bugs-and-issues.md new file mode 100644 index 0000000..92e6978 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bugs-and-issues.md @@ -0,0 +1,31 @@ +--- +name: Bugs and Issues +about: Create a report to help us improve +title: '' +labels: NEEDS TRIAGE +assignees: '' + +--- + +# Before filing a Bug Report + +_Using these will ensure you get quicker support, and make this space available for code-related issues. Thank you!_ + +- [Docs Site](https://docs.zerotier.com/zerotier/troubleshooting) => Troubleshooting, quickstarts, and more advanced topics. +- [Discuss Forum](https://discuss.zerotier.com/) => Our discussion forum for users and support to mutually resolve issues & suggest ideas. +- [Reddit](https://www.reddit.com/r/zerotier/) => Our subreddit, which we monitor regularly and is fairly active. +- [Knowledge Base](https://zerotier.atlassian.net/wiki/spaces/SD/overview) => Older wiki. + +If you are having a connection issue, it's much easier to diagnose through the discussion forum or the ticket system. + + +# If you still want to file a Bug Report + +## Please let us know + +- What you expect to be happening. +- What is actually happening? +- Any steps to reproduce the error. +- Any relevant console output or screenshots. +- What operating system and ZeroTier version. Please try the latest ZeroTier release. + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..5a1e094 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,13 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[Feature Request] " +labels: suggestion +assignees: '' + +--- + +If there is something you'd like to have added to ZeroTier, to go to https://discuss.zerotier.com/c/feature-requests/ instead. Issues there can be voted on and discussed in-depth. + + +Thank you! diff --git a/.github/ISSUE_TEMPLATE/game-connection-issue.md b/.github/ISSUE_TEMPLATE/game-connection-issue.md new file mode 100644 index 0000000..d7b3a9b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/game-connection-issue.md @@ -0,0 +1,15 @@ +--- +name: Game Connection Issue +about: Game issues are better served by forum posts +title: Please go to our Discuss or Reddit for game-related issues. Thanks! +labels: wontfix +assignees: '' + +--- + +Are you having trouble connecting to a game on your virtual network after installing ZeroTier? + +- [ ] Yes +- [ ] No + +If you answered yes, then it is very likely that your question would be better answered on our [Community Forums](https://discuss.zerotier.com) or [Reddit](https://www.reddit.com/r/zerotier/) community; we monitor both regularly. We also have extensive documentation on our [Knowledge Base](https://zerotier.atlassian.net/wiki/spaces/SD/overview). Thank you! diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..b9e1f49 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,123 @@ +on: [ push ] + +jobs: + build_ubuntu: + runs-on: ubuntu-latest + steps: + - name: gitconfig + run: | + git config --global core.autocrlf input + # git config --global core.eol lf + - name: checkout + uses: actions/checkout@v4 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + targets: x86_64-unknown-linux-gnu + components: rustfmt, clippy + + - name: Set up cargo cache + uses: Swatinem/rust-cache@v2 + continue-on-error: false + with: + key: ${{ runner.os }}-cargo-${{ hashFiles('rustybits//Cargo.lock') }} + shared-key: ${{ runner.os }}-cargo- + workspaces: | + rustybits/ + + - name: make + run: make + - name: selftest + run: | + make selftest + ./zerotier-selftest + - name: 'Tar files' # keeps permissions (execute) + run: tar -cvf zerotier-one.tar zerotier-one + - name: Archive production artifacts + uses: actions/upload-artifact@v4 + with: + name: zerotier-one-ubuntu-x64 + path: zerotier-one.tar + retention-days: 7 + + build_macos: + runs-on: macos-latest + steps: + - name: gitconfig + run: | + git config --global core.autocrlf input + # git config --global core.eol lf + - name: checkout + uses: actions/checkout@v4 + - name: Install Rust aarch64 + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + target: aarch64-apple-darwin + components: rustfmt, clippy + - name: Install Rust x86_64 + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + target: x86_64-apple-darwin + components: rustfmt, clippy + - name: Set up cargo cache + uses: Swatinem/rust-cache@v2 + continue-on-error: false + with: + key: ${{ runner.os }}-cargo-${{ hashFiles('rustybits//Cargo.lock') }} + shared-key: ${{ runner.os }}-cargo- + workspaces: | + rustybits/ + - name: make + run: make + - name: selftest + run: | + make selftest + ./zerotier-selftest + - name: 'Tar files' # keeps permissions (execute) + run: tar -cvf zerotier-one.tar zerotier-one + - name: Archive production artifacts + uses: actions/upload-artifact@v4 + with: + name: zerotier-one-mac + path: zerotier-one.tar + retention-days: 7 + + + build_windows: + runs-on: windows-latest + steps: + - name: gitconfig + run: | + git config --global core.autocrlf true + # git config --global core.eol lf + - name: checkout + uses: actions/checkout@v4 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + target: aarch64-apple-darwin + components: rustfmt, clippy + - name: Set up cargo cache + uses: Swatinem/rust-cache@v2 + continue-on-error: false + with: + key: ${{ runner.os }}-cargo-${{ hashFiles('rustybits//Cargo.lock') }} + shared-key: ${{ runner.os }}-cargo- + workspaces: | + rustybits/ + + - name: setup msbuild + uses: microsoft/setup-msbuild@v2 + - name: msbuild + run: | + msbuild windows\ZeroTierOne.sln /m /p:Configuration=Release /property:Platform=x64 /t:ZeroTierOne + - name: Archive production artifacts + uses: actions/upload-artifact@v4 + with: + name: zerotier-one-windows + path: windows/Build + retention-days: 7 diff --git a/.github/workflows/validate-linux.sh b/.github/workflows/validate-linux.sh new file mode 100755 index 0000000..a661f6f --- /dev/null +++ b/.github/workflows/validate-linux.sh @@ -0,0 +1,497 @@ +#!/bin/bash + +# This test script joins Earth and pokes some stuff + +TEST_NETWORK=8056c2e21c000001 +RUN_LENGTH=30 +TEST_FINISHED=false +ZTO_VER=$(git describe --tags $(git rev-list --tags --max-count=1)) +ZTO_COMMIT=$(git rev-parse HEAD) +ZTO_COMMIT_SHORT=$(git rev-parse --short HEAD) +TEST_DIR_PREFIX="$ZTO_VER-$ZTO_COMMIT_SHORT-test-results" + +TEST_OK=0 +TEST_FAIL=1 + +echo "Performing test on: $ZTO_VER-$ZTO_COMMIT_SHORT" +TEST_FILEPATH_PREFIX="$TEST_DIR_PREFIX/$ZTO_COMMIT_SHORT" +mkdir $TEST_DIR_PREFIX + +# How long we will wait for ZT to come online before considering it a failure +MAX_WAIT_SECS=30 + +ZT_PORT_NODE_1=9996 +ZT_PORT_NODE_2=9997 + +################################################################################ +# Multi-node connectivity and performance test # +################################################################################ + +test() { + + echo -e "\nPerforming pre-flight checks" + + check_exit_on_invalid_identity + + echo -e "\nRunning test for $RUN_LENGTH seconds" + + export NS1="ip netns exec ns1" + export NS2="ip netns exec ns2" + + export ZT1="$NS1 ./zerotier-cli -p9996 -D$(pwd)/node1" + # Specify custom port on one node to ensure that feature works + export ZT2="$NS2 ./zerotier-cli -p9997 -D$(pwd)/node2" + + echo -e "\nSetting up network namespaces..." + echo "Setting up ns1" + + ip netns add ns1 + $NS1 ip link set dev lo up + ip link add veth0 type veth peer name veth1 + ip link set veth1 netns ns1 + ip addr add 192.168.0.1/24 dev veth0 + ip link set dev veth0 up + + $NS1 ip addr add 192.168.0.2/24 dev veth1 + $NS1 ip link set dev veth1 up + + # Add default route + $NS1 ip route add default via 192.168.0.1 + + iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.255.0 \ + -o eth0 -j MASQUERADE + iptables -A FORWARD -i eth0 -o veth0 -j ACCEPT + iptables -A FORWARD -o eth0 -i veth0 -j ACCEPT + + echo "Setting up ns2" + ip netns add ns2 + $NS2 ip link set dev lo up + ip link add veth2 type veth peer name veth3 + ip link set veth3 netns ns2 + ip addr add 192.168.1.1/24 dev veth2 + ip link set dev veth2 up + + $NS2 ip addr add 192.168.1.2/24 dev veth3 + $NS2 ip link set dev veth3 up + $NS2 ip route add default via 192.168.1.1 + + iptables -t nat -A POSTROUTING -s 192.168.1.0/255.255.255.0 \ + -o eth0 -j MASQUERADE + iptables -A FORWARD -i eth0 -o veth2 -j ACCEPT + iptables -A FORWARD -o eth0 -i veth2 -j ACCEPT + + # Allow forwarding + sysctl -w net.ipv4.ip_forward=1 + + ################################################################################ + # Memory Leak Check # + ################################################################################ + + export FILENAME_MEMORY_LOG="$TEST_FILEPATH_PREFIX-memory.log" + + echo -e "\nStarting a ZeroTier instance in each namespace..." + + export time_test_start=$(date +%s) + + # Spam the CLI as ZeroTier is starting + spam_cli 100 + + echo "Starting memory leak check" + $NS1 sudo valgrind --demangle=yes --exit-on-first-error=yes \ + --error-exitcode=1 \ + --xml=yes \ + --xml-file=$FILENAME_MEMORY_LOG \ + --leak-check=full \ + ./zerotier-one node1 -p$ZT_PORT_NODE_1 -U >>node_1.log 2>&1 & + + # Second instance, not run in memory profiler + # Don't set up internet access until _after_ zerotier is running + # This has been a source of stuckness in the past. + $NS2 ip addr del 192.168.1.2/24 dev veth3 + $NS2 sudo ./zerotier-one node2 -U -p$ZT_PORT_NODE_2 >>node_2.log 2>&1 & + + sleep 10; # New HTTP control plane is a bit sluggish, so we delay here + + check_bind_to_correct_ports $ZT_PORT_NODE_1 + check_bind_to_correct_ports $ZT_PORT_NODE_2 + + $NS2 ip addr add 192.168.1.2/24 dev veth3 + $NS2 ip route add default via 192.168.1.1 + + echo -e "\nPing from host to namespaces" + + ping -c 3 192.168.0.1 + ping -c 3 192.168.1.1 + + echo -e "\nPing from namespace to host" + + $NS1 ping -c 3 192.168.0.1 + $NS1 ping -c 3 192.168.0.1 + $NS2 ping -c 3 192.168.0.2 + $NS2 ping -c 3 192.168.0.2 + + echo -e "\nPing from ns1 to ns2" + + $NS1 ping -c 3 192.168.0.1 + + echo -e "\nPing from ns2 to ns1" + + $NS2 ping -c 3 192.168.0.1 + + ################################################################################ + # Online Check # + ################################################################################ + + echo "Waiting for ZeroTier to come online before attempting test..." + node1_online=false + node2_online=false + both_instances_online=false + time_zt_node1_start=$(date +%s) + time_zt_node2_start=$(date +%s) + + for ((s = 0; s <= $MAX_WAIT_SECS; s++)); do + node1_online="$($ZT1 -j info | jq '.online' 2>/dev/null)" + node2_online="$($ZT2 -j info | jq '.online' 2>/dev/null)" + echo "Checking for online status: try #$s, node1:$node1_online, node2:$node2_online" + if [[ "$node2_online" == "true" && "$node1_online" == "true" ]]; then + export both_instances_online=true + export time_to_both_nodes_online=$(date +%s) + break + fi + sleep 1 + done + + echo -e "\n\nContents of ZeroTier home paths:" + + ls -lga node1 + tree node1 + ls -lga node2 + tree node2 + + echo -e "\n\nRunning ZeroTier processes:" + echo -e "\nNode 1:\n" + $NS1 ps aux | grep zerotier-one + echo -e "\nNode 2:\n" + $NS2 ps aux | grep zerotier-one + + echo -e "\n\nStatus of each instance:" + + echo -e "\n\nNode 1:\n" + $ZT1 status + echo -e "\n\nNode 2:\n" + $ZT2 status + + if [[ "$both_instances_online" != "true" ]]; then + exit_test_and_generate_report $TEST_FAIL "one or more nodes failed to come online" + fi + + echo -e "\nJoining networks" + + $ZT1 join $TEST_NETWORK + $ZT2 join $TEST_NETWORK + + sleep 10 + + node1_ip4=$($ZT1 get $TEST_NETWORK ip4) + node2_ip4=$($ZT2 get $TEST_NETWORK ip4) + + echo "node1_ip4=$node1_ip4" + echo "node2_ip4=$node2_ip4" + + echo -e "\nPinging each node" + + PING12_FILENAME="$TEST_FILEPATH_PREFIX-ping-1-to-2.txt" + PING21_FILENAME="$TEST_FILEPATH_PREFIX-ping-2-to-1.txt" + + $NS1 ping -c 16 $node2_ip4 >$PING12_FILENAME + $NS2 ping -c 16 $node1_ip4 >$PING21_FILENAME + + ping_loss_percent_1_to_2=$(cat $PING12_FILENAME | + grep "packet loss" | awk '{print $6}' | sed 's/%//') + ping_loss_percent_2_to_1=$(cat $PING21_FILENAME | + grep "packet loss" | awk '{print $6}' | sed 's/%//') + + # Normalize loss value + export ping_loss_percent_1_to_2=$(echo "scale=2; $ping_loss_percent_1_to_2/100.0" | bc) + export ping_loss_percent_2_to_1=$(echo "scale=2; $ping_loss_percent_2_to_1/100.0" | bc) + + ################################################################################ + # CLI Check # + ################################################################################ + + echo "Testing basic CLI functionality..." + + spam_cli 10 + + $ZT1 join $TEST_NETWORK + + $ZT1 -h + $ZT1 -v + $ZT1 status + $ZT1 info + $ZT1 listnetworks + $ZT1 peers + $ZT1 listpeers + + $ZT1 -j status + $ZT1 -j info + $ZT1 -j listnetworks + $ZT1 -j peers + $ZT1 -j listpeers + + $ZT1 dump + + $ZT1 get $TEST_NETWORK allowDNS + $ZT1 get $TEST_NETWORK allowDefault + $ZT1 get $TEST_NETWORK allowGlobal + $ZT1 get $TEST_NETWORK allowManaged + $ZT1 get $TEST_NETWORK bridge + $ZT1 get $TEST_NETWORK broadcastEnabled + $ZT1 get $TEST_NETWORK dhcp + $ZT1 get $TEST_NETWORK id + $ZT1 get $TEST_NETWORK mac + $ZT1 get $TEST_NETWORK mtu + $ZT1 get $TEST_NETWORK name + $ZT1 get $TEST_NETWORK netconfRevision + $ZT1 get $TEST_NETWORK nwid + $ZT1 get $TEST_NETWORK portDeviceName + $ZT1 get $TEST_NETWORK portError + $ZT1 get $TEST_NETWORK status + $ZT1 get $TEST_NETWORK type + + # Test an invalid command + $ZT1 get $TEST_NETWORK derpderp + + # TODO: Validate JSON + + # Performance Test + + export FILENAME_PERF_JSON="$TEST_FILEPATH_PREFIX-iperf.json" + + echo -e "\nBeginning performance test:" + + echo -e "\nStarting server:" + + echo "$NS1 iperf3 -s &" + sleep 1 + + echo -e "\nStarting client:" + sleep 1 + + echo "$NS2 iperf3 --json -c $node1_ip4 > $FILENAME_PERF_JSON" + + cat $FILENAME_PERF_JSON + + # Let ZeroTier idle long enough for various timers + + echo -e "\nIdling ZeroTier for $RUN_LENGTH seconds..." + sleep $RUN_LENGTH + + echo -e "\nLeaving networks" + + $ZT1 leave $TEST_NETWORK + $ZT2 leave $TEST_NETWORK + + sleep 5 + + exit_test_and_generate_report $TEST_OK "completed test" +} + +################################################################################ +# Generate report # +################################################################################ + +exit_test_and_generate_report() { + + echo -e "\nStopping memory check..." + sudo pkill -15 -f valgrind + sleep 10 + + time_test_end=$(date +%s) + + echo "Exiting test with reason: $2 ($1)" + + # Collect ZeroTier dump files + + echo -e "\nCollecting ZeroTier dump files" + + node1_id=$($ZT1 -j status | jq -r .address) + node2_id=$($ZT2 -j status | jq -r .address) + + $ZT1 dump + mv zerotier_dump.txt "$TEST_FILEPATH_PREFIX-node-dump-$node1_id.txt" + + $ZT2 dump + mv zerotier_dump.txt "$TEST_FILEPATH_PREFIX-node-dump-$node2_id.txt" + + # Copy ZeroTier stdout/stderr logs + + cp node_1.log "$TEST_FILEPATH_PREFIX-node-log-$node1_id.txt" + cp node_2.log "$TEST_FILEPATH_PREFIX-node-log-$node2_id.txt" + + # Generate report + + cat $FILENAME_MEMORY_LOG + + DEFINITELY_LOST=$(xmlstarlet sel -t -v '/valgrindoutput/error/xwhat' \ + $FILENAME_MEMORY_LOG | grep "definitely" | awk '{print $1;}') + POSSIBLY_LOST=$(xmlstarlet sel -t -v '/valgrindoutput/error/xwhat' \ + $FILENAME_MEMORY_LOG | grep "possibly" | awk '{print $1;}') + + # Generate coverage report artifact and summary + + FILENAME_COVERAGE_JSON="$TEST_FILEPATH_PREFIX-coverage.json" + FILENAME_COVERAGE_HTML="$TEST_FILEPATH_PREFIX-coverage.html" + + echo -e "\nGenerating coverage test report..." + + gcovr -r . --exclude ext --json-summary $FILENAME_COVERAGE_JSON \ + --html >$FILENAME_COVERAGE_HTML + + cat $FILENAME_COVERAGE_JSON + + COVERAGE_LINE_COVERED=$(cat $FILENAME_COVERAGE_JSON | jq .line_covered) + COVERAGE_LINE_TOTAL=$(cat $FILENAME_COVERAGE_JSON | jq .line_total) + COVERAGE_LINE_PERCENT=$(cat $FILENAME_COVERAGE_JSON | jq .line_percent) + + COVERAGE_LINE_COVERED="${COVERAGE_LINE_COVERED:-0}" + COVERAGE_LINE_TOTAL="${COVERAGE_LINE_TOTAL:-0}" + COVERAGE_LINE_PERCENT="${COVERAGE_LINE_PERCENT:-0}" + + # Default values + + DEFINITELY_LOST="${DEFINITELY_LOST:-0}" + POSSIBLY_LOST="${POSSIBLY_LOST:-0}" + ping_loss_percent_1_to_2="${ping_loss_percent_1_to_2:-100.0}" + ping_loss_percent_2_to_1="${ping_loss_percent_2_to_1:-100.0}" + time_to_both_nodes_online="${time_to_both_nodes_online:--1}" + + # Summarize and emit json for trend reporting + + FILENAME_SUMMARY="$TEST_FILEPATH_PREFIX-summary.json" + + time_length_test=$((time_test_end - time_test_start)) + if [[ $time_to_both_nodes_online != -1 ]]; + then + time_to_both_nodes_online=$((time_to_both_nodes_online - time_test_start)) + fi + #time_length_zt_join=$((time_zt_join_end-time_zt_join_start)) + #time_length_zt_leave=$((time_zt_leave_end-time_zt_leave_start)) + #time_length_zt_can_still_ping=$((time_zt_can_still_ping-time_zt_leave_start)) + + summary=$( + cat <$FILENAME_SUMMARY + cat $FILENAME_SUMMARY + + exit 0 +} + +################################################################################ +# CLI Check # +################################################################################ + +spam_cli() { + echo "Spamming CLI..." + # Rapidly spam the CLI with joins/leaves + + MAX_TRIES="${1:-10}" + + for ((s = 0; s <= MAX_TRIES; s++)); do + $ZT1 status + $ZT2 status + sleep 0.1 + done + + SPAM_TRIES=128 + + for ((s = 0; s <= SPAM_TRIES; s++)); do + $ZT1 join $TEST_NETWORK + done + + for ((s = 0; s <= SPAM_TRIES; s++)); do + $ZT1 leave $TEST_NETWORK + done + + for ((s = 0; s <= SPAM_TRIES; s++)); do + $ZT1 leave $TEST_NETWORK + $ZT1 join $TEST_NETWORK + done +} + +################################################################################ +# Check for proper exit on load of invalid identity # +################################################################################ + +check_exit_on_invalid_identity() { + echo "Checking ZeroTier exits on invalid identity..." + mkdir -p $(pwd)/exit_test + ZT1="sudo ./zerotier-one -p9999 $(pwd)/exit_test" + echo "asdfasdfasdfasdf" > $(pwd)/exit_test/identity.secret + echo "asdfasdfasdfasdf" > $(pwd)/exit_test/authtoken.secret + + echo "Launch ZeroTier with an invalid identity" + $ZT1 & + my_pid=$! + + echo "Waiting 5 seconds" + sleep 5 + + # check if process is running + kill -0 $my_pid + if [ $? -eq 0 ]; then + exit_test_and_generate_report $TEST_FAIL "Exit test FAILED: Process still running after being fed an invalid identity" + fi +} + +################################################################################ +# Check that we're binding to the primary port for TCP/TCP6/UDP # +################################################################################ + +check_bind_to_correct_ports() { + PORT_NUMBER=$1 + echo "Checking bound ports:" + sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" + if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "tcp") ]]; + then + : + else + exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to tcp/$1" + fi + if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "tcp6") ]]; + then + : + else + exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to tcp6/$1" + fi + if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "udp") ]]; + then + : + else + exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to udp/$1" + fi +} + +test "$@" diff --git a/.github/workflows/validate-report.sh b/.github/workflows/validate-report.sh new file mode 100755 index 0000000..3ae4e1a --- /dev/null +++ b/.github/workflows/validate-report.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +################################################################################ +# Set exit code depending on tool reports # +################################################################################ + +DEFINITELY_LOST=$(cat *test-results/*summary.json | jq .num_definite_bytes_lost) +EXIT_CODE=$(cat *test-results/*summary.json | jq .exit_code) +EXIT_REASON=$(cat *test-results/*summary.json | jq .exit_reason) + +cat *test-results/*summary.json + +echo -e "\nBytes of memory definitely lost: $DEFINITELY_LOST" + +if [[ "$DEFINITELY_LOST" -gt 0 ]]; then + exit 1 +fi + +# Catch-all for other non-zero exit codes + +if [[ "$EXIT_CODE" -gt 0 ]]; then + echo "Test failed: $EXIT_REASON" + exit 1 +fi \ No newline at end of file diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..bb362fb --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,56 @@ +on: + push: + workflow_dispatch: + +jobs: + build_ubuntu: + runs-on: ubuntu-latest + steps: + - name: gitconfig + run: | + git config --global core.autocrlf input + + - name: checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: x86_64-unknown-linux-gnu + override: true + components: rustfmt, clippy + + - name: Set up cargo cache + uses: Swatinem/rust-cache@v2 + continue-on-error: false + with: + key: ${{ runner.os }}-cargo-${{ hashFiles('zeroidc//Cargo.lock') }} + shared-key: ${{ runner.os }}-cargo- + workspaces: | + zeroidc/ + + - name: validate-1m-linux + env: + CC: 'gcc' + CXX: 'g++' + BRANCH: ${{ github.ref_name }} + run: | + sudo apt install -y valgrind xmlstarlet gcovr iperf3 tree + make one ZT_COVERAGE=1 ZT_TRACE=1 + sudo chmod +x ./.github/workflows/validate-linux.sh + sudo ./.github/workflows/validate-linux.sh + + - name: Archive test results + uses: actions/upload-artifact@v3 + with: + name: ${{github.sha}}-test-results + path: "*test-results*" + + - name: final-report + run: | + sudo chmod +x ./.github/workflows/validate-report.sh + sudo ./.github/workflows/validate-report.sh + diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..79a9e24 --- /dev/null +++ b/.gitignore @@ -0,0 +1,140 @@ +# Main binaries created in *nix builds +/zerotier-one +/zerotier-idtool +/zerotier-cli +/zerotier-selftest +/zerotier +/nltest + +# IDE stuff +/.idea +/.nova +/compile_commands.json + +# OS-created garbage files from various platforms +.DS_Store +.Apple* +Thumbs.db +@eaDir +._* + +# Windows build droppings +/windows/ZeroTierOne.sdf +/windows/ZeroTierOne.v11.suo +/windows/x64 +/windows/Win32 +/windows/*/x64 +/windows/*/Win32 +/windows/ZeroTierOne/Release +/windows/ZeroTierOneService/obj +/windows/ZeroTierOneService/bin +/windows/Build +/windows/Debug +/windows/Release +/windows/WebUIWrapper/bin +/windows/WebUIWrapper/obj +/windows/lib +/ext/installfiles/windows/ZeroTier One-SetupFiles +/ext/installfiles/windows/*-cache +/ZeroTier One.msi +*.vcxproj.backup +/windows/TapDriver6/Win7Debug +/windows/TapDriver6/win7Release +/windows/*.db +/windows/*.opendb +enc_temp_folder +/windows/copyutil/bin +/windows/copyutil/obj +.vs/ + +# *nix/Mac build droppings +/build-* +/ZeroTierOneInstaller-* +/examples/docker/zerotier-one +/examples/docker/test-*.env +/world/mkworld +/world/*.c25519 +zt1-src.tar.gz +/MacEthernetTapAgent + +# Miscellaneous temporaries, build files, etc. +*.log +*.opensdf +*.user +*.cache +*.tlog +*.pid +*.pkg +*.o +/*.a +*.dylib +*.so +*.so.* +*.o-* +*.core +*.deb +*.rpm +*.autosave +*.tmp +.depend +node_modules +zt1_update_* +debian/files +debian/zerotier-one +debian/zerotier-one*.debhelper +debian/*.log +debian/zerotier-one.substvars +root-watcher/config.json + +# Java/Android/JNI build droppings +java/obj/ +java/libs/ +java/bin/ +java/classes/ +java/doc/ +java/build_win64/ +java/build_win32/ +/java/mac32_64/ +windows/WinUI/obj/ +windows/WinUI/bin/ +windows/ZeroTierOne/Debug/ +/ext/installfiles/windows/chocolatey/zerotier-one/*.nupkg + +# Miscellaneous mac/Xcode droppings +.DS_Store +.Trashes +*.swp +*~.nib +DerivedData/ +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 +*.xccheckout +xcuserdata/ +.vscode +__pycache__ +*~ +attic/world/*.c25519 +attic/world/mkworld +workspace/ +workspace2/ +zeroidc/target/ + +#snapcraft specifics +/parts/ +/stage/ +/prime/ + +*.snap + +.snapcraft +__pycache__ +*.pyc +*_source.tar.bz2 +snap/.snapcraft +tcp-proxy/tcp-proxy diff --git a/.kick b/.kick new file mode 100644 index 0000000..28b8ee7 --- /dev/null +++ b/.kick @@ -0,0 +1,14 @@ +kick +kick +kick +kick +kick +kick +kick +kick +kick +kick +kick +kick +kick +kick diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 0000000..84bb863 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1,75 @@ +# Authors and Third Party Code Licensing Information + +## Primary Authors + + * ZeroTier Core and ZeroTier One virtual networking service
+ Adam Ierymenko / adam.ierymenko@zerotier.com + Joseph Henry / joseph.henry@zerotier.com (QoS and multipath) + + * Java JNI Interface to enable Android application development, and Android app itself (code for that is elsewhere)
+ Grant Limberg / glimberg@gmail.com + + * ZeroTier SDK (formerly known as Network Containers)
+ Joseph Henry / joseph.henry@zerotier.com + +## Third Party Contributors + + * A number of fixes and improvements to the new controller, other stuff.
+ Kees Bos / https://github.com/keesbos/ + + * Debugging and testing, OpenWRT support fixes.
+ Moritz Warning / moritzwarning@web.de + + * Debian GNU/Linux packaging, manual pages, and license compliance edits.
+ Ben Finney + + * Several others made smaller contributions, which GitHub tracks here:
+ https://github.com/zerotier/ZeroTierOne/graphs/contributors/ + +## Third-Party Code + +ZeroTier includes the following third party code, either in ext/ or incorporated into the ZeroTier core. This third party code remains licensed under its original license and is not subject to ZeroTier's BSL license. + + * LZ4 compression algorithm by Yann Collet + + * Files: node/Packet.cpp (bundled within anonymous namespace) + * Home page: http://code.google.com/p/lz4/ + * License grant: BSD 2-clause + + * http-parser by Joyent, Inc. (many authors) + + * Files: ext/http-parser/* + * Home page: https://github.com/joyent/http-parser/ + * License grant: MIT/Expat + + * C++11 json (nlohmann/json) by Niels Lohmann + + * Files: ext/json/* + * Home page: https://github.com/nlohmann/json + * License grant: MIT + + * tap-windows6 by the OpenVPN project + + * Files: windows/TapDriver6/* + * Home page: https://github.com/OpenVPN/tap-windows6/ + * License grant: GNU GPL v2 + * ZeroTier Modifications: change name of driver to ZeroTier, add ioctl() to get L2 multicast memberships (source is in ext/ and modifications inherit GPL) + + * Salsa20 stream cipher, Curve25519 elliptic curve cipher, Ed25519 digital signature algorithm, and Poly1305 MAC algorithm, all by Daniel J. Bernstein + + * Files: node/Salsa20.* node/C25519.* node/Poly1305.* + * Home page: http://cr.yp.to/ + * License grant: public domain + * ZeroTier Modifications: slight cryptographically-irrelevant modifications for inclusion into ZeroTier core + + * MiniUPNPC and libnatpmp by Thomas Bernard + + * Files: ext/libnatpmp/* ext/miniupnpc/* + * Home page: http://miniupnp.free.fr/ + * License grant: BSD attribution no-endorsement + + * cpp-httplib by yhirose + + * Files: ext/cpp-httplib/* + * Home page: https://github.com/yhirose/cpp-httplib + * License grant: MIT diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..fff7808 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +# CMake build script for libzerotiercore.a + +cmake_minimum_required (VERSION 2.8) +project (zerotiercore) + +set (PROJ_DIR ${PROJECT_SOURCE_DIR}) +set (ZT_DEFS -std=c++11) + +file(GLOB core_src_glob ${PROJ_DIR}/node/*.cpp) +add_library(zerotiercore STATIC ${core_src_glob}) + +target_compile_options(zerotiercore PRIVATE ${ZT_DEFS}) diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d07f352 --- /dev/null +++ b/COPYING @@ -0,0 +1,12 @@ +ZeroTier One, an endpoint server for the ZeroTier virtual network layer. +Copyright © 2011–2019 ZeroTier, Inc. + +ZeroTier is released under the terms of the BSL version 1.1. See the +file LICENSE.txt for details. + +.. + Local variables: + coding: utf-8 + mode: text + End: + vim: fileencoding=utf-8 filetype=text : diff --git a/Dockerfile.ci b/Dockerfile.ci new file mode 100644 index 0000000..9ff3b01 --- /dev/null +++ b/Dockerfile.ci @@ -0,0 +1,28 @@ +# vim: ft=dockerfile + +FROM ubuntu:21.04 as stage + +RUN apt-get update -qq && apt-get -qq install make clang +COPY . . +RUN /usr/bin/make +RUN echo $PWD +RUN cp zerotier-one /usr/sbin + +FROM ubuntu:21.04 + +COPY --from=stage /zerotier-one /usr/sbin +RUN ln -sf /usr/sbin/zerotier-one /usr/sbin/zerotier-idtool +RUN ln -sf /usr/sbin/zerotier-one /usr/sbin/zerotier-cli + +RUN echo "${VERSION}" > /etc/zerotier-version +RUN rm -rf /var/lib/zerotier-one + + +RUN apt-get -qq update +RUN apt-get -qq install iproute2 net-tools fping 2ping iputils-ping iputils-arping + +COPY entrypoint.sh.release /entrypoint.sh +RUN chmod 755 /entrypoint.sh + +CMD [] +ENTRYPOINT ["/entrypoint.sh"] diff --git a/Dockerfile.release b/Dockerfile.release new file mode 100644 index 0000000..87ef653 --- /dev/null +++ b/Dockerfile.release @@ -0,0 +1,23 @@ +# vim: ft=dockerfile + +FROM debian:bullseye + +ARG VERSION + +RUN apt-get update -qq && apt-get install curl gpg -y +RUN mkdir -p /usr/share/zerotier && \ + curl -o /usr/share/zerotier/tmp.asc "https://download.zerotier.com/contact%40zerotier.com.gpg" && \ + gpg --no-default-keyring --keyring /usr/share/zerotier/zerotier.gpg --import /usr/share/zerotier/tmp.asc && \ + rm -f /usr/share/zerotier/tmp.asc && \ + echo "deb [signed-by=/usr/share/zerotier/zerotier.gpg] http://download.zerotier.com/debian/bullseye bullseye main" > /etc/apt/sources.list.d/zerotier.list + +RUN apt-get update -qq && apt-get install zerotier-one=${VERSION} curl iproute2 net-tools iputils-ping openssl libssl1.1 -y +RUN rm -rf /var/lib/zerotier-one + +COPY entrypoint.sh.release /entrypoint.sh +RUN chmod 755 /entrypoint.sh + +HEALTHCHECK --interval=1s CMD bash /healthcheck.sh + +CMD [] +ENTRYPOINT ["/entrypoint.sh"] diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..06a3fad --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,149 @@ +----------------------------------------------------------------------------- + +Business Source License 1.1 + +License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. +"Business Source License" is a trademark of MariaDB Corporation Ab. + +----------------------------------------------------------------------------- + +Parameters + +Licensor: ZeroTier, Inc. +Licensed Work: ZeroTier Network Virtualization Engine 1.4.4 + The Licensed Work is (c)2019 ZeroTier, Inc. +Additional Use Grant: You may make use of the Licensed Work, provided you + do not use it in any of the following ways: + + * Sell hosted ZeroTier services as a "SaaS" Product + + (1) Operate or sell access to ZeroTier root servers, + network controllers, or authorization key or certificate + generation components of the Licensed Work as a + for-profit service, regardless of whether the use of + these components is sold alone or is bundled with other + services. Note that this does not apply to the use of + ZeroTier behind the scenes to operate a service not + related to ZeroTier network administration. + + * Create Non-Open-Source Commercial Derivative Works + + (2) Link or directly include the Licensed Work in a + commercial or for-profit application or other product + not distributed under an Open Source Initiative (OSI) + compliant license. See: https://opensource.org/licenses + + (3) Remove the name, logo, copyright, or other branding + material from the Licensed Work to create a "rebranded" + or "white labeled" version to distribute as part of + any commercial or for-profit product or service. + + * Certain Government Uses + + (4) Use or deploy the Licensed Work in a government + setting in support of any active government function + or operation with the exception of the following: + physical or mental health care, family and social + services, social welfare, senior care, child care, and + the care of persons with disabilities. + +Change Date: 2026-01-01 + +Change License: Apache License version 2.0 as published by the Apache + Software Foundation + https://www.apache.org/licenses/ + +Alternative Licensing + +If you would like to use the Licensed Work in any way that conflicts with +the stipulations of the Additional Use Grant, contact ZeroTier, Inc. to +obtain an alternative commercial license. + +Visit us on the web at: https://www.zerotier.com/ + +Notice + +The Business Source License (this document, or the "License") is not an Open +Source license. However, the Licensed Work will eventually be made available +under an Open Source License, as stated in this License. + +For more information on the use of the Business Source License for ZeroTier +products, please visit our pricing page which contains license details and +and license FAQ: https://zerotier.com/pricing + +For more information on the use of the Business Source License generally, +please visit the Adopting and Developing Business Source License FAQ at +https://mariadb.com/bsl-faq-adopting. + +----------------------------------------------------------------------------- + +Business Source License 1.1 + +Terms + +The Licensor hereby grants you the right to copy, modify, create derivative +works, redistribute, and make non-production use of the Licensed Work. The +Licensor may make an Additional Use Grant, above, permitting limited +production use. + +Effective on the Change Date, or the fourth anniversary of the first publicly +available distribution of a specific version of the Licensed Work under this +License, whichever comes first, the Licensor hereby grants you rights under +the terms of the Change License, and the rights granted in the paragraph +above terminate. + +If your use of the Licensed Work does not comply with the requirements +currently in effect as described in this License, you must purchase a +commercial license from the Licensor, its affiliated entities, or authorized +resellers, or you must refrain from using the Licensed Work. + +All copies of the original and modified Licensed Work, and derivative works +of the Licensed Work, are subject to this License. This License applies +separately for each version of the Licensed Work and the Change Date may vary +for each version of the Licensed Work released by Licensor. + +You must conspicuously display this License on each original or modified copy +of the Licensed Work. If you receive the Licensed Work in original or +modified form from a third party, the terms and conditions set forth in this +License apply to your use of that work. + +Any use of the Licensed Work in violation of this License will automatically +terminate your rights under this License for the current and all other +versions of the Licensed Work. + +This License does not grant you any right in any trademark or logo of +Licensor or its affiliates (provided that you may use a trademark or logo of +Licensor as expressly required by this License). + +TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON +AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, +EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND +TITLE. + +----------------------------------------------------------------------------- + +MariaDB hereby grants you permission to use this License’s text to license +your works, and to refer to it using the trademark "Business Source License", +as long as you comply with the Covenants of Licensor below. + +Covenants of Licensor + +In consideration of the right to use this License’s text and the "Business +Source License" name and trademark, Licensor covenants to MariaDB, and to all +other recipients of the licensed work to be provided by Licensor: + +1. To specify as the Change License the GPL Version 2.0 or any later version, + or a license that is compatible with GPL Version 2.0 or a later version, + where "compatible" means that software provided under the Change License can + be included in a program with software provided under GPL Version 2.0 or a + later version. Licensor may specify additional Change Licenses without + limitation. + +2. To either: (a) specify an additional grant of rights to use that does not + impose any additional restriction on the right granted in this License, as + the Additional Use Grant; or (b) insert the text "None". + +3. To specify a Change Date. + +4. Not to modify this License in any other way. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1bedf30 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +# Common makefile -- loads make rules for each platform + +OSTYPE=$(shell uname -s) + +ifeq ($(OSTYPE),Darwin) + include make-mac.mk +endif + +ifeq ($(OSTYPE),Linux) + include make-linux.mk +endif + +ifeq ($(OSTYPE),FreeBSD) + CC=clang + CXX=clang++ + ZT_BUILD_PLATFORM=7 + include make-bsd.mk +endif +ifeq ($(OSTYPE),OpenBSD) + CC=clang + CXX=clang++ + ZT_BUILD_PLATFORM=9 + include make-bsd.mk +endif + +ifeq ($(OSTYPE),NetBSD) + include make-netbsd.mk +endif + +drone: + @echo "rendering .drone.yaml from .drone.jsonnet" + drone jsonnet --format --stream + drone sign zerotier/ZeroTierOne --save diff --git a/OFFICIAL-RELEASE-STEPS.md b/OFFICIAL-RELEASE-STEPS.md new file mode 100644 index 0000000..f7842e9 --- /dev/null +++ b/OFFICIAL-RELEASE-STEPS.md @@ -0,0 +1,33 @@ +ZeroTier Official Release Steps +====== + +This is mostly for ZeroTier internal use, but others who want to do builds might find it helpful. + +Note: Many of these steps will require GPG and other signing keys that are kept in cold storage and must be mounted. + +# Bumping the Version and Preparing Installers + +The version must be incremented in all of the following files: + + /version.h + /zerotier-one.spec + /debian/changelog + /ext/installfiles/mac/ZeroTier One.pkgproj + /ext/installfiles/windows/ZeroTier One.aip + ../DesktopUI/mac-app-template/ZeroTier.app/Contents/Info.plist + +The final .AIP file can only be edited on Windows with [Advanced Installer Enterprise](http://www.advancedinstaller.com/). In addition to incrementing the version be sure that a new product code is generated. (The "upgrade code" GUID on the other hand must never change.) + +# Building for Supported Platforms + +## Macintosh + +Mac's easy. Just type: + + make official + +You will need [Packages](http://s.sudre.free.fr/Software/Packages/about.html) and our release signing key in the keychain. + +## Windows + +First load the Visual Studio solution and rebuild the UI and ZeroTier One in both x64 and i386 `Release` mode. Then load [Advanced Installer Enterprise](http://www.advancedinstaller.com/), check that the version is correct, and build. The build will fail if any build artifacts are missing, and Windows must have our product singing key (from DigiCert) available to sign the resulting MSI file. The MSI must then be tested on at least a few different CLEAN Windows VMs to ensure that the installer is valid and properly signed. diff --git a/README.docker.md b/README.docker.md new file mode 100644 index 0000000..0410f89 --- /dev/null +++ b/README.docker.md @@ -0,0 +1,72 @@ +# ZeroTier One in a container! + +**NOTE:** _Most of this information pertains to the docker image only. For more information about ZeroTier, check out the repository_: [here](https://github.com/zerotier/ZeroTierOne) or the [commercial website](https://www.zerotier.com). + +[ZeroTier](https://www.zerotier.com) is a smart programmable Ethernet switch for planet Earth. It allows all networked devices, VMs, containers, and applications to communicate as if they all reside in the same physical data center or cloud region. + +This is accomplished by combining a cryptographically addressed and secure peer to peer network (termed VL1) with an Ethernet emulation layer somewhat similar to VXLAN (termed VL2). Our VL2 Ethernet virtualization layer includes advanced enterprise SDN features like fine grained access control rules for network micro-segmentation and security monitoring. + +All ZeroTier traffic is encrypted end-to-end using secret keys that only you control. Most traffic flows peer to peer, though we offer free (but slow) relaying for users who cannot establish peer to peer connections. + +The goals and design principles of ZeroTier are inspired by among other things the original [Google BeyondCorp](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43231.pdf) paper and the [Jericho Forum](https://en.wikipedia.org/wiki/Jericho_Forum) with its notion of "deperimeterization." + +Visit [ZeroTier's site](https://www.zerotier.com/) for more information and [pre-built binary packages](https://www.zerotier.com/download/). Apps for Android and iOS are available for free in the Google Play and Apple app stores. + +ZeroTier is licensed under the [BSL version 1.1](https://mariadb.com/bsl11/). See [LICENSE.txt](https://github.com/zerotier/ZeroTierOne/blob/master/LICENSE.txt) and the [ZeroTier pricing page](https://www.zerotier.com/pricing) for details. ZeroTier is free to use internally in businesses and academic institutions and for non-commercial purposes. Certain types of commercial use such as building closed-source apps and devices based on ZeroTier or offering ZeroTier network controllers and network management as a SaaS service require a commercial license. + +A small amount of third party code is also included in ZeroTier and is not subject to our BSL license. See [AUTHORS.md](https://github.com/zerotier/ZeroTierOne/blob/master/AUTHORS.md) for a list of third party code, where it is included, and the licenses that apply to it. All of the third party code in ZeroTier is liberally licensed (MIT, BSD, Apache, public domain, etc.). + +## Building the docker image + +Due to the network being a substrate for most applications and not an application unto itself, it makes sense that many people would want to build their own image based on our formula. + +The image is based on `debian:buster`. + +The `Dockerfile.release` file contains build instructions for building the described image in the rest of the README. The build is multi-arch and multi-release capable. + +These build arguments power the build: + +- `PACKAGE_BASEURL`: The base URL of the package repository to fetch from. (default: `https://download.zerotier.com/debian/buster/pool/main/z/zerotier-one/`) +- `ARCH`: The architecture of the package, in debian format. Must match your image arch. (default: `amd64`) +- `VERSION`: **REQUIRED** the version of ZeroTier to fetch. + +You can build this image like so: + +``` +docker build -f Dockerfile.release -t mybuild --build-arg VERSION=1.6.5 . +``` + +## Using the docker image + +The `entrypoint.sh` in the docker image is a little different; zerotier will be spawned in the background and the "main process" is actually just a sleeping shell script. This allows `zerotier-one` to gracefully terminate in some situations largely unique to docker. + +The `zerotier/zerotier` image requires the `CAP_NET_ADMIN` capability and the `/dev/net/tun` device must be forwarded to it. + +To join a network, simply supply it on the command-line; you can supply multiple networks. + +``` +docker run --name myzerotier --rm --cap-add NET_ADMIN --device /dev/net/tun zerotier/zerotier:latest abcdefdeadbeef00 +``` + +Once joining all the networks you have provided, it will sleep until terminated. Note that in ZeroTier, joining a network does not necessarily mean you have an IP or can do anything, really. You will want to probe the control socket: + +``` +docker exec myzerotier zerotier-cli listnetworks +``` + +To ensure you have a network available before trying to listen on it. Without pre-configuring the identity, this usually means going to the central admin panel and clicking the checkmark against your zerotier identity. + +### Environment Variables + +You can control a few settings including the identity used and the authtoken used to interact with the control socket (which you can forward and access through `localhost:9993`). + +- `ZEROTIER_JOIN_NETWORKS`: additional way to set networks to join. +- `ZEROTIER_API_SECRET`: replaces the `authtoken.secret` before booting and allows you to manage the control socket's authentication key. +- `ZEROTIER_IDENTITY_PUBLIC`: the `identity.public` file for zerotier-one. Use `zerotier-idtool` to generate one of these for you. +- `ZEROTIER_IDENTITY_SECRET`: the `identity.secret` file for zerotier-one. Use `zerotier-idtool` to generate one of these for you. + +### Tips + +- Forwarding port `:9993` to somewhere outside is probably a good idea for highly trafficked services. +- Forwarding `localhost:9993` to a control network where you can drive it remotely might be a good idea, just be sure to set your authtoken properly through environment variables. +- Pre-generating your identities could be much simpler to do via our [terraform plugin](https://github.com/zerotier/terraform-provider-zerotier) diff --git a/README.md b/README.md new file mode 100644 index 0000000..0de8328 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +BackOne - (1.14.1) +====== +https://backone.cloud diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md new file mode 100644 index 0000000..72ca1f3 --- /dev/null +++ b/RELEASE-NOTES.md @@ -0,0 +1,499 @@ +ZeroTier Release Notes +====== + +# 2024-09-12 -- Version 1.14.1 + + * Multithreaded packet I/O support! Currently this is just for Linux and must + be enabled in local.conf. It will likely make the largest difference on small + multi-core devices where CPU is a bottleneck and high throughput is desired. + It may be enabled by default in the future but we want it to be thoroughly + tested. It's a little harder than it seems at first glance due to the need + to keep packets in sequence and balance load. + * Several multipath bug fixes. + * Updated the versions on a number of libraries related to OIDC support and HTTP. + * MacOS .app now shows the correct version in its Info.plist manifest. + * Sanitize MAC addresses in JSON format rules parser. + * Some basic information about the platform (OS, CPU architecture) is now reported + to network controllers when networks are joined so it can be displayed to + network admins and in the future used in policy checking and inventory operations. + +# 2024-05-02 -- Version 1.14.0 + + * Linux I/O performance improvements under heavy load + * Improvements to multipath + * Fix for port rebinding "coma" bug after periods offline (some laptop users) + * Fixed a rules engine quirk/ambiguity (GitHub Issue #2200) + * Controller API enhancements: node names and other node meta-data + * Other bug fixes + +# 2023-09-12 -- Version 1.12.2 + + * More improvements to macOS full tunnel mode. + * Faster recovery after changes to physical network settings. + +# 2023-08-25 -- Version 1.12.1 + + * Minor release to fix a port binding issue in Linux. + * Update Debian dependencies. + * No changes for other platforms. + +# 2023-08-23 -- Version 1.12.0 + + * Experimental Windows ARM64 support + * Fix numerous sleep/wake issues on macOS and other platforms + * Faster recovery after changes to physical network settings + * Prometheus compatible metrics support! + * Fix full tunnel mode on recent macOS versions + * Numerous macOS DNS fixes + * 10-30% speed improvement on Linux + +# 2023-03-23 -- Version 1.10.6 + + * Prevent binding temporary ipv6 addresses on macos (#1910) + * Prevent path-learning loops (#1914) + * Prevent infinite loop of UAC prompts in tray app + +# 2023-03-10 -- Version 1.10.5 + + * Fix for high CPU usage bug on Windows + +# 2023-03-07 -- Version 1.10.4 + + * SECURITY FIX (Windows): this version fixes a file permission problem on + Windows that could allow non-privileged users on a Windows system to read + privileged files in the ZeroTier service's working directory. This could + allow an unprivileged local Windows user to administrate the local ZeroTier + instance without appropriate local permissions. This issue is not remotely + exploitable unless a remote user can read arbitrary local files, and does + not impact other operating systems. + + * Fix a bug in the handling of multiple IP address assignments to virtual + interfaces on macOS. + +# 2023-02-15 -- Version 1.10.3 + + * Fix for duplicate paths in client. Could cause connectivity issues. Affects all platforms. + * Fix for Ethernet Tap MTU setting, would not properly apply on Linux. + * Fix default route bugs (macOS.) + * Enable Ping automatically for ZeroTier Adapters (Windows.) + * SSO updates and minor bugfixes. + * Add low-bandwidth mode. + * Add forceTcpRelay mode (optionally enabled.) + * Fix bug that prevented setting of custom TCP relay address. + * Build script improvements and bug fixes. + +# 2022-11-01 -- Version 1.10.2 + + * Fix another SSO "stuck client" issue in zeroidc. + * Expose root-reported external IP/port information via the local JSON API for better diagnostics. + * Multipath: CLI output improvement for inspecting bonds + * Multipath: balance-aware mode + * Multipath: Custom policies + * Multipath: Link quality measurement improvements + +Note that releases are coming few and far between because most of our dev effort is going into version 2. + +# 2022-06-27 -- Version 1.10.1 + + * Fix an issue that could cause SSO clients to get "stuck" on stale auth URLs. + * A few other SSO related bug fixes. + +# 2022-06-07 -- Version 1.10.0 + + * Fix formatting problem in `zerotier-cli` when using SSO networks. + * Fix a few other minor bugs in SSO signin to prepare for general availability. + * Remove requirement for webview in desktop UI and instead just make everything available via the tray pulldown/menu. Use [libui-ng](https://github.com/libui-ng/libui-ng) for minor prompt dialogs. Saves space and eliminates installation headaches on Windows. + * Fix SSO "spam" bug in desktop UI. + * Use system default browser for SSO login so all your plugins, MFA devices, password managers, etc. will work as you have them configured. + * Minor fix for bonding/multipath. + +# 2022-05-10 -- Version 1.8.10 + + * Fixed a bug preventing SSO sign-on on Windows. + +# 2022-04-25 -- Version 1.8.9 + + * Fixed a long-standing and strange bug that was causing sporadic "phantom" packet authentication failures. Not a security problem but could be behind sporadic reports of link failures under some conditions. + * Fixed a memory leak in SSO/OIDC support. + * Fixed SSO/OIDC display error on CLI. + * Fixed a bug causing nodes to sometimes fail to push certs to each other (primarily affects SSO/OIDC use cases). + * Fixed a deadlock bug on leaving SSO/OIDC managed networks. + * Added some new Linux distributions to the build subsystem. + +# 2022-04-11 -- Version 1.8.8 + + * Fix a local privilege escalation bug in the Windows installer. + * Dependency fix for some Ubuntu versions. + * No changes for other platforms. Windows upgrade recommended, everyone else optional. + +# 2022-03-30 -- Version 1.8.7 + + * Fix for dependency installations in Windows MSI package. + * Fix for desktop UI setup when run by a non-super-user. + * Bug fix in local OIDC / SSO support for auth0 and other providers. + * Other minor fixes for e.g. old Linux distributions. + +# 2022-03-04 -- Version 1.8.6 + + * Fixed an issue that could cause the UI to be non-responsive if not joined to any networks. + * Fix dependency issues in Debian and RedHat packages for some distributions (Fedora, Mint). + * Bumped the peer cache serialization version to prevent "coma" issues on upgrade due to changes in path logic behaving badly with old values. + +# 2022-02-22 -- Version 1.8.5 + + * Plumbing under the hood for endpoint device SSO support. + * Fix in LinuxEthernetTap to tap device support on very old (2.6) Linux kernels. + * Fix an issue that could cause self-hosted roots ("moons") to fail to assist peers in making direct links. (GitHub issue #1512) + * Merge a series of changes by Joseph Henry (of ZeroTier) that should fix some edge cases where ZeroTier would "forget" valid paths. + * Minor multipath improvements for automatic path negotiation. + +# 2021-11-30 -- Version 1.8.4 + + * Fixed an ugly font problem on some older macOS versions. + * Fixed a bug that could cause the desktop tray app control panel to stop opening after a while on Windows. + * Fixed a possible double "release" in macOS tray app code that crashed on older macOS versions. + * Fixed installation on 32-bit Windows 10. + * Fixed a build flags issue that could cause ZeroTier to crash on older ARM32 CPUs. + +# 2021-11-15 -- Version 1.8.3 + + * Remove problematic spinlock, which was only used on x86_64 anyway. Just use pthread always. + * Fix fd leak on MacOS that caused non-responsiveness after some time. + * Fix Debian install scripts to set /usr/sbin/nologin as shell on service user. + * Fix regression that could prevent managed routes from being deleted. + * DesktopUI: Remove NSDate:now() call, now works on MacOS 10.13 or newer! + +# 2021-11-08 -- Version 1.8.2 + + * Fix multicast on linux. + * Fix a bug that could cause the tap adapter to have the wrong MAC on Linux. + * Update build flags to possibly support MacOS older than 10.14, but more work needs to be done. It may not work yet. + * Fix path variable setting on Windows. + +# 2021-10-28 -- Version 1.8.1 + + * Fix numerous UI issues from 1.8.0 (never fully released). + * Remove support for REALLY ancient 1.1.6 or earlier network controllers. + * MacOS IPv6 no longer binds to temporary addresses as these can cause interruptions if they expire. + * Added additional hardening against address impersonation on networks (also in 1.6.6). + * Fix an issue that could cause clobbering of MacOS IP route settings on restart. + + * NOTE: Windows 7 is no longer supported! Windows 7 users will have to use version 1.6.5 or earlier. + +# 2021-09-15 -- Version 1.8.0 (preview release only) + + * A *completely* rewritten desktop UI for Mac and Windows! + * Implement a workaround for one potential source of a "coma" bug, which can occur if buggy NATs/routers stop allowing the service to communicate on a given port. ZeroTier now reassigns a new secondary port if it's offline for a while unless a secondary port is manually specified in local.conf. Working around crummy buggy routers is an ongoing effort. + * Fix for MacOS MTU capping issue on feth devices + * Fix for mistakenly using v6 source addresses for v4 routes on some platforms + * Stop binding to temporary IPv6 addresses + * Set MAC address before bringing up Linux TAP link + * Check if DNS servers need to be applied on macOS + * Upgrade json.hpp dependency to version 3.10.2 + +# 2021-09-21 -- Version 1.6.6 + + * Backport COM hash check mitigation against network member impersonation. + +# 2021-04-13 -- Version 1.6.5 + + * Fix a bug in potential network path filtering that could in some circumstances lead to "software laser" effects. + * Fix a printf overflow in zerotier-cli (not exploitable or a security risk) + * Windows now looks up the name of ZeroTier devices instead of relying on them having "ZeroTier" in them. + +# 2021-02-15 -- Version 1.6.4 + + * The groundhog saw his shadow, which meant that the "connection coma" bug still wasn't gone. We think we found it this time. + +# 2021-02-02 -- Version 1.6.3 + + * Likely fix for GitHub issue #1334, an issue that could cause ZeroTier to + go into a "coma" on some networks. + * Also groundhog day + +# 2020-11-30 -- Version 1.6.2 + + * Fix an ARM hardware AES crypto issue (not an exploitable vulnerability). + * Fix a Linux network leave hang due to a mutex deadlock. + +# 2020-11-24 -- Version 1.6.1 + +This release fixes some minor bugs and other issues in 1.6.0. + + * Fixed a bug that caused IP addresses in the 203.0.0.0/8 block to be miscategorized as not being in global scope. + * Changed Linux builds to (hopefully) fix LXC and SELinux issues. + * Fixed unaligned memory access that caused crash on FreeBSD systems on the ARM architecture. + * Merged CLI options for controlling bonded devices into the beta multipath code. + * Updated Windows driver with Microsoft cross-signing to fix issues on some Windows systems. + +# 2020-11-19 -- Version 1.6.0 + +Version 1.6.0 is a major release that incorporates back-ported features from the 2.0 branch, which is still under development. It also fixes a number of issues. + +New features and improvements (including those listed under 1.5.0): + + * **Apple Silicon** (MacOS ARM64) native support via universal binary. ZeroTier now requires the very latest Xcode to build. + * **Linux performance improvements** for up to 25% faster tun/tap I/O performance on multi-core systems. + * **Multipath support** with modes modeled after the Linux kernel's bonding driver. This includes active-passive and active-active modes with fast failover and load balancing. See section 2.1.5 of the manual. + * **DNS configuration** push from network controllers to end nodes, with locally configurable permissions for whether or not push is allowed. + * **AES-GMAC-SIV** encryption mode, which is both somewhat more secure and significantly faster than the old Salsa20/12-Poly1305 mode on hardware that supports AES acceleration. This includes virtually all X86-64 chips and most ARM64. This mode is based on AES-SIV and has been audited by Trail of Bits to ensure that it is equivalent security-wise. + +Bug fixes: + + * **Managed route assignment fixes** to eliminate missing routes on Linux and what we believe to be the source of sporadic high CPU usage on MacOS. + * **Hang on shutdown** issues should be fixed. + * **Sporadic multicast outages** should be fixed. + +Known remaining issues: + + * AES hardware acceleration is not yet supported on 32-bit ARM, PowerPC (32 or 64), or MIPS (32 or 64) systems. Currently supported are X86-64 and ARM64/AARCH64 with crypto extensions. + +# 2020-10-05 -- Version 1.5.0 (actually 1.6.0-beta1) + +Version 1.6.0 (1.5.0 is a beta!) is a significant release that incorporates a number of back-ported fixes and features from the ZeroTier 2.0 tree. + +Major new features are: + + * **Multipath support** with modes modeled after the Linux kernel's bonding driver. This includes active-passive and active-active modes with fast failover and load balancing. See section 2.1.5 of the manual. + * **DNS configuration** push from network controllers to end nodes, with locally configurable permissions for whether or not push is allowed. + * **AES-GMAC-SIV** encryption mode, which is both somewhat more secure and significantly faster than the old Salsa20/12-Poly1305 mode on hardware that supports AES acceleration. This includes virtually all X86-64 chips and most ARM64. This mode is based on AES-SIV and has been audited by Trail of Bits to ensure that it is equivalent security-wise. + +Known issues that are not yet fixed in this beta: + + * Some Mac users have reported periods of 100% CPU in kernel_task and connection instability after leaving networks that have been joined for a period of time, or needing to kill ZeroTier and restart it to finish leaving a network. This doesn't appear to affect all users and we haven't diagnosed the root cause yet. + * The service sometimes hangs on shutdown requiring a kill -9. This also does not affect all systems or users. + * AES hardware acceleration is not yet supported on 32-bit ARM, PowerPC (32 or 64), or MIPS (32 or 64) systems. Currently supported are X86-64 and ARM64/AARCH64 with crypto extensions. + * Some users have reported multicast/broadcast outages on networks lasting up to 30 seconds. Still investigating. + +We're trying to fix all these issues before the 1.6.0 release. Stay tuned. + +# 2019-08-30 -- Version 1.4.6 + + * Update default root list to latest + * ARM32 platform build and flag fixes + * Add a clarification line to LICENSE.txt + * Fix license message in CLI + * Windows service now looks for service command line arguments + * Fixed a bug that could cause excessive queued multicasts + +# 2019-08-23 -- Version 1.4.4 + + * Change license from GPL3 to BSL 1.1, see LICENSE.txt + * Fix an issue with the "ipauth" rule and auto-generated unforgeable IPv6 addresses + * Fix socket/bind errors setting IPs and routes on Linux + +# 2019-08-12 -- Version 1.4.2 + + * Fix high CPU use bug on some platforms + * Fix issues with PostgreSQL controller DB (only affects Central) + * Restore backward compatibility with MacOS versions prior to 10.13 + +# 2019-07-29 -- Version 1.4.0 + +### Major Changes + + * Mac version no longer requires a kernel extension, instead making use of the [feth interfaces](https://apple.stackexchange.com/questions/337715/fake-ethernet-interfaces-feth-if-fake-anyone-ever-seen-this). + * Added support for concurrent multipath (multiple paths at once) with traffic weighting by link quality and faster recovery from lost links. + * Added under-the-hood support for QoS (not yet exposed) that will eventually be configurable via our rules engine. + +### Minor Changes and Bug Fixes + + * Experimental controller DB driver for [LF](https://github.com/zerotier/lf) to store network controller data (LFDB.cpp / LFDB.hpp). + * Modified credential push and direct path push timings and algorithms to somewhat reduce "chattiness" of the protocol when idle. More radical background overhead reductions will have to wait for the 2.x line. + * Removed our beta/half-baked integration of Central with the Windows UI. We're going to do a whole new UI of some kind in the future at least for Windows and Mac. + * Fixed stack overflow issues on Linux versions using musl libc. + * Fixed some alignment problems reported on ARM and ARM64, but some reports we could not reproduce so please report any issues with exact chip, OS/distro, and ZeroTier version in use. + * Fixed numerous other small issues and bugs such as ARM alignment issues causing crashes on some devices. + * Windows now sets the adapter name such that it is consistent in both the Windows UI and command line utilities. + +# 2018-07-27 -- Version 1.2.12 + + * Fixed a bug that caused exits to take a long time on Mac due to huge numbers of redundant attempts to delete managed routes. + * Fixed a socket limit problem on Windows that caused the ZeroTier service to run out of sockets, causing the UI and CLI to be unable to access the API. + * Fixed a threading bug in the ZeroTier Core, albeit one that never manifested on the regular ZeroTier One service/client. + * Fixed a bug that could cause the service to crash if an authorized local client accessed an invalid URL via the control API. (Not exploitable since you needed admin access anyway.) + +# 2018-05-08 -- Version 1.2.10 + + * Fix bug loading `moons.d/` files for federated root operation. + * Fix compile problem with ZT_DEBUG on some versions of `clang` + * Fix slow network startup bug related to loading of `networks.d/` cache files + +# 2018-04-27 -- Version 1.2.8 + + * Linux version once again builds with PIE (position independent executable) flags + * Fixed bug in zerotier-idtool file sign and verify + * Fixed minor OSX app typo + * Merged alpha NetBSD support (mostly untested, so YMMV) + * Merged several minor typo and one-liner bug fixes + +# 2018-04-17 -- Version 1.2.6 + + * Features and Core Improvements + * Path selection has been overhauled to improve path stability, simplify code, and prepare for multi-path and trunking in the next major release. + * This version introduces remote tracing for remote diagnostics. Network controllers can set a node (usually the controller itself) to receive remote tracing events from all members of the network or from select members. Events are only sent if they pertain to a given network for security reasons. + * Multicast replication can now be done by designated multicast replicators on a network (flagged as such at the controller) rather than by the sender. Most users won't want this, but it's useful for specialized use cases on hub-and-spoke networks and for low-power devices. + * Cryptographic performance improvements on several platforms. + * Multithreaded performance improvements throughout the code base, including the use of an inline lightweight spinlock for low-contention resources. + * Bugs fixed + * Disappearing routes on Mac (GitHub issue #600) + * Route flapping and path instability in some dual-stack V4/V6 networks + * Blacklist (in local.conf) doesn't work reliably (GitHub issue #656) + * Connection instabilities due to unsigned integer overflows in timing comparisons (use int64_t instead of uint64_t) + * Binaries don't run on some older or lower-end 32-bit ARM chips (build problem) + * ARM NEON crypto code crashes (build problem) + * Fixed some lock ordering issues revealed by "valgrind" tool + * The "zerotier-idtool" command could not be accessed from "zerotier-one" via command line switch + * Leaking sockets on some platforms when uPnP/NAT-PMP is enabled + * Fixed two very rare multithreading issues that were only observed on certain systems + * Platform-Specific Changes + * MacOS + * Installer now loads the kernel extension right away so that High Sierra users will see the prompt to authorize it. This is done in the "Security & Privacy" preference pane and must be done directly on the console (not via remote desktop). On High Sierra and newer kexts must be authorized at the console via security settings system preferences pane. + * Windows + * The Windows installer should now install the driver without requiring a special prompt in most cases. This should make it easier for our packages to be accepted into and updated in the Chocolatey repository and should make it easier to perform remote installs across groups of machines using IT management and provisioning tools. + * The Windows official packages are now signed with an EV certificate (with hardware key). + * The Windows UI can now log into ZeroTier Central and join networks via the Central API. + * The `zerotier-idtool` command should now work on Windows without ugly hacks. + * Upgraded the installer version. + * Made a few changes to hopefully fix sporadic "will not uninstall" problems, though we cannot duplicate these issues ourselves. + * Linux + * Device names are now generated deterministically based on network IDs for all newly joined networks. + * Android + * Multicast now works on Android in most cases! Android apps can send and receive multicast and subscribe to multicast group IPs. Note that in some cases the app must bind to the specific correct interface for this to work. + * IPv6 can be disabled in UI for cases where it causes problems. + +# 2017-04-20 -- Version 1.2.4 + + * Managed routes are now only bifurcated for the default route. This is a change in behavior, though few people will probably notice. Bifurcating all managed routes was causing more trouble than it was worth for most users. + * Up to 2X crypto speedup on x86-64 (except Windows, which will take some porting) and 32-bit ARM platforms due to integration of fast assembly language implementations of Salsa20/12 from the [supercop](http://bench.cr.yp.to/supercop.html) code base. These were written by Daniel J. Bernstein and are in the public domain. My MacBook Pro (Core i5 2.8ghz) now does almost 1.5GiB/sec Salsa20/12 per core and a Raspberry Pi got a 2X boost. 64-bit ARM support and Windows support will take some work but should not be too hard. + * Refactored code that manages credentials to greatly reduce memory use in most cases. This may also result in a small performance improvement. + * Reworked and simplified path selection and priority logic to fix path instability and dead path persistence edge cases. There have been some sporadic reports of persistent path instabilities and dead paths hanging around that take minutes to resolve. These have proven difficult to reproduce in house, but hopefully this will fix them. In any case it seems to speed up path establishment in our tests and it makes the code simpler and more readable. + * Eliminated some unused cruft from the code around path management and in the peer class. + * Fixed an issue causing build problems on some MIPS architecture systems. + * Fixed Windows forgetting routes on sleep/wake or in some other circumstances. (GitHub issue #465) + +# 2017-03-17 -- Version 1.2.2 + + * A bug causing unreliable multicast propagation (GitHub issue #461). + * A crash in ARM binaries due to a build chain and flags problem. + * A bug in the network controller preventing members from being listed (GitHub issue #460). + +# 2017-03-14 -- Version 1.2.0 + +Version 1.2.0 is a major milestone release representing almost nine months of work. It includes our rules engine for distributed network packet filtering and security monitoring, federated roots, and many other architectural and UI improvements and bug fixes. + +## New Features in 1.2.0 + +### The ZeroTier Rules Engine + +The largest new feature in 1.2.0, and the product of many months of work, is our advanced network rules engine. With this release we achieve traffic control, security monitoring, and micro-segmentation capability on par with many enterprise SDN solutions designed for use in advanced data centers and corporate networks. + +Rules allow you to filter packets on your network and vector traffic to security observers. Security observation can be performed in-band using REDIRECT or out of band using TEE. + +Tags and capabilities provide advanced methods for implementing fine grained permission structures and micro-segmentation schemes without bloating the size and complexity of your rules table. + +See the [rules engine announcement blog post](https://www.zerotier.com/blog/?p=927) for an in-depth discussion of theory and implementation. The [manual](https://www.zerotier.com/manual.shtml) contains detailed information on rule, tag, and capability use, and the `rule-compiler/` subfolder of the ZeroTier source tree contains a JavaScript function to compile rules in our human-readable rule definition language into rules suitable for import into a network controller. (ZeroTier Central uses this same script to compile rules on [my.zerotier.com](https://my.zerotier.com/).) + +### Root Server Federation + +It's now possible to create your own root servers and add them to the root server pool on your nodes. This is done by creating what's called a "moon," which is a signed enumeration of root servers and their stable points on the network. Refer to the [manual](https://www.zerotier.com/manual.shtml) for instructions. + +Federated roots achieve a number of things: + + * You can deploy your own infrastructure to reduce dependency on ours. + * You can deploy roots *inside your LAN* to ensure that network connectivity inside your facility still works if the Internet goes down. This is the first step toward making ZeroTier viable as an in-house SDN solution. + * Roots can be deployed inside national boundaries for countries with data residency laws or "great firewalls." (As of 1.2.0 there is still no way to force all traffic to use these roots, but that will be easy to do in a later version.) + * Last but not least this makes ZeroTier somewhat less centralized by eliminating any hard dependency on ZeroTier, Inc.'s infrastructure. + +Our roots will of course remain and continue to provide zero-configuration instant-on deployment, a secure global authority for identities, and free traffic relaying for those who can't establish peer to peer connections. + +### Local Configuration + +An element of our design philosophy is "features are bugs." This isn't an absolute dogma but more of a guiding principle. We try as hard as we can to avoid adding features, especially "knobs" that must be tweaked by a user. + +As of 1.2.0 we've decided that certain knobs are unavoidable, and so there is now a `local.conf` file that can be used to configure them. See the ZeroTier One documentation for these. They include: + + * Blacklisting interfaces you want to make sure ZeroTier doesn't use for network traffic, such as VPNs, slow links, or backplanes designated for only certain kinds of traffic. + * Turning uPnP/NAT-PMP on or off. + * Configuring software updates on Windows and Mac platforms. + * Defining trusted paths (the old trusted paths file is now deprecated) + * Setting the ZeroTier main port so it doesn't have to be changed on the command line, which is very inconvenient in many cases. + +### Improved In-Band Software Updates + +A good software update system for Windows and Mac clients has been a missing feature in previous versions. It does exist but we've been shy about using it so far due to its fragility in some environments. + +We've greatly improved this mechanism in 1.2.0. Not only does it now do a better job of actually invoking the update, but it also transfers updates in-band using the ZeroTier protocol. This means it can work in environments that do not allows http/https traffic or that force it through proxies. There's also now an update channel setting: `beta` or `release` (the default). + +Software updates are authenticated three ways: + + 1. ZeroTier's own signing key is used to sign all updates and this signature is checked prior to installation. ZeroTier, Inc.'s signatures are performed on an air-gapped machine. + + 2. Updates for Mac and Windows are signed using Apple and Microsoft (DigiCert EV) keys and will not install unless these signatures are also valid. + + 3. The new in-band update mechanism also authenticates the source of the update via ZeroTier's built-in security features. This provides transport security, while 1 and 2 provide security of the update at rest. + +Updates are now configurable via `local.conf`. There are three options: `disable`, `download`, and `apply`. The third (apply) is the default for official builds on Windows and Mac, making updates happen silently and automatically as they do for popular browsers like Chrome and Firefox. Updates are disabled by default on Linux and other Unix-type systems as these are typically updated through package managers. + +### Path Link Quality Awareness + +Version 1.2.0 is now aware of the link quality of direct paths with other 1.2.0 nodes. This information isn't used yet but is visible through the JSON API. (Quality always shows as 100% with pre-1.2.0 nodes.) Quality is measured passively with no additional overhead using a counter based packet loss detection algorithm. + +This information is visible from the command line via `listpeers`: + + 200 listpeers XXXXXXXXXX 199.XXX.XXX.XXX/9993;10574;15250;1.00 48 1.2.0 LEAF + 200 listpeers XXXXXXXXXX 195.XXX.XXX.XXX/45584;467;7608;0.44 290 1.2.0 LEAF + +The first peer's path is at 100% (1.00), while the second peer's path is suffering quite a bit of packet loss (0.44). + +Link quality awareness is a precursor to intelligent multi-path and QoS support, which will in future versions bring us to feature parity with SD-WAN products like Cisco iWAN. + +### Security Improvements + +Version 1.2.0 adds anti-DOS (denial of service) rate limits and other hardening for improved resiliency against a number of denial of service attack scenarios. + +It also adds a mechanism for instantaneous credential revocation. This can be used to revoke certificates of membership instantly to kick a node off a network (for private networks) and also to revoke capabilities and tags. The new controller sends revocations by default when a peer is de-authorized. + +Revocations propagate using a "rumor mill" peer to peer algorithm. This means that a controller need only successfully send a revocation to at least one member of a network with connections to other active members. At this point the revocation will flood through the network peer to peer very quickly. This helps make revocations more robust in the face of poor connectivity with the controller or attempts to incapacitate the controller with denial of service attacks, as well as making revocations faster on huge networks. + +### Windows and Macintosh UI Improvements (ZeroTier One) + +The Mac has a whole new UI built natively in Objective-C. It provides a pulldown similar in appearance and operation to the Mac WiFi task bar menu. + +The Windows UI has also been improved and now provides a task bar icon that can be right-clicked to manage networks. Both now expose managed route and IP permissions, allowing nodes to easily opt in to full tunnel operation if you have a router configured on your network. + +### Ad-Hoc Networks + +A special kind of public network called an ad-hoc network may be accessed by joining a network ID with the format: + + ffSSSSEEEE000000 + | | | | + | | | Reserved for future use, must be 0 + | | End of port range (hex) + | Start of port range (hex) + Reserved ZeroTier address prefix indicating a controller-less network + +Ad-hoc networks are public (no access control) networks that have no network controller. Instead their configuration and other credentials are generated locally. Ad-hoc networks permit only IPv6 UDP and TCP unicast traffic (no multicast or broadcast) using 6plane format NDP-emulated IPv6 addresses. In addition an ad-hoc network ID encodes an IP port range. UDP packets and TCP SYN (connection open) packets are only allowed to destination ports within the encoded range. + +For example `ff00160016000000` is an ad-hoc network allowing only SSH, while `ff0000ffff000000` is an ad-hoc network allowing any UDP or TCP port. + +Keep in mind that these networks are public and anyone in the entire world can join them. Care must be taken to avoid exposing vulnerable services or sharing unwanted files or other resources. + +### Network Controller (Partial) Rewrite + +The network controller has been largely rewritten to use a simple in-filesystem JSON data store in place of SQLite, and it is now included by default in all Windows, Mac, Linux, and BSD builds. This means any desktop or server node running ZeroTier One can now be a controller with no recompilation needed. + +If you have data in an old SQLite3 controller we've included a NodeJS script in `controller/migrate-sqlite` to migrate data to the new format. If you don't migrate, members will start getting `NOT_FOUND` when they attempt to query for updates. + +## Major Bug Fixes in 1.2.0 + + * **The Windows HyperV 100% CPU bug is FINALLY DEAD**: This long-running problem turns out to have been an issue with Windows itself, but one we were triggering by placing invalid data into the Windows registry. Microsoft is aware of the issue but we've also fixed the triggering problem on our side. ZeroTier should now co-exist quite well with HyperV and should now be able to be bridged with a HyperV virtual switch. + * **Segmentation faults on musl-libc based Linux systems**: Alpine Linux and some embedded Linux systems that use musl libc (a minimal libc) experienced segmentation faults. These were due to a smaller default stack size. A work-around that sets the stack size for new threads has been added. + * **Windows firewall blocks local JSON API**: On some Windows systems the firewall likes to block 127.0.0.1:9993 for mysterious reasons. This is now fixed in the installer via the addition of another firewall exemption rule. + * **UI crash on embedded Windows due to missing fonts**: The MSI installer now ships fonts and will install them if they are not present, so this should be fixed. + +## Other Improvements in 1.2.0 + + * **Improved dead path detection**: ZeroTier is now more aggressive about expiring paths that do not seem to be active. If a path seems marginal it is re-confirmed before re-use. + * **Minor performance improvements**: We've reduced unnecessary memcpy's and made a few other performance improvements in the core. + * **Linux static binaries**: For our official packages (the ones in the download.zerotier.com apt and yum repositories) we now build Linux binaries with static linking. Hopefully this will stop all the bug reports relating to library inconsistencies, as well as allowing our deb packages to run on a wider variety of Debian-based distributions. (There are far too many of these to support officially!) The overhead for this is very small, especially since we built our static versions against musl-libc. Distribution maintainers are of course free to build dynamically linked versions for inclusion into distributions; this only affects our official binaries. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..c539ed6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,93 @@ +# Security + +ZeroTier takes the security of our software products and services seriously, which +includes all source code repositories managed through our GitHub organization. + +## Supported Versions + +The following versions of ZeroTier One receive security updates + +| Version | Supported | +| -------- | ------------------ | +| 1.14.x | :white_check_mark: | +| 1.12.x | :white_check_mark: | +| < 1.12.0 | :x: | + +## Reporting a Vulnerability + +**Please do not report security issues through public GitHub issues** + +Instead, please report vulnerabilities via email to security@zerotier.com. If possible, +please encrypt with our PGP key (see below). + +Please include the following information, or as much as you can provide to help us +understand the nature and scope of the issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +## Preferred Languages + +We prefer all communications to be in English. + +## security@zerotier.com PGP key + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +L455 +=lheL +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/artwork/AppIcon.png b/artwork/AppIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..b96076bea032a6c087e7dfebded1b6a863ab16d7 GIT binary patch literal 40879 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 literal 0 HcmV?d00001 diff --git a/artwork/AppIcon@2x.png b/artwork/AppIcon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6f1952e0345ed583a7ca33ad74d4a170a93af6de GIT binary patch literal 75421 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 O;DSr~%BsKkqyHGxzLOp66Nn?7Q!|=e9GK9(wS; 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 Q`tiT_J70Lp%m3v61D4M0s{jB1 literal 0 HcmV?d00001 diff --git a/artwork/AppIcon_1024x1024.png b/artwork/AppIcon_1024x1024.png new file mode 100644 index 0000000000000000000000000000000000000000..c423c4f73e40d26c512e29afa22d479d3236cdbf GIT binary patch literal 47728 zcmeEu^l-oKp^?y)`CJ35)y(JF9}|{#1Ed}cf0T8ZsE=Et+Nw5VOY6#TO`cvYHk zRZ`v6_72#Yu)eI2^zSGCbM2pfqy-6^6CLJ%l>WX7NR=g%7W~6DSu&NcJO&U58ltRl zMcW&?I6~sh+|#qNs)>uZ(-=|CwQc&v+@b4>INAm}`VxKes_!ulXzX#)IP_K0ME^t@ zZ;sa}_Ki^os}SE;_ufni7<}p(vh%7g7ljSz4!pVBI{bbYm)wxvJnGwuqb%QEY#x3_ zcKqRSDmWzyxfAkBvR2PtSd8K5c=BhV4P2EoO!Y}1PH&beVYQ`Nmb0IEPxFwef1h@P z30j?abhsRYv4Dq~*JzX*&yH2fJqbwO8!e&9#0@Y}F^~o*K%j7x%L}yjYm0Qj&8LI= z;1R`ZOo@VH0mDLS~?__87w1yR?ad2&y)0&mgmrDi%;G4gE(XjOV8RXgXH^{x5GC6Yl{ zk?a@<49PwYgX%!)xPq&+g|JoHI(fML9brz{k?Y@)hvm4NhtGn=;JlDwkyg8avAiK0 zUa|Qmqoa|-krXrkvu($~;n4&NY_!lU*8O_4=|1fFX|G=2IeXWCJs0pHBG?GL9V-zr ze-Jwur?^C!tae!5mCi?@y4}-l7Wb(3&k7e!&~aWVKOj0M&(1KMs|=kQRlJeVE;gSI zqe>&yfXvESUP&&lOCM$4%N#gr38~I7#Fsup{j>kDAeNGGF^lBZKBMh1d9!n$`Sqkq z<$QzhUWa1GYBIXKGoOcK{;Z5V;#b_%tsP4@d#&(@Ks$i}gqGc*5Yv#LQ}!HZkj6#kuU)1O5{kByx9&2J1Q9b-79&2suXv&HRD z(NFa*F6dL$A1;$&=tzU`dv;eZAGKEmzR|3FEP_LPpM(8F;s&jT7+S-c>`o|!4lI-P z>CGN7ZLe#JQ1e6Y%!1vU^h{hYLY{~E;sWmYhj09EBS4(^P4o!a#|9MVHj2~w#_SI$ zt1g)aL_aypDMhE)4p$MFuW5Eym96mkzuYL*WIs3bJ?>;C{8NJ~j}_nXcd#1m9`hPr zBMXNF>qTRmop}|<==%Rj9f&@hG(CoHJKk<1&gpizST_fZl^aOw9qhF5k3NQ>8Ad5O zhU|9d=e(i+Q#Nq0F|zb>iVcb3S*hCZjNep`SLw{HiJgL&qz>&Xc;H9)*-ppEiOzd@ zz@~^%yJp?X$l+bf9DyfkwokVxy(iI!S%bv~k}M*OmA`LUq?c z$5D3MKM-2kY5xGz6f$xAR^FBjdFrwlb3Qa_JLKnfNd0qULgTN0i~yV~mF(=s#p7`{ zQ*kzR*6#*$nwXLyNMB6W^N_D%p^ob(ioX7pJOru=Pnrw~=n6fE4Be1cJ<}MTPeta*;NCSSMc5DPd0Qh+?SSNd^Qu_?Tu{o&I)&W`1IA=nm&UddQB! zh{9x^FxIw-x^mmoyz~sxfD~Rnt8zFLG|~6(F)_#ByvGLF&XQpsI$YJl(}z9}B{>W- z`@5U?4QvC-YDa>ZLfpKW7h)K6ant$nmy$p4-vsY(v0W#_RI;iZZjbTrkp64JE-{ch z=%%MWRgm-nyX=6@{-PwrBm6%)3j|TBhwbyWYHkbZK3Z5zgaS%q9FxY~ET?n5bO;`M@+yHJ#{XrQ^@VMT{FZ3g`i=N}C%y}~X#!muk> zUo%O;`GaCkA>!dS8D_*jq(`0M&9zs&`TT#^WkOt93lXAclu`ODRO0Ejb_?3Barcz8 zl|#aq!12J}j_CJ4D_HaxXGq5k)3X6qE}IvL8wLk?*1CR$8PnLR?#P3J8)}bav8>M z?%>@6w!S~zt2Co zlI-y20%s-1UruVW`(_JGxNIneHe zczswE|6CV80#nW5UXKqG{`4cZ+Rh$dykElp z5P(UA*&c?<2TVTTdl+X1c`YFNcC^7(F8V0&s{X%QVq)OkbLhw%Vb@e~NuFSOh+Qat zQ}FZ`Y;pr;{4dv-IZ?ECPDn|)=Rz7}nT;UAeZjIjf(BFi_hCwe5c8Y8F4^d14#2N` zWi^$W_Xu=Lal0~p-t6C4M&L#NnU{lt?#h_GK3gghItZ89>67g9%iS}uYOj$N)l$iCTDIH62=4)OqMwfnHXx6J{Sbn`Du;gYnofhhzLoiFR6 za2%^4MWAb}FH{910v*QmkVNZoLW_jkUuT8RmWCB~j5`m~L*^~Va+fduAQ#R%11Dbb z)OSWl<~`q*D3YFXh)w3Ds*0BM;ckx0fxnT(|8x?~6cqBM-lFgH>f9jQ-JG3~9zt=a z{((_Q^b*OF=C*$Y1*o3A@N%$E{6JmNvN&F7-VoC5MAdS%(6ph=d7gOFlh=Px_CU`0 zOAXeiR@)i?kAXi}2(7;nqcThPuc*+FASd#(w;7a%vn?pFV^^>3w;ot*jV+mk9si@* z@WoRaG=?5GUPKSuZMA1ZH1rN#e}&&IM^60pXzrTmxb__G61(SFUGix#^v9iy-h+uu zv$!oP%PW6aHv1M6J)C(iCwkUyy*(A8;kAEj;jrLmnyBybpucOq=QQUCBsz=&hX1>kFOehp4}&M&&7@RlRyr^d1Hu zN7T&ognmr0MPES@@lpRAmb=n!-hR7w8D@Uiq&Q*Z$=NRV$7~?5GcddPEbf|OSqFZ| zjjBt%mFD()?qPrQ4ui?YL_@M{^Zcpy$uQB5^_}~n=IvF(bEp5Z7kUpW0@dv@7dc%# zXQ2hf>RvT*Pt#pU9Gp`BXEYqFWN%eObH+W_Vqh02O&6npP#eNQpJGaiC+xshhbd4s=E;F0E`3%)7 z7`CdJ*Zam<7D?j!?_qXdvr}7o2mTp_HNwq+Z`C1b4 zNvD_RD$#wUxG`Eare|v4XYe-!#;|jCVdjEb(67JV3t)Imw6syh`ScG6G`qV*L3Iaz z@)csgqz}}pEs-_|*6U$)2bwoQYt`nna5e1?5g&|sv8nBLXB-D=Kf$n>-}Seho4%%6 z5Ir!=hvn|HlXPsUjfS!JGfTRH(8GP#@Y)|UK-cuZ?9O~l?XtV&_ys(KW+_NNU(9Y8 zP2>$~m|%n@o}uYZ5!}F&z6zlWx1aq{3Jm5B%i-pMffq%{(XpUxbHd%_nCKk0AhsZCWr}LioW`nMo7?0O!VEX#$siv zbux^HAfu`d_qA)6|4I|d-hKv~I$-z7v9mS>hP|7md61*b(Q)FBK7q{^1+m;ic0U~J z!4qhcXw*s!HI?IEC%}%WxdJ0B;3{?Z6y(Fr5EDMi=dXx>7JzH_VRk=0a*vJ#ywild z^SXMgq$`ogI^n~7=Jj>uLkLXf)$^ideeat8vJlk{97sjEKMD(OpVoOQngstFb1;}u z*hqYUS1x3HGO*H%DoOqi=`Jzo5-J#okh7kL6UD3SY(!kmrkfo-Tfu~Yu;Gnl3Jb&k zGPLFkY(xs#9ty+yzG?XKY=w#FEfn%5mPu;nRAf_G0Dt9EeS2Q?q~q2j&UAC*p$ z4*iF?DVW{!9PW7wxijY=H|Ur`X)Q{cpAf5;c_k(~DeIX}e>gzWEo_fQE-(=uWNIK)q)Ok z#cI7_Lgc$H@%HQjsOTJ$+BuO57}hUTvzjmVSO0P1EgVo9T^=H~RFl-E&^&)92Gx90 zVkY(Tphi<?IC}b5Ss^eVwd4H!(A7k&AFZ316pFjg-`O%sR01* z&>dy_`a~kJJ);|7cCg&k)g?JeX_&^3UAd*EReGX@H%`sEFpgP3+Xp6&$*gk`;~i=K z_6gytLs*TTmA1o%FmvPI^o4y~0V)!z7rE=nxOMr-6mtVFqlVWK;;o*iBZFDAo0ryy~x7bI4K8e5p7>f+FO$X2$O;oZ6ye+h=b zNJtAs@}09FHdz|t=|TZP#P@v2!9BTjh{iT~I$w_zv1bHm^CG;v?g%>+#G(z+rhC$H zGKN_C7#cWb^eCG)BoC5KQ~!#Ah#ut4aqOH70?~BDE|$r?EexT@7Bte}g*8 zzB2nSg>XaFO(R;!$1rknL9R3ZVeQsG_dGrZ(-PsA1nLJu_qIWMS=DOkTIA0z?Y35fzFD?R$8zA z_w7t{(mg87NLR+9+hr#S*UPCv!ScX2on zA7}PD_RiO_Taa!yG7Tl;0}3L)WldhFvSUPsdHbMdz<^qYNPNh`bM2QVoXn6RW)SkJ)^US zAORAX(&_t*tdcCiA!I04yaB6TOmUTWzt(4>8PyPB6?;5|IXZl=7 zBoC^H9)F3l(Sc~++)!d8)(i7ww3f|a_4X-tv$#-;_WyX~>&V48!p_m3>EFP`{fQif zd0Ne=t(+2Mkr}o}q?>3pY!5X=4H{vU#zQ32MQR&L)qM$=IhAZBk(RUb*HA-j@9h!! z;u=M07^MHH`kzW3@N3t}{oLT}O(&x~h< zif+Y|cCV2i{l{xA)7s={A5{iG=B`fYHK8UusVwQh)Sy za~w5sLpIez|r|u~;lVfOTP5hr~8PHoX_*EqcFQh`K_dn@R z^g#n-&|P+iQ{MQu??t!NfXK#uf*MBo{3g~v>Za{h%KMmk3|`FgP4tJORz9H(Z)Hby ziCx}CUq)cw$D7zJ>^%Ey;!UScz)W9H?U)(6d+{XlcoGGtjUH~}Kl=CycEy7Xr3AU%GDqy^%Kyjl#m+P{qNN`ZmX3v;%~taw zA`hUZsZ;DRQ*%TWB`6cT6xn~=y^J`W6@_}hF*+EBt~9IvED98n)JvIoNp|x{bo)3G zqq^ZvbXp7rEEabAn4}4j!kR~+(;?&k0UxH+8hsEKYK-3T80o+4st`bxQ9=G=zbhdS z1jhPFw8Gz~P#3ReK~{<5IW!lk0r9?*(nv$ZPA;IKPQ)4-44P-s!u=_K+B3jYAt3w2 zn27Zx7P8WA9!Z=9oq{YLBjTj@bquUV{-J6n(KQW79u<+>8|Q$ML8vH1Gl+Nq4kP=2 zhxtFw{Lz8`4|N880sh-41ZZs55I?e*nlhuitL;m4$#0j~S}!&5-6-h%SaOwZn=ebY;~oXvm!BcH&>5uMM@Wn)9X^hh5aslLFyd37;e&(+k)HNfeHsnd7L>ofYn&IyCx(8yl1AU-KPB}mGt=PEt@DeX+tmqR$YSxOvLR{*_sX>e`RcA*bGqq;6TQ;{< z_r#XdDar)fa_*kG!!V!Cp>sT>jp_|N^CH6_j|jKoVKfN=SfERQ3oHB95DA=N&~C)f28BsJOh;=BpOTPpn>aLYepb}645PjIKL6^^>)$EceVBLg6IA*7N-`r zC6q=KQss2CgzpXKO%V@o^&F03E7U9q3WYRSNW0T@BoYc2rsvIa@N>3(7QInjemgDg z?OeB?u_T4yWv=DA#?P52HG&a7*4&W4L*p}wX&(!w~w3mFB8zGdCFuz|Xr5|{TAE+^wHI6oDhc!?#*K>$oYxKoFv zabPgya8Di4qxIS(fb5LRL*MM1T#VQKfL%VnvQD!W=;>!Vc41lYF72hIGXPM5tx`n& z!CQ2&`BQ-&T{++-ACE7h2?+@QLWWa^4>jx&aemhmURY1J#diibJ>Fy!Jfi^Q4zypg zWH5&^D!+wbhZUf3IG7R8cW}Dqn35h#PfL6U1u; z6++2d6>)GhZuG)ade1a*FKU0&PV%}MIiKVY@c_#lNp_b(3;#*W&ykp}`fzXRm11zp zl7@suYL{~KJ=>3x-|&swFZ5fwmgF6c0whk8%1JoA%!EJLR4w2~N)nQrGt^kfQ-v3f zKx7gyyDM$wrUu(<2Os^WaIsh1TvF^lw`-+sy?6Vy^4`ivLYxAiWvDX&wphhBo`kj` z)5-nJ%t|Mh^?Ln_%bG7MN2V*nw1V%nO1Ra%@7lYUn5US0l^4mLR}Deb9I+mN;z}5; zjm?_eq2{VgZjP0zdP7*EFRZOexoW=9V%~6~J4Ju{_BC$6D>|SPB_U_;vyWRqi(>Ke z&Q5+SEfnRM(bCQ6`9ad#sdXljzAJCiD3`h-nUFSOlJG~EDBvY3r1z%6Fq4R0$1Gj8 z-7Ko3g&0_v`V+YEc@!Iy$EfD9TnVe4{wt>iR9_VW)w6(|f>1JD{CW)%?8{U#D#q1E5te5dN8@lG#4 zEWbljP9~r|p_N7EBF_N7#4F&OX9dtu>^_p34Hi$U@xu3Lddy62qgPRPXLV6_Jg%fRDouS`T*q#+JZ;>1^MF3P2<+JOvZ*sMGsh^+oWf| zDdD%WsjFq&6kN}gP`Qn*L{P&R!9&nVc zN#PG;vuW$!Jt}W3d?kYqSgn%}-afHS>OiQVKH^71QKGbm}8lpoYHfSV5ys7=RMzlN#VsO8fAd<0R@2+YxP+*~!>9A+Y;^HKkNu^x=$i3&Awl8sR zcYZ&1Dwg%xo<{oRzMejesblV4Ez=%`^T)N7^Ry1LZamO%%(L)Sz3k;~Z;kAUD8V13 z?@aF+;a#@AXQ{KrGq82FJ~;qPL_Jl(z}PPd76U7%L5vy}PR=*H%^lITvW&^G&D8Tb zD6I%tP0VGTT+}veh6ct(NqGP$e2}DYu)daT zf4t+hLiel4g?NL*+49F;CgMlgbBC(7k&3{QCV?ffjzIy*zVL1djwpQf2WS3KTlMX| zO-6bek-O$THf0H8R>N5LO=p}+sO(?~v+Dv*Is6&XnyqWr%`kz0Q ze#&@XUVVE0dn47dzRO0xDZbS2(l%AGQ*g>1xbzt`bo^Biw<_G78VP@}U0F2|-jewWgntiT?nBTdbDNp)5h(sX(F<@(!Mf<>Aa8H~$|40T|MK3J^Z zh^Jt@bgI*{!v?(3;nx`>*7CKN8QIj`9aXhsC{T+B<7}R`gd+SqUaV|G<@Bydp#S}k zZMe@}65T2IlyjdO!rI=;N)B=IY`rU;DRjEgbCZ)KB`Y@};azS(t{Po*b?V|IZTYBa zMVI|IjN~=D!PxK|X^+{DGvPY+GDW&S38hV}7SvQklFRZKK!Z6oGg)3Het1iDlf@VY zdjE}5Qy$eh8Q&YYiNnq^zVGWpCpCD;<2=3PHa&7J(%(GRK8>xCHPxJdRnXM^Q+fNy zt2T?gI4cWwS9N*hE$VmMVUP|Bu^D;{D%zNHus20jV=_fQUwM(qtmWhLWHSn==KMRS zhLann#r->2wLBsDirq=+)#CS`?%isLmNhd;Js;#nhr7^!i=Pf-!jkdgp?aCca(FoF zPRR@I+tz3MX^$U*l?#A>h!rtac!7z8n;u#YP2=^;{JkDVJ_wW6ExKAAy_^u>ZMJEF ze<_>sO04E`^C^wK6U=f#dj2Da>!dL^7qq!n2BU`L^mTtOyR{wRB3p151~QhJ{YE>E zwRETO10a(DJn&7Dw}q%Y9c)tS+^68T6)U^CM#*`_>$AL8zuqkZ1S7uiG{A5qv}v%A zrDv}ucIu`zm9ANNR*dPcWlWiiuF1vm-uzE{9!Z>z_bzfws3fDS0j zNy*~A(ySeyPI+{ARh^QdH{J8B?q^qJR({oo>n-~@ zwQ76l&0UXgC1O~|3&g((?3^0ynD+~0 z6`-AsdgHz%k$eO^9#vG7?3QU_nKm|KfXiO@_|#c^I-czs z%nd6wR+!XH@V78Teymz9ckk3D^zo?XSK>*bBb7NU78H;@W=Hr#x4?{?8 ziSHj(@u>Z%{Iy}hqqh7}Q23QCCyIu~WBJvw?mp`*&ymd^Wny&8F3Ul=Tugka2Yd2G zk|?Qa(S7*v?WvG+^rZER`7gicO+8 zYR|B|XfIx`FT?&ZlV4bcG`6D5b}Q7)d3TkeXp1_kyuVbcLj)!YF#qq$ySOs8sw1%R z*b6)`do{8$ooo;;1Y~UUB>SqJ=}K^p(_c$ok%!DCY^~60ImrYrK6G~SUTF!P-`M*; zl(&0&e$={8rob?cGDVl$g-qrkMA75JOaz^R*9JbfQnv(7}-U z+`v1W=BMBsrwb~fTN0n@V-pa}bT__wj#Q{x%KlMw(#XN2(7c^m!#DMsJ@S;Z^_eub zWNi4+P&wwfSBn)7=NF3mm_1v91p}(C1=^hfg;E*-j8*DV&cTPdQ74WQKEJoy7PfvP=UaX&h~oQ!4wA*TbzH}H5yl+ zv-7++RRn0itAtiBJ;;w?-5-s;{DkM5)Z)_SvR)q>zM;)iPYUOAJZf1rQCc9k`wQ4%4_!>AHF}~ zt#dq`ua$<`Bk-BJ?$WKOJ%?e<$<9|Cz@_h~VPNA@&e`|k1PNAvR70eO-kv!yyn03J?oD_F zQ2Ftedp!2=L0WI?Rkh6leDO%w=eEA|BU{|C@MI{{-4nQ|UMJlHC{zmGP2pvBa5#}L z8ql5cMP_lfn$LeZ(@t`$OuZ*AynO9;{6kQj0Pe))JDQpsOa+El6wGzU%;@xqz1Zj- zQM;t|^C)2T5iM2h#TQI_o_!HBM!eW%mf~6G1{t4kuVX{tV zJIfCufhmXtKA|KX?B-Dz!8=dQSte0`o;2xtkZ zu<$N^CfDp}`i`~VxYyUZ*y-&!Y|h3VfAx~3r%r83AL;h`5<<-m$FsXA7Z#ox<5#y* zabuTq>p6nqELU#4MA`r#hiycoj>C#cU+alvPUB5u7cg1@>#h;_{RYm_^6BqF4=*{a zCt1PEcrF$?&u0Zn|2#Ch8#Ws?So!vB{Gsk_5;nXfs_&+|B53`wgYr2$m#Q4n<{SXY zEfa3C(P@WCY#o|U%JTa%Nz|o#IN0LsBnIIhUe&D9xJ8Wxe)X6M33<_R7=pd?_)W0M zddCftQF7ztRqj)8VM6)E0gWVqUJ26q_GZ4Il0wQ3vA=jjZ*u(--LOY?S-##4O9#F9 zHaArJEp`rpU%l%M0#(~P8MT*+POOw;i{JLKZSJen%xCjCFlce0GZVb|6tJ9= zplQ{Z%_N)K>3t_WWU4>#z;cbJgiRz#ZhOnMr%LG(3o^a@Nu}F*vvrQFu#`;I!5chB#e?~2NyM@{@K>lB-w1JR9&J_{fm5oK%9*D z`5W6WIEzHiUYsF2*m-xwo;BKIx%p@?wY{5JyM)wtE3#!!@wz#f=L4V&ou=S`!T7>W zcO04w0*{jNC9u{vlvg{bOhxB57t*#{ZggJ0nsgP7W|!ie*d1d%+RzD3<+1hYDK9e_ zM{Hlv7NewZ$ASuO-c=9^$#e!4&`Lo(qk_`79KoW>4qV;Ai6Z77f@-Wu$t*$~>;f)F z`48WYczvbjEU5FP%#!zLaPgR2sje&&$o@D$D9im(5qtP@pnvVPZGK(c0HbX8Gugga z*~O;va3&FUliC#|DYP8E=9}i{+0Y?&6uSo8&6%ss;hhZ_f_&X^13>O5tq@~Hk>%OoS1=n z$U*}DPOY5Y{AnglAVptT#bhy0EsomdS&cv51Ye#e?C&eExKb^AUXmbc2~W=_=L{NyguxyXNm{DL3{ni)BAh#8C1rSLIR4pG1D27p>q5CdieL%I%ZO5K>Vl#MzV-Rma3XB z&wuK2j>#PwsruCUbL_M2FSb_J#zX&+;@Vf?s<5bpOB<0x;kOoS2D$@>M)r=?Q{fKQ zmaa(+9$l^mgETUPk_`h%61wJW(6t4x1i!A~GR11;rT1OUuQ_Ds#(alKBlVXWnAHuh zm?zXwCx7Z$TE83C+Dn#_A>rM-WajtjlXg}*5)2<163WcI`7E1IIR?^x$`*t>zIb}uXCz^QVjV43_Hs&K}g#)R-6pfIc+Mq5;c8xi-iH;9wvpa%1bi@?6j)zLMpgpxmQOwxI> z)zJS^W1DJx;Ea$`cvA<@*)vyaHetb(xXFOEhg-$L0`w?YreZV!wb;;*` zAmvwnqe$I;3#(*TA-TT{i(5XmHQIU7Bm5$N5t0lV4sfWq`?&HD3k>gVKN*KNNK+Tk zixXWO3w)Qld@Du$y21kt3F4<^G9DNdQ=qtE!Z4d}?(9}nRWA=KAobrO%h(s#ysng< zbcJ>#+%hS2Uog%a;H;#c!+`r>s^K_HELLnUL60S~ZRA0&uTRf?)g%ZC0*%8Y{o~={Cup% z!G^P0hS3|Z)m>@ON@@mjx!4x*7WML^M$>%8&|&7C;t!IG>1;*AGr=V+_vbCZcOg%! z0SZxtHH5V7E`}wG7_b)ROStSguJ@?kboh!j0{W(ifniLb&|p&SzFoB{+jv7`_25$9 z4-J8S`Wi48-EYXId(QwJ!bt%I22jSjbd#z`uqJ8f?6nuS^92eQ;ZU_c?2%r(@W zXF?UJ+JA~#toOb)+w5O+`FfX$D4^7w4C<>M4j3Xg%uW_dGRurUoLN}4P2%bmevV;6 z>}{y*ZEPj;Q1t#x9|5_A->+m#u}hIOMBS+y=CxbV>o|k-w;g$hLIJqly2DR};tBnp z6fks+0c_wjDcgwW6sUH3Aon{-=miC{+c{2JqHF8{A559`Hixdv`_bO(D;ru+;=}-LURA1QFyaTXo<{87!b=cGKKqFmB(brfR>L}8nsq@ zc}B{Xk{7>r6Vtm+M)0vG`W-lt#nt@N0NV}k5AMy#joBG(^Rr~N9gS63_!xeo^Ezcm z`W$}-gQiCS$8zMhR5-~!<-WT6OGcI7!39)Fo9)Bjf})ihh()cT{V-t4vPMM zLKuG&_3usIGr!(9A33ri0dEwbI>#!u8aTrkZ1MimPWJ;^n8-_F-Z83zkk|l@!m_`j z2fjAyH#H4xHKP+A@^|sOjW67Gdf)h7&U2Y;BNQV7JNGQnEr^>c|Go*k2dsT}+wa3$ z$vp0x;PZ;0W5A72o|>?R3sY-&HST_4F?+4u?^mr-G+Hf*OUMck8Q?=6gLWY<-TFCN zY5VJ4&|GQ>v*ttK(k|nrt8=~_eV{x;786SCk`9t4d6KZa5y6Wy&uGp3Du+g;dnyCu zDmHm_4+_0b&9XqV5Z!}V0F>Qq*kW)r6`xAyK?zDf?!po$1_OpY%*D_Ex0KK?mEtxj zwiMq+zQW4x&p4TFg~2L0**USx)Tx<=L6r_w)eV=~oR9j_V(#2ZrH5A#;OBG)kC!Tf z(Dz!zy;!6WxXh&%w=L(2X|YE1zd+-V-Z#w6)n@&wM`cbfw(JG68QwBBw0AzS5r$a+ z3^10fJ3A{KM2@feKB|S+qOt0ZmZMp7tP*Iy=gK9MokA1mB;mic6z8JBgKDa9He zxUDyQx@MyMvd~S<1P25_}#F%&AMF5XP-odnG*Q)OIv^Gpd1ibH+VMak>>SA^-?3vu#NQM zxK=^XD4LM_w!xn(;olD+prucNFc?a2Jt>Zx4JtYC4ha>?+D|x`%@MSpH=ymVzk;1`TY{p zF+is=K@>l~aEb7c`sHO$fda-5!|DX5kF48fcRH^x)&39?4TjEKur;9dAZuaS8dObt zu=|YaxoLcfPM&<()fzs6xu3RO>o&kvWUlfA?w_|Yd-~8#>u5i1PMK6_>oFP(d12!S zVY(WB(J}j@7-`j1(6^x<3q{Es>~LlvjPVudSwB6b@mfs;h?$EwuJP|~_l92fxzk^< zQ(`jLB?v>hv%idI_VJ&MeBb{?^zD(YS19g*FWvEnq5)SeZ3BeEFf!m6Tcurm;G6D> zo!z&1zx<^kw#U`a!b5$g%QzJ`)M=KZmOjW;OG}-*VU+9YI~&MDsO{MMD}zb1X4E@r;q|#JDv{(50>!K4X}S(G z3Rr=ktHSU>05WWjJvQTD=XPnCY;vra!*La?1qN7F>3?zuy~b8r@%5)igqn%TYSz#( zv!n12o||gbV2A<0Nq?&wiec0{E(VQ}Y^R23m%Ac#Qc_ z5;|9)zx6pfY{(j^Zv?88j=@iAj0H5tW~)Iu?a4L3Cu7RL{0i0ZNzOAAa(HH3I_TZI zbby8XYfP0r9|wGsd#l?mJkTQrZgGRx#X`A1iz|=sS?f6u8`$5h6Y8j6ua+@3>9@X# za|c6St+d};uX`K#d!p>yrYx+lO~&%*itB}cr*2oOiN^lnvx zlBMQcZ9bg8#nMp1XTJwvr52p>bnkjl6ZiX0ZFj*Q1DE34 zAVS&zrekGJ2ZUp|U`)k*!yAIWqh*~DmOV1nw<0b1l|vLk5Bes|4t(k?1O^N$_?5H5 zHQx?w2tDWD?K}rd1-AB1?Z!i-`&pL(`J3}GixT@vam7t6fl`c2N1(L(3Yq>G&RV_p z@_M|*U~x;(__u9AO8A4+qU-WVZ_o>?u{x$!R!mm0_N|yIYRGMO@bl$;GnYknqk=T> zagj?*%{JA7@4(`h;@d?wwee}P7e0LeB-J1Q)dCC(w_Ki}liTEG?)lQ?F};l22scyl zJWittd`vQYxyt3>`;l$&Bfq7ttjq^v!Hx4CE|Jgkm*60k?P8Ac*S{Or9H2B zoDG8Fd>I#glJ`aoIKvqGZi<@tfTk}MsS0Dn{e|#`!HB#)^E;Daj7DXtT5x92_Z**{ z;Ph@l8t-rXnBTj*>q2!p`hHh<{rByg;h@@nE=aCv>%#JG)JVcfWp|$W^$8*LH05zKvUwZ+rHgjGF$=WZI=vmb#{tU z&O6JSuJakp_5E(nX#0*BrmpK1emkkdvPW+OV=!L@!$~wGU?_sx-7dtzA zSkMJvBapu-9o+N04n{L@wcFjBTxNo?q$)2m*$r zw^Qn5ya&$izWk9H?X;&Cav5`-|=5qSUpM?Y+X>i69Y7Nv>l%O8|L zeMVz^!}c)1ML}-2hSkq)a&M_;?XZ&*rUpQk%g=P`g3E9x-+QW{CL-ROvNNlcGoD)g zb>1CxulGrZ0|!!A&vo*_b`QQV#ZR->1RVQ9g)HO&&5ZaH)k;_+80clO`sU^tsk+ZK zis5aV$44_ve9o&A27a5VXXD;`_dT9$vE_@1W$-M_A)@_Ki-9ZXfRqdsHG_%V{_gw|#}7EXhN*>NECxs%A3Na_^~ zW&{78m7VJvJR~Nb&qg;vp;0ym3}V!Mk-5E}B1Y&;ngk{KYdP;s%zEM-TG+bzaG-fr zoa$(Jt%eX|mQUZj)S+O$)H`o2H*$fwxn1_$nseb-iB1-RyJFw?q7d-Jr9W42coobK zeT@T`TLDmV>Gh`mcnt33=Ts!e&XQ*6Ep?7Vu}p7|FqJQP>S^e+qlW3oX?2x@E<7Nz zHfSO|o*wjd4g?^W3|Q84KF}BI>E@PlUVJUTA1nUZYi8*8-?#vUq5h}YY;2b`N{76n z-h!?N&GPGIl*>yH${rqnp~1qA)lH<6-IWvIo?lKF${UV9cKjg=ne`U9Q84#a9!~&OhF= z?hQ`Cb|*h4GQ`jqcb5yF4w4mlNgWQY+OeBQWI*?e&oG&sqngH6XhQ z1ZBpQ#7{CXQxIoYzVb#UKdLdw&5oQ+)nTJqyCfhfRNW)ELzvBO*Bf6veHhLh$)idKo;v+4eAuHEP`v;s*-m-~+Xbw%32P zg|$V7XjKY~t3vd)o1mB4V4xaB+KE&HH($uUkG-Hj*jP)z<&I|GFgq@7?Ou2g5d zc)cN&>)VaH+szH%KG0G`$bjp6AiT`VDJrCw*G%H*b-MS?CRey`jUSAj`+XY>m_0{3 z-Tm20$CyKY`>aQ=29$dAJe4HIw*CyBfHmz@WCjG zPU8iAn}l2G?X){Os_OpwX9qa_Ik2CBp8Yze;9W*O%wN7|ZD-l++{TzFMYc-#P=tld z`2Kv};>Hf8n9y!`ps$BNJA0Y-!$#6}X7C4YKoI?*Yy~R8CGQLhEy8bi&YKkIDL%Lz zzCrl>`klbb=u`Vr18tXjap}9DV5_SB==fg`S%gAWeN$0%&0e|Z#{ZfW4CoB=q9kMT zgJ&B~f6eW8VitCF4F_lQt&dQ7gy?nps9W;x)uOQbv~lL_6}QI4S#l^`n(O6j6lX>J zmkN<-vmE~IQrMM?MY z*(u9K)B^=<0oGc#)y)BnCd9|iATItF2r!D2CU?HLH1aSy!R^=6jj7VZfNxa5n_(gm zCx2SzNLi=cJ`M&Mi!#+Viuof3I_O~&K<1B}zr98J@vQuyAL=f19XoVb^{VWg%$4>? z{}$IS4R&Vd2g88tB%3$r7K(B@@WVVY-^!9X;e{Z5X!o>1s@Ml9jq$w>!9CY{l6toO z#@2N+!k!qkvBQRl_0v%r^iGda%}W8)>;pg}eY^MbK7{CU`mW9WjCT*pHgSSgVhY(( zk_4B179k+bp}tmMb5m6J!Yh+1gOia}D5Mq!#;(FEDnBk2)BrZBIN0WCn7&i6h4(t} z17RWujDCs<#>nVj;-Z9Ix9f_E2hP$bj9hb$uYHk9diTmJeZLOP`ko6%ob{?oK#hZI z1l3s>*_gO`3(8Jla}o^*yQAd+GNmAS{IZbF+iD^#jyBYiBVMuymse$LInqJ+Ae>#W zJ}M3r zO&+qnta6*~2_T-~y2AtXi<-A49$?;LU@dYQFXQ0dcG~I_Kkf-73b=xDL_OsXaa-3M z{Zk+-_Vu{;LEp>$5ylBnR2GU{wc%d@V{p(f3xPAS=gK7GdpF>K0Z#NN+3|CJ;(bfW zN&%FhF6GjXq0R|~eKB8oMm5!n2gO3!$&~=nUpGNM1;#jQz!(tEFYBk9JHYxwWvhR0 z@h`Ns;lEgdby&~w$w%b^n^g%J{={H;|2G5L<1tfjAm#RcIDvDvf+qotEeFwmSf=W> zbt+~mlNvN<*zVGM)EnIeNWsSt;;~O`^>B-k0x0O8IyrzV-0nI6Fj|(cK3KoQ3 znZEDZR39hhhBkDKtzuRH02Zmwj$)(t|B~;T;9pVYq9jja4K=vCBhL1Ad6 z97I4`Q9wXpP!VY)r9ry8YX(v26p%(#Kv+OpS?ApI+$j_|swBIufLX=XDnGRZte2;_t}gipvteQGx5 z3t(ebjY_+9D})4#>TOUCZTP+71g;z-KXs|^c>g(B74lozuk(eQm7^kUOrZ0R0ixcv zG~OT^;zU;}H3157yKIaW;x!q>M0KJ7$ot{uuM0oYqrBeG$OMIr<$VDnZd81Z^BxOvA>=1{JTknl)nxN3TL5kOw9ilppaZ@mu}B~({+A* zfNeL+zBZ>TV2=!Zdne(~#r+S$T*|C10QOoTo)?{ulnT=Q|NRh?yVJo+{WmcU#BU(WChcWs9Xvggi~epcKom;KzM~i;CGieH-`V{P?bJjCu$C9Z|#)*J?Pg09fvsX_vfK#(q-m8 z14GBDaTXRn?_b1lVQ?Z#cZizO^6{g=^Re$lOig^fnF653D-=zHm#UZN-Esu=4SnGf zD3ulU^lXe2E^Oe9SL4Y+L;l*$*`1_#n=b%seoiZbSH3CcbX&BwAl+P zOY-z(N@XpY6*^j_6(W{{b)nTrBD3h=UgrgMd>_|_`U+|a9%t}+h~r(r$B(|l66{c+ z9-W*1B>3-A3Z$lzt~)F~tLx;(S<@O<#n7Y?LGvJgn*it zuKko!_Q+)W(e^x`cA@?A6J7u=fKV1j;=5IX%@^AE6{K|CkAii!g_}ySylmdsBp@EXsM56@#Mzz^cN8jABErpqdoSY2S#63UyadYW$+MB zdjz1yJ)?u#LBb|#f~(2X30yl93%lYhzTojRjFux6yrt9a z?IlE6%wRrOUX;|%6`u1L96;MZ_=Uf&R4z5FsayZ8qPI{U5r(M%(l9Mun4F1dqJACB z7orjE>Dd-*1Vj_}oG^?b^^=-R@Q#MgsP5`+z2)>K7eW>~us4y<##lGj$Uo8%DA136 zay3aGJ!pZ#gFC8des-6iOIFH>R^^4RaSqgq)ela-^MhZ>yDm+BR~f?%Gcs}fTh8wZ z_#x%_|7k>^h83!}6Y9kY9$(-d-_k>jL2QODdzS1qB;ZRF7pE7BaQmNY7nYZ7Jb5Jp z=`$F%rQSaB?7T>hik1jP4rhhJhyW>N9Se_*KBv&AY>V`G4g|4>kR>!Fln>x#mUV zolbJ$RMlHd|HcL7fGLY|Vy{$UOT9}=0+>&<}kB)-Ds|2Ts7;$z#hE(#5R)?lx@RcX&vB8EVKVg8zxd^D#IeFhApU zS3wkBAd}+bOu4~-36KN0Q5sI~?GK)Ryf6%3?ty0Lp_xH!8$RcM4Ogc|rLHz`gb+?A zMpyw^D0q`B&rkKT>T7zP)Xc?**^95J0z9bC%L^@AG}AW1X@$YVTFSVg)$9@%_Sn7EzqnXD!`M`|E?Lh z?W^JoXsy13oRj~0kNvst=vXkJ!wCEzv05!X1lC|N^g5XqTS0nOZ`Dt&a<0A0YAf=G zj6f#saCp#8@`sND_ijkU55wbx``;Z9=unRHF{2BH)6} z9oAkY0JZnG*dbw}SL?*%_^Gc*CqR-*$TIC}n zR-zr2?K*S>QU`4ZnlbS(^vRMAF6O2TfgEGhbqeMp>>F3fs15*Uoq}cvnK6HIplp{W+E-ANw{ecz9O}2;NWpekn!n~n7YirtUyKN` zrUr-ZPOzj)0V|xXncZe5xPRTT0a)rw!~wOjLA4?e-0mR9aX=49=#GewI6SSrD88#jHhfwMN|@Cl8?n)KzDA#HPU~RU4$v2o-KCW zS0v2aYdr>eCuFc~!dqvHcf~9;pW>}x@!f70_vNLeLij~oMj+q#kPQ%q_)XH97TNjM zNmA&<$jh{VD_SE<^Sz1yJzfdis&HHYLos#B8y?8BcoG`vz6h3Cv7k%%+xdQi><)yF zIVsUPrQpNHuUdS)gsW&SL_}cubb#LyM1Y6;Z>9mIoj|e3kb>?3H?sn%(nq+*Uuj(9 zyR%1RqW=xmupvizN>F)*+x0C)1TTPHNFYT`OCc#^2Be$}uf19sXoVaNcw;F16(M%W z(?9fs(_eldzxkmL4$GJnE0kw8Y#bhUL`;0OcIwWD7K*q@0}xn%cwal*zUgyO@?YQC z2uKyo#GWF|YB4XqK84-!z*K3LH5^$jfdL7qjUfDx_%i$}bqtb$<=^)Xfnx@Z=2)if z6qJY9j*k{mqLmfb|e1VPC?n13c9H{HSL`-3DHS~d`YJ0zrI4r$M=9r8CjTq3++;AT&Z-MacWtjS4v&DmNuN_J*%FO*amego zQ>6_chbB6rZ=qd`R80yWF!5K3~AKwQIv-mVPOJT*mS61aQoK?eJd20BwRUDIHA z?%AkCm=>($OT#)nRM43E&g`U&FbX5s>5`QViF1qN`{55-0|;Q5$QF7;gnOo4kdS>9 z1{^%$>*qw{zI7S6(kmoKNh zWpxKn|I86jS4EIe zq7G9R@bZV(VLAw-yp^Efz_#aseJrLk(0a9Rp{S_(@2Sq9I3)?RO9mr|BngHt)o`PW zi?q7$2MV&;h679ii*+R|ddgE2l30*rJE^#BOw$g`_Sn(6s6)$m|I!cq*8Mo1BG~Ke<50j@SdLTfpX~ ziDf28Vf2ZTB!HbeKwZkLd^ zkGoSqrvvU!l}Y=tq9rycDU|~|ottLbi_ZiB;q$)t71m8|fe9+HL`}`lG)B(qei~2kBFH}y zBi<8ile=6{Aif`%1b>feJ~vC5=zI>mAs5y2fanKp9NRty?3AI*8@UAAQMT*{KZD_X zyi4@3jhQ-$E}(TR=xtigZ67A%XJWcE08Bb!oZ37w=J_*TL$>jj%812n@>h_Izs z{Ik6QFkc3CReds;1qz0Eh0L8O7Fx*tOJf%J)xgr*LVRkV>fY`n{On=7S30w!&$s4x zQ9HmN6~mPz30_|OU0nTvm?D$FZaOVW=>X1`y42z&Oyx6R1_4id~`MHZ*qLIf}@1;P> zE=bsO1>{p;xKMYm zE7(P2JBUtm7^XA4-)e*16a;p7Xz4byz*~)Io7V~tbtv`K*KX1)IKBhoI(9eA2uz01 zr3ULpZ~IKo+uw4P0=pn(ebg(DF~P}$V<~B5K|{y#H0>9geYkG?J~7!HVex+ioQ)D} z2b(Zos=T`gS_+8CL$3es=Cr{r=NI5TFKmSS4o4J8n51}tCg2#xY!S+-Fx(|N{{hM{oAE)Ik< zIUUDus-L~J+5slL$JHu87K1TSeK*c82e14W?t&h`@qY6BLcVpH33~COSfBz>78#0A zBEOXfyPY59=GYq$qX-!wahyXW9L;i9?G9VjW4tEV2up8s9YAo~v; z>3bi17-;6sK{P=BD#S4hNGw=B-OtzbNg!RF@_%vjSv#VrmxW|GHkdx8>`EZ0h!MbY z!Iu{U>)At_Fr|G9JeU6cR!j?FkuecLB=PT?-6^L3`m#}A@(A6tNO~in2>H}ck`Q;7{UQDg8daP13IQMg-I#lh!^TUGTcK#OS8T0oZi;GcrBHu5DWVB2pW zz8=^sEO*X>p)eW5cfqrFErfet{Cid#JR8>3^zT`AbXgZ)Hi3pvNC`Jc1<>5`zM7Yt znk6z>gT{zM+6hW%-TZ**Ek_3A7I#SCZHA3on86p|eWsjY@t>+h_U^keB%DAW3EHJs zW8IuPpNEBp8nhXGKlt@o4!+tc@Vzfr0L~}r94u{7+WG+lozp%Pf?dAF>{6Enr2zjS zt!z|5M&vOFzShm=AUld|si_Ley=D+d7J3sZp5VoAoirE%+qfdZLZ14<-D>GMsKul1 z7=`7xd8stn-9&@d2=p^K$poS+t1(=t_zqJQc;G)70<+3GvRCl*fv!Zk`j>x>1K+a7 zs8_V2jjnfHP1o`$U@RhKZ?ijbsA>O+_7`!ytKu%}#(aUgm zA#&aoi>-QN^;(LD0c4OAhhQY+lqGT%&|?q72#~k?-awu1XaOB_cJyAQ{0nwsn0e(T z6eTD{sbLmoeSa|T$xjb`MBBXs9^`=)9y#a)bH0jkdcT}o_A9L;@SC+$$G=!Jjwqlu zZ^51@LdKP;J3|6CHT;on(-!f&6MMWTOFpH~goYVGVTZ!y7B1NPC{!OO^LOQfTPq%5 zv4f;{FT3zW#BmnZydGjxO=jzW<{*Kr7etwd2a{AH#8Rsu3@x~ENz6?dvoI$gFUVmV zhSmViUXYMT!lv-%Hsf?B*)2e>0oNQvW$J|@jHuxpL)u?nbooQ0NFV6w?=DE=ZoPy* zCy3|q2O{hLeOX=-gaoc2>MV=37t?2OC3pp*F*YJV;4{k0jdBmSn?a$99l^6nA}&vD z60jZo1RP^j66813;uju2ffo1^6xOo+ZcYc*N(LA`VMF>ui6<#4LTk!hf(cBvfhGs* zhhc{#Ip|?`Oz~zCY~W*)pS^x*MZT1pOv&lMi;ej~Ngxn)?*wIRK@r)6Tn-XfSG0_i*T3d{2Lh&PrFX0)VmV~EO^bm0i%&fJm`E1 zJG1JY9I(l@*&>v+2r+@A7c#BDEVyp$V4`XmfGD|S^=0}1x!e@>-B`)xy7+B!g94!9 z59IXQ^QwY0Q!&3m4)jkFp}0}ga--Ij@Mj=BOtJ2jdak=GS1Ua*@@Vv)Cdb~|6i%F3 zA{2b|ecCIJ3twPX?=cn%a?{;ihMIN@H2;&ZeYdzfBAHeS{GjF4y8S$STGHIk=a;w> z<2+4@=l=f^Dmswtsv&n6DXc>nKk)RB>7dcTl|f~`1fr)B5}^#Y>=`y@LOt)Z{6hyo zdw;ON^O{(a^~6{d%`83DO$oF%K(Fk+40Y|oXSZ31utnc8O0}|e!lnG6b8-f8_fiXAp3COS^+yVtGr*K|Kx ztjWwt_b80&r;M7pDg60|2x&wJ3Izmo;v$lsO3?+Szen2z7jEl->!aB^mz#h z`vD{`2&kMT&R|@*zbSJSp~eqwE+{X^VumNX!T){F0tySaL7=P%&RvuE%G$`y28s-H z6X;NmQCH)Ha1W{kF0t^oGY69H>607WlQ4vF6gX6=i2JjYxan_Uhdza7naUk4&`mFjx6)R5GmA)H zQ-1$-72XWwgns3_LLQBxOaI^)zh|(t3Vn;qX#^bX1_@bKR?eZzvJHRh?c;KcobZkx z-X82pGj8M4DB;NGCX6$~#`L-$u$s>izI&Y*Qn!tbdq#J$gcDas@y%9rV#K51Xb z1m6R(V8P@EGW#sT_ud=ZKOT3%iFWmSMS%`WVulaJo>YJFfAjSvS(lLE6IK`K;n4sx z+a<#H$wxxQcL^~|@1hyOfwIGusX2u$ghM#7$y+H*;ctN&(?(4@?-Sh?ffsm#>jC86 zti53cd?F0q7RP;fN!^BL&vQFXK*dG5B`w{^6yXO-=}36E4g*I|@e`$2R{jZd?-_on z{rCKt$QAbn`S>1MDY^usjKz!p*B|xv8JtmJNKw@ln_Bez7nyaa*JVKGLLs&FgT8%< zK6bWXq+?)o!>;16$&fX_ui5lXR{uBqvc*wCsYmzOYhbc2CIW;Xp9cpm$&*={1WqcG z_pABH1mQj)#6OVx@z#d?fh&fSe_2hO2}ksHoVo8G>tuqcLm&Rd?kF( zSNI>L=zlk!(Gu9t5gqn2hXN9Xrq*BV%~{%sX3fAIKwjZtwM6HHbZ#NL@Jh$rl6$lU*w4wF|ca+4nbc6H!uyPg?OP;Djk%XlJ4nY0|Qgn+kXS< zMJ{`ld+o2KJMfc*KV*4yGf66v*2<$$7rS4zYluMz6DRd4jB_(hrheDN2-njD0E)i~ zah5id+`OJ=f7s4D{AKWdwulWl+!-;KapxCV(3xN)GXaZn(3-Ozn?wr4%n~M2Q60Q3 za^6f~k|d@$-uy_|fg-vcLD^}gogrP-MfN--_@OH{-It0aRz16BtW)UqQ)tf1Q&=V6 zH+|nX2_4UNo*Tmy`G4=EgYCkyUJ$=_M5HZTlUp>!>RTzLp$9QK!R-`jTkF$b8b_C9 z#jOBe0aznp_N&5jQ>L#+nx3&Ai5ahr)N*bGC9ysi1?B*Qg==k*f=+c)tO&ooW980% z`p4^XWAWptf=q0>dFUhi09sfo=CM_i`vpzTV#ULcasNy&P_5@v>w31|HZPV)_6dsC znzrvO+?AV5eMD9O)x58QDMvBH+5(Tqe@&NX%*UwOJt3Gklm!R%9&PwsO@i~rw~Ai!N481x?>-Gf&J~B z3uS(2V5l&ElFE8q_(=yS&Z@9OQ?3%4hjk|N^#kJPEJEI(wZfB7CFQcaT58Gf&u06Y z(Un@@!7<^jIfgWBn_<&rZi`;Mw=Wh}Bm^{a3V};LZZm=@8plJ67Pf7Jim0>@VhBJ; z)W+qc(R$V5A*3;NegR_^pCv>{NJi+MvzANu@77078_+nMh0A|Z;A#Wr<^7Ak$Xdcz z=?%Vl8(e9Eb)DHc-wFk<|AHo7!H9sXQLj^S6?y+6^Ru8r0MVUi0+RpaNB)|GgCeut z*M?H83stNmdqIN17f>eak(^q&;bJ|ekb4?{Ca)mCv$R+R|PI-?pu8QN3IYAe>eWj-_3~z$XDdxos?;5g7HZ*C~#s$K0F_O z8^m##n7L&CcUYQqk)tih2DJe}>9!mKPt(+0xqk+-3+(g-U@Duah3!$4lLFK zcj1dFufpLAjryXK^L*c4aSezp@fIj5EeR2mId=q#?(W)s=Qwzr>Hwf-U(A(2LK!(y z9+GPguCG_}LJ9U5?^VcYI>-`;6tKg?AiQKOB1&FOn37I3dsax+!{6)*F64zgE9UYV}v$&dML#2mUfiv|)}$8h4q- z?C3<2p75cJ^M0F9ou?1Pmgt~xb3KYx)!IuO)ScxX_ZD|~c`fc-faC}Df9KUi8)hMR zXh+o4-V>{??3NxM`{uG|Po)s-{@MWJeupG6vHYHM$*LT)*74VVjQgtk^~L>P{luIb z#mML~_<@Jx$yiI7)70k&-$$Z~zPS-V0B`A0iRA6*YCai4zDblob=( z^-L>I1hZI&uEUz4#N6h&)bmPA;`<@{%u@B?zY`Z?!q1eKVNNj+ISl#WB}TMUj^t5uhYJOr*?d<+UWwS;ABLI-p2 zEUB6w7;xP<=VZ+kp#vfRkbVU6g)dGwUh30vMs`SX(TL|Dr;O@<2xFKC_h6 zlQc`Z;x^|S^Fj{QKhbmst_XSv18gy1VYftd(e-#dAEXXC_Ss2RCHyfTBm$8wKsE%c zbe+Cn%eC+8sa)1!K4>*&{#VvK=o!im(EqU8Ki`MsP`YU!ietT5Vkjnc&5gTupo!~A zDpREAn#CZvmJ+;s9v7}X(KtIj>$`1W{_8rl*lUtSJrbBa#DiSPZ!>1PDO9^&CpfP6V%+jK<#93lUbR2B*q?gnoGl`o6XI0`zPPSL6Vn7@WA5xJ;2O(kZal=>D?=9-gf@X zBxhuMi$?6I{*e|G3lSkE66@xR55K8%GWJv+eqi!C$=7#VZukinEWr5i@t_*!RGi>r zgvhED@9q8pe>~V8Yq%$9mAdO5c$C9^NSq@o=kXMM4Ft6MJ3}KOJnWt0w8vVPzx?XdV#tL0a!&_YQar*4-fOz)5p@m@dykzsf zVm)%Vt6}SMK92}1i4RbJ#BZX9CtcrexW;7t?Hi=Kah?rO-b9cA4mnLBM=!!_`J(d} zW4?;^)cYojSP$F$_ZQIsxLEbvqv$6-m#L?@+IcPSM1U*g0bBqaMZq$jtn3jY<-oYR zX$ZMnsC&LB@nydM&oM;4x2wdcI(L?K^S)1vzU}i=(v4N8U&}tz=^Ylb&8rYVbpcm0 z_u(DSN}g!XRS{{{x>_Y~Ka+jAAAnSo`VBC(<)?v z%aK*gF6s!EmrbR90rIu~S4kdW(H2n%F08sQr$2pE8-C`f+P8PrB!8gOkg?{sU$~}U zV7xb30WfxWOq`a&%nI zs1Lq_`qa`Av$#+%oc-E&w1^6hJWo(avgwQ=dcXMLC?v00Mvkqi$s$&6F(HFliWUdzH82S zJDc(R_d|_Dh5vkW7|n)9ZM~0+IF2fg?uW!XF?VC$X5wfx{3Dbvzu~aHsThutezn6K zxA=QIxTpTU?`fUnM4`TUSdZy5Qt;J<_0M63dfb-m1J#+r zir*p}MLzZS)U7K`Wl_)WcMIiAF;P_{L-)gdxLuH&wo}BmsH)+__i;@1v@J58HRFjgvH}p6@yWCD0|Uf0c7~Hi zoHoShcp8Qr+T$krN^G|W;Z0x(v@WZt3}~Oc6RHkw;||oMK8tgvT3rl-2jk0DPPnobT@QQMDH8NE}j`3Tu^F$Q!p*-3ZrB=_^$A`}Ys>P;W!8 zSyXT*B2P$Ur9+oHm*}YWx>o9`Tk?PZQhsXJ*5Ul%r&I#Z* z`<}h`T4mWN*E$BJ-M#v0?|klaA0gLE#e-UJ&BzL#>2JRE7OX89N~pWa+(5C{_V+?V zBX?zJkg60|6cc5E)dE>Vk{K=R80lmaz0orNC?`mrXSRB$wKCBq_9Yc)48&r&5iV<- z)f@Z8?HralK`sqLtIEQx|4wA;Ka?u=>%+2BYs6J8AFZ?fVuKI6Je?NmE>NivV(LL+ zS&8MkwgKiMwls$X=^Qp!jP4Bm+Wg1)rFvR}v<9?ED z$fQ}0nsn=qHs{MdDgL$3xmR#o(ag-83g$^X1~eW35(Wk&;d;M5`7SO{Uj%)s51{IM zB&fdcQB<5Ig&AHfFTAr>UN`!1GdJen17K1wmWy(4v0G5{TL1M&S`#8=*>7OrLXQ8k zJfh-G5xSMRzAFoA6O(6~`)ciczI(5kUxA1NhnI9LlXG*{K+^7&w=Qf(o>zFLH8-}2 zodp##z|SD?3Zn4)s{tzH(XPm)m&dl_z&qV{Zq4gikXrdi#XfQNY!>6s|7mHQ#ydGu z53BP(Gew$=l3TYR=vFDW?Z_TF4mzDuWn>;1?u1(AZqEwi+Nh9 znZJo4zMy>=O%iv-)-v}(E%TH)&lGoThxI<(9_Kjro>8SH}{;Xjuq7{}wdzy#< zY%SynANf38SHWrdjvUsU<>qwSnA`jkBJF;tsA+6{4HQd2G}FeJ-F#xRm(x#3bR;ZA z(^!@H&`oMT+6oV; zi8wFYSTak?1o^C=F-=boPogmtN3Z*SYkIjNd!@L=u$UCn)&cd-G9x4M@7mYL+PwN-0s<#w~=b|6CGcyrDqnW4n;^J!d4xZm`IPz(=1nx=< zcdV=RPahav!}kL7C+_06?tt50)q#7ju&9t4h=sq1Od(~w*2{OdZEK0mw{*G9l*W!H zV*UbHCxRUvb7Jj#YS3FhNH{FNQO)-A*~#&DU_{wcGPS5yeo$PNlrRs5RgikuKDVP!#BcSd%W$ZEe@u`*E{_>0>;TOXhqmn zR!ZF4jy+_B(p1NUx$lWHFM|@8GFwLMBUqi|S1Rs&?dmHG`VQ{fpM>_*gv>_wbMpNQ zaZYsiZZQ`ihCnf^1Gw%xPa*|SiZ}0o+(hPWscNq(bMlGluP#t|WHbo9y=e(p{}I*R zp{J)w`z9~z7s6YT#syC|IX#x1J$?B99R~?ngv`9dh`D`**T~k%i~3|;x3mVPqR%*x zDoeM0^Eq1LY9BlnYf6fz-tTIy@ZlmLc;F-TR9wYhoRM_@#NlW(?8FH~i#^Up0mQf? z1kj%|+Znq`JrnPGmD7>2QqOL$jpLJahkk}WfIonw(W}5=r|J6SOYi*2CokB3NO%d@ ze;8Z2gTFNdDtWR1_P7%o^%kYb9MR8l);CEK8rnPKJHe6|B!AxNI!Y|vKPL}By&eS4 zZ)U5Q@x*7~k00x*y$04Tcpl|e% zkA%Wc0I55H1MV@P41nQSi5|L+vx_kdRRxM9)@n(_?8kL;xt)xwnh45zf_$?8znz*F zM~C!4V?g>^p z8hM*CAUyJo_`6b>P}Lz*W}RA5{`E0Q6Y3Zhfg*-_fS?o;lEkXEUOMmgE&IOuHgQ6? zy(#PbAzzLAW0k%{eFdQB5C&)UV&n;?60<^GxV3Hxsx@0FbgOoMddC~r5?R~B?^h7k zgJ`Ch(B&_u$n5uZvH0?F=v^sXFHe?j-#J^w^z5(>fl2<4K{Sbit0X+d04M(KbozDX zGfA@@-<`J3A5Yc}UBVb;!Z~lCgr8zc@x5|yil(~#c8^tD$LxHk8E1jLf9E7)?ndDQ z+8#kpcVDOAB375oE(pt&dkX9y^ZiN@Ozt0$Y29NyS^Ls0DE#BYLsX9nhI&faxuM+s z@X~G|Z^xavZve9yE_%aOQwr(V$(5tv|DyFD8~Q z)d+3cYm|i}f0IQJuh|~2kQNcBn@h+g$L0DS^~!nsI;&k;nMK19s4S?hUzAGs3BC+I zD{spyIP$)GqQs+S(>g_)yuh3-4q?X6g)sEQF?h;!yG9!RB7npXHNxH;6Bd?RLfmyAEuN=z`JactVq$j&;{& z!Qw$mM4hGCzMGMDmw%zolhI4L%vg*a_^j`Tg@SNRqOr|w9)**lcQzmYK2mg_V7}+O zzh;rIp19lUeD5YB;)KF&t#8-#(E}Zx;!RseXDzvkJIB-Qj=y&$6@cR2g3NefAq9Md z_@SHm{w1D)wI>fM@BOl!)OG*9ZsHh6@OM%ik@Xduvm>PtebCljl`~)?)pe_s0|#*CYCH)H$PcMt-Yd*inSq9964k>bh6G zL}Qb$vx#TrhI%6&jEqA-UE&XZ`KyD=6!DIOsSdj>vRAi<3qBbw)%N+EpZ%dd75(u$ zA~*sSL9v)}?sST;&d3|m&iVLL;>kUuU)=?F#;MUg5kV2C9#B8W1RJ1{h{w0k=Zp$< zx#tyqBX6=!^%G(!uAMD*#+Zs8oGy&ha_ch6K3fgO1VEu`^or@)hnkWcrTkJ+(s|D_ ztlD{vtDW0};&W7}Sm#asIuLdqW|RZ~iY+KkYVBXCviO`q?4Y1mnc4kUuU!Gmx6EklOay?KnBT#Q7vjEcB+n0<6+|qLY{VYbaUaJK6Cuhwrll^y2{!^G z*pOM2FSiU0&PD1E+iAqUt=>J0Wh~#;trszRZ_sx%zif%KkIO9a3 zcd`e2b%Sy0D$AbrHSe08egDvUpNCW|pFYk*-Ul~Cqy^foz6D^$8hziqZTa4|Skn+O3miyY>!6{m35cMsVsXK z{s*N9z{M|X3s%i0x{?O_OEdHgf3ppgNe-v~gTJC+?bZp6y zy?Z*PCwf0Z%UkYR_WGBnF4rtxJ;e}%Z{&W9L!%UV?GCU1J>N}adO=2e19>N;=H&IF zDBpIRLiePyN?u9;Bbg#vQANoe#714fHk6K%++NCS)$#WX8C<7z>vK=wVI7#O86tzZ zg5;#aajX>->+pn`CSH4^2A!{%?=QNoRCkWso^AbI7qDbxn`S~~;hP=H=EqLv+m!{D zj|+XRr2*2szkXvYyZC->^7FJ+D?mJ>B&fNBvMa?8pK5lxZH0tT-%a2IMT?4=<-c5yd8z95^;ftcIV4X>}}IDX51 zqiZ4~y?*Mb#U}dB{?}spzbWL}_f|o|-~ocbC4R=IudytE?o#MLKb7RO9J|A)m^rV? z?|Y)3E1RNwEIhc%akW($a;D9f8Vk=rC^MV7GC^XELt%-6o$b)AkY*vCJ8Q?cZ5EhJaRHfd{Pl#|q9ut4#k*8~N3 zu+3)^d&z8?Q+p(rH#X8hO;+C^B1nZ@9D;m835ex~jL|U$Is8$pQ6CnW3g-ecT_5b+Nk66`#JidUwMgXG)`E zJ;HYdX2im;)Gt_hCJ`-7?UR0GLRkR+ph(;&3NHg~Gmo6RJ{KFoP;?UY*0#e}d3j<# z!Sa2hIs16&B;>Q?$s;WLCX?&FG;`~n9SsvEx(qMRmF#gFnx3u4e>xh`ze~VYYtTXn zlL1G>Wss?iutN7#$~Byr`fP2B=USsIlTpTP&i#(W^U;H@b)(vbam74;n!1&biCTW2 ze-aw?m^|7AM)H1r?s{O0*m88)(r{$$Y61O5;P-7Ja9W_%1C@1clzHkV?(;!Q_zl{l zg9Ap!>f|dmKFzpIh3<9d6?Fg!w^@AT@o3kK`?E;wa;3uZ&(LJIMq%Yp)$N3#ZEwTk zdM~G^7D`SO`=(%6M?oUSe;m%L3)nmyXd1ZaPVm}=;zT`B^9fKxkv=A=Dh7oqy{+a- zhw$R&yroS5RQlP3Uqog7EA^i4<;H9e{LNi-9jX7#B`{Mea#8z!NcD+@m3$oG=lbx}N7h8T2-`k`MacBcHv`_iVlFH|Zu9hVN#-q1$Wy z1^jnK^-m+cM;!M=-vaoN{u%cxp6o0iN6m@88@a{ffoIN#JhTZ+si*A>1S@qd(4e3| zf^$TbQJNG5m{$L>#oO4h_)aaXQZQ^M3^ ziafF*WtFpDUxB)V!=K|4^Lui_V}=hm+fy8xNsluyb0A6vFb*aH3qpbwgpF{1bP}=C z=8c7xqC^2XA3dr08=^0dcbZpzrv5rxBQElEd0u3G(?3^M|8(!P+pFd*^lPO<-(}Rpxen#`IV7XQk2Va}dwc01%)l=*v*R&7RuH`-9O=d>T?Qb4$(Q+Rn^Sb zi@n1_#7#8EKv+T>8|^Vil>z|nb^v#1pIroZtNBqa4OSk`h=tZ1ugmDA6tNGL-5=8H zB0d_-$=zaEA=J6YvGOf4-dd?b@#SmWWp89Par?xFg#9-4!~ttD)X~K6UAx2Ozh@4P z^-tA~Ur5R;Acp|i1b^}M(*UFy4~m9jb5QFjb+o>}l$UEnS^J}ViO*ZM6~ae518wgn zHQXn#1B1!QER&6mLg*>Blw^VE`IC8h-L1%Tw(YXfQ=_ukvFMqbx>a8%=S@q*)|`Dn zWf2$%H*jMkRtSP-ue90N&!^AZ^YW_}(`9nKfd?+%Pt?IDzqj5x6IQ{QNl8XG* zUVS53q`}09-@d7hx9`t^T*5D`_cJvp8XcA9N>WM8HxqtHJOC-?8xYG;H)2r82Tw4u z{i$0^8;hdj8;OH)aq2>IC(BQs6c-nqbf?9V#!`gnv5cNSvxpiZa6VAAtm zSxb!=?|B--tnK{;q{2{>{rHWV&mzq^w58y(5p4)*8~Mm)k9d3&?KmUS>?D-!+75)U z-l3QxRzWCCYRzY3%#>~}+q->8#)1=v8|DrheS3o+3eTpG`PNe_ooBnquQuM}{4Ae4 zGnsP7%x;jfm=+A0Lj4c@L>0VDb5+|)7dxGEUC;Fa^&1kA{G))?g_GV)F`Ke9d7h-=PYBD>L8zsk0? z0jwxJGd?xY@WBCS_v;{s@Vb+r6ux_Pdxvkf2iNaqYg`?TY=4t_VwdYx`aIxawe3;m z1tPH4Wr_7cZra-nM7+-=OHd}|R`l-Jeegodv} zM9(TRepc(BPOt}iZTq;-V5|3z0;w6MBk!H9GmP@{`H6TPn*THbppzoO1}jMCdx%;z z?mDRA-(;3mZvOb;&^X@Xk|DXG+Zb_AVQwXGfAChbWSB6E4hQa@XL*OLsT6gzq}fW! z>%Q1|1&tbI(Jj{w@{%*UqE$h?bdkKg2#Q&WQ&8p-a}!a>h7+! zMZZ-kN*kiup14v|%nNY8dh4vf5F5>xWY~TlEocM=fyb|Ti^O0 zZ^%dYV;R^l&U|XTh&X$-62qWTZ$$s@oeCrR%qmgOZ&08D2cZ80*YbNbuf!6p8@uO%0&L^v z+vBWm%3RuAjktfi+I_uaPB%Vqt5%{o>#eKvnJp2i3RgF$W{Oq~SGnEyBX1c&sy2pU zw*bt_!d>1myEci&k#vZ%i~z(VR0!iS7=KDZ*tI-q(J%8U^~fwYhvLsc@M}8$C{DHc z66!A0K4RcXC3I%yqC zZ0b%=7BL#yIv8o0!Q9wbRcbx($@^92z~y-JO@~ETWlDv2`-4$cLcYPtD7}R0YNNiq zs4<;OzGLo~HR^JYcAt0Sf=4Y65_XMNzg}0+85hZ>qKQmokrqK#Kz+V{*9o>H@tU}h z_d|l~*PYrAlYzf-QgbpAy&KY&$HWXB!RkW9$qGzNwQZhiC-TGu-|3x zOgCO;BDR%cEuV~%NhJ>AbXnz$NxU_;cC_xK$9k$oOya<&FfMMjq5)(hbPk6xj|-JBADRSx$(vCTWNd1L!g zmJ#_tSKrPhc=EKUxkb5`A(j0ys4dNdcgK>#U;yoFMP%>{^KbrD1t3Y16|>JfY%<}I zv$T(uSNQg&vNA{VCV=U?01sZ!XGX>e&!akcHBG{Pf!bzhQ4>b)`WZVmH~nk#5zj;Z z#>nAF(9~iEtasYq9@I5p2YEMI$E-=~Yc0%^=}Z{v3B{Q8DPWa_ji46AL-$L7i>rf` ziGmfPRfA&}GL&M4dZ^ThPxS}NBquZ~E!uqq=VZdVD3*S6_{>x!ZDy8}lA8WmubF0H z29#cqNQK+qlm@60r=s%g>EaG|cwMo@Y1jp4y+t9oFmcN`Ib&7MaSXEvD9Sp8MGt{9 z-UMGBcHFxh9a@^$)ELJ zh4u>eZ|Jt!OtT3==YY+F%-O$U>rs*9md;!|AR`4<9|KdYC(Z{)nM(*}*XX4t9IrO7 zR7wvG%$ns-&C^bb_)Hv*6c>YKjc_`o19Yhzsufr_wbH<7F1NfA2W7dlt@mVLfXm z0Q;#~_;ag!!xfGG#j0N#VsyU~!cU$^%gutA_9n=bP~UsG0CSfU$^$JY=gv;E<>*{v zm*`j`m)UxF`1k(2h#w4Tvl!%)uU`s)Zok|BJO#WSdl^{bJE(QRHf}BDq(38k!74jz zh8*_pYJU9kQ@4h>MxVnLJ<)^xmc{dj5Wg%DN+P`oF5iG5{HTYj>t`B=wI&k_cdO^C zvn~B>!Y(G=L@S?83w@0vvGr`-C^K)p`~TYd@_4Ab@A3DHna3a*S;{^kDr+KQWKt$d zcBK$y3E7f0+e|4cyJU+No={QB7GdH^Btk0LW<-UuB>R%zeakF;e;-pfHk4rtQ zny4k?Y#R)rP)PWAiXjK70NkVPke#W_QQcQ4eB+?f6WLxcRn0%3(98yts#^0ann>Kr^ z@2Qg^zr>979vKwynqqk*ay@qI_WYYw=ih=W$0rwBm!^ZC*%LmczII(^t5B8rpzUWh zd;LzYx!H#7WIx#TmPD!ogZ%+N3J1?^dG`zFPdc3R*g=!y0L#Tw^C|x*HHB@*zb>c@ zqy&Ypv@~Z+YWqi}Z-T=bSEG`}p$ZUYJ&SSgI;QeqhDMU#Ug37`Y>+^i*!sYUKP%#{ z@-tji+2!5aY`avs$~pW&Q?Bj-BIq}lvIIv*5-6fziaICi3I{nT z9|caVp1tM^11*U?y<0N;lLyB%hZd_V_j?-Ic&wO5;!hGY1dGy!&mJ583D)-N@shXQ zWzoMH#sgt5UrYqJ$;Vx&Sw3}oyZ6~mTtI+_!Q%(gN-OqZrt?{!uZFU3 zFFsDTaGq@Z37&^)n|!}nL2;*o;)D0$xr-`o-!9lbr3x3rfnjrU*#7a$tIu)bZj(tj z5mex?5t6y-(BYV}$2mU6XM^^hy)?cUMxEt3?UhmKKYm3dWAWgvhdE$nNVyVr@RY^D zr(3B>&Za&y>m|Nrd^ZHQr|{c?bZZ%BUqyOT>eMo-<+^9UMcK!Zuot1MQTeiJqn~z{ z+*^27K&cAaE1+Z8BU@Mh`}2!&y93JCJ`)@O9sj>-6o-f+TKcEF)zPfd2=t$YJbBUw z1=#lX#pdnw_5c!ymJxtf=M(xziUK&#@NUvik_D3sOkwz!&qACH8wou1$oPUO--mkx zf`he)>GH5lt~HhfNv!CmU&+7CP!X$ySw?1N(sffk1O3EAya952z3v3Qqs1 zNbW+C9*}y~h8%%b(7&EQP-7?>=!U8R#=@yIv;aKV8jPkxz=6+kq6iv4PCXXCn+38NC4e(t_H}Z8k}7>1pxZIN ziT!6$l+bLWdM0j#0)XddBD4NulCo#3Nid3JPWr!nk-Y&Wz-6uIc^}yS`wuOEFT*2< zCTagaFfiF)EN3q3$|M@d7mMXp$c0{(D|x}`6zCGyI~NAbj|+&^ zKE^UM6M&eF#!wCm5l)c1q@bd)=35}&5d)}qGGYJ2S5eXDEMH4AMGp>HksKHlhB%?w zY6J+eWuRb-C6-qf&RVvH%u%imqs23E5Rk!z7y`(GKyNaJ)i@6AudkGHcmkiTtTmv#M3%e@ zD@1tz)FO2-M`W{wq6QTTdnSTqb*-v*C8f=rbT|E3?}gRqc>3q(gwf)f8UEXO`(Mc( zy1?uY?1XOncNrsSGi8W*7MkkeG!0Y=6d<=-&$f6>vZC@owFDesX-=>Trx7_DP3qyL z@QoRvo-jE`pa>wdFatv|6zPF3H;O=7(rSv6HR)C4*LXe^KB`Aa)IpQDs3=yBij(X3 z!T^h+cc-z=1hhFM?%t(qJM_iq6aXa747zVzEm4HlZ$v4| zZ1!Uo0JkgbFRJkp&qk;yzoj|(4WkKI|Eee)2OuyxO^`sS2{I6k7*2oZht9gLH%z|H!~ob{EfzIK2rQLThy@m$6EHJBEE9=~MN-HP zhY!*L0g#*g?k)InlIA|NGVleZYdr`;U;?CBC2e4I4Izokxscv}LZ;2Fe~sk;M}xH8 zy@f~#zgVc@kl*%;bs`hMd513F;57azr6_61fs3TMk-c-b-YMo>4J^4jY4EW$cHYl40RRNq)uKFT=w!sD%+`ODm{5V-iJ=@-ZnbCk5k$5^gJFo~ zuJ@H}N`J}27*Zuor(e)M@{}h?z+!iAszY1uGuVPLMnFD~7S4KeD+kJ3iQii_`b+XJ z#HCv)^Ew;)4LC`nQV;v7Zr4Tcup&SZL!{NKd!rw_cTDi>sJzf0v&a=%4IHJ99!61E zDQW&6aqf-KlYI-Me`Y>AF**lmv|7?~-pwTmLaxhx%~#5q`~cdCASW3O7$1kE{gqFd zi?}4GuriyVgGi$^saE&DGT?$fDP&%RxCefUuz>dEb8$yftq|Vrb?g;e4&mu20dWAc zb`eL21DfDwETz&i8U-gVp%(*>UdItdzPY45!g3Hkfw(|PDy1m>)iV$I$i;POlv`76 zRtTKd>2*4;TuX3fJ_b*xur50vwrMPFh0KCQOq+#0KsY9&5E%Cd5oyIu9aTk<5@41$ zD4&k6@9LkWBLJgfpHDLEavJID%>JnmqEOr~f4d$x4|0Vui2s3ePTh6(5u`ut`Cn=A zF0u1}O%VT}9V--*{B^{C3qZuww%>+2#~t`s@B>dJQq*mEe&ssoa6xr00XK9`^UuHA z(#-%5IwGYZeMV{wKQ0H)*+T#2Y*JX9`zT}mmp17l((;;odut-8Xp-v3u$*uYI3R%u zWGg?$@vgW&BEF9rWppH!-IldA0px_yOSw`(jlRKJ6iwWW0kc#Q-BJbDf^UHmm%G<9-dwHt3ZD;GebeNS* z;Ak#O-(k=$I!}5fgJ+N*=W3bWvgvF1_tlJ83@kVE$2SJyo`zqMrXUG34VpR;9IdQ2 z9%fDnJ2!}*K;m}1(;w~+*Z)7wdE;H58Md&6piV&g?3wkbPOc25Appqu33)jEhI&4v z|NV?~z%H$j)kKR7X{bRv>MFjQq(~gz4&`M0ID{O(rp+h>9HU5+?-?~@9EWnIcP473 z@oP0R5C?=N;E>gED~sqSb!{G?jy~6?6mgHsr&(A4vP#^}msmMO+RG1#qD*#CRs*ir zU{H7wyZLhAVi8dMM4cTGyN=D6rF#=8Y>za)97(zexz(qxCKFzhA`NM5&#RSoqBr0? z)@J#I2J5UtfRKBQYc4868W=3ay9h)UFp%DhK`sBRnG*9w;5<;amry4uh0H=sIgt{5 zrA!D-5=FUu>Q)<(W|;~}0!WoF>ref>CB>Uz3h6s&7pma<4+wt&FA6fCV^X)_l04FU zGJYxpg1emY-Q+>U7sChhj4HC221o0AJ zy24Z9asq)B^738O%Tx|xK?OoOgDTcC-7?y5A7?!+T}dqcKm#YlQT7W>{H1t@BjX4woIH}@9Vbb#CkM8IF%M|@ytqo( zEP@wiTDacnB*QExP6fWqfHibzxkGY5HAe!@AY zp>ubD^D09Q+~sh5&S|?Mf8WW0;#IpcU5mv<7kpQcLrecD;2p}4hI*vRjvK>gqdqR<6~jx=B;TwL)FGe7vwJ7t5I(xG0j#zw zMTT+j_gvoyC7zhsLR^4KT-)LNOY|D)91Yj4Wa?i_9N~u&b3}*r8%(m~#aQ(Bb|lI0 zveQBLmvwiMILQwI1s6lUvFH%klgnqWv$lX5HZ5Mw>MqB1dW`!|GWJkCiZl=ovy00( zvZxS>PcW8nakTq769BPpj}8)KC@S2gV<%k^IM;w@4Go%aE2f57&9O^JmFZ-T$N%y? z;DQXQUs)2n-^uHN7v7lM(N)4Fok&|azTA2n!d}=@wrTkOMncK)tlvy|>ygG?3wxb& z^kSqqnvnWxC_FA9F&lx|%pe6=XiG_kzKc|k2Dp~s-Z@cxLOq4L$v{j^c{7Tow>Nz8 z+X@YRohlx@+LwVOXgF$jyjXFNE^ga*c`FkqEao^trcCAK`{Cb5H3gtrkz|*3^98&a z8;VuASvxHO^5*3uXKs@zo-P3C@<|!;#SBSjUXOy0`_^QO41uLV?rC^hkJ}99*ZHdS zOBNzVjs6Z}1H@r*F$XCbMor*Ts^~rRbR|&C*z;ovgl&DIT`f$b%p`SB!kJj;#@^J1 z_+P(EmVT_nC)T4$C@WL$i3@sY^GJ~V0naZ5M( zxop$N_dQ$jEM^Ab0OHuV-I1jZ*XCP%$;C>L^kDiyhqj&dg_mTBZ{?T*hZ&N@%`PNY zhPpoO3*RU2zZDpCUNJ>edJf;GF1OQIw~-I|U4qlwz6l;4n-2D2&)|n56Rqaci-vV% z--1jVbO{Eo4aafc@!78|?`wIug_nYvym4AW_xe=l`B6bhgG;INssf_xA$GbB&LXsuH3F9V&FMBV!_`){@f5e7% zkldg_WnXb!_Q-s`%mwu;ee#r_vs2`FJS~zyV@P~2deC=;JS+6m!#D0}(VQq)CllX0 z)hFtRXnj??p;W`dJ)AfB!^Idd*@N7CRP##hn`V&cgrh5g9m3f9kNrMd8naiyz0fWCT2K$az_^NmUVPz2PvQ}k+69>8X7O5eu?wZ+R_{BoZZ`aJ_v=gDMY zp@2)@%Ygctc*;#j=U@4XD8B*?QsP2f04mj@i`^&&*Bn{h2E~wslVKQa@)ypGvjKTGaATYQB zT8wqAwZ389e-tV~>k(roerO4sl<%-Inqfk1HODN%<>9Yz7GLhmlMBg}jj*%sp!Eo`>J?}bqe9Y^V zXoz)Zp2fDN5-fIRPh+#2y`}!GJQ<-@s#fE*pM<>4dz%ubkjplD%-KD|^~Z603-NXC zcBM?KD^Ct9bUKFzP(dWWihK8HWTXM;O=hq7N07du`1GZsGk3;~kpBk9E^g6b@~Fq&3Nr{yRUHdq9=p1mylWB*~fyjgN{<8?Y=IX zUf~2eI#z(wxy!_nynN-WVXB@|#FtS+h2*c4~5S4$808EQP@5_s3p zEyXz!A59$b41ZLyQG063x#doNK)f4+DF!w8em7h8Dn1Z~u9_Ni&+M3) zH3z@Ym&ilN-O2i6RyLMqi_5gOaUZFj;%hohgAmUWZuA%*-IJ@cpxrlXW7NA_^<&%( zgYd-hAjjuy?OV{{;DUF_)Q7su4AL*b$qHL03%z$DT0R?Jyd(R>+0<|JBl!F8%>Zd? zsGViC()gY6_thnbt0HTf_`G6H28M#qCB}o`v94O{#s6mQ#$ssI>LNn$Fcf*?)y6}4 z=EaW$UtYQ+E57eUO0a!n%D7+9hOxy&o`JZqIOST&b#L!H(x+yg{o*c4o!v_H(VSdv yO^R}n!q?CG4H-n>6AZ%f0quT`i*mPBS0oT~X2qo+@_8ZfW1wfWzfjly!v6#HRYH>h literal 0 HcmV?d00001 diff --git a/artwork/AppIcon_20x20.png b/artwork/AppIcon_20x20.png new file mode 100644 index 0000000000000000000000000000000000000000..bb10b4781521ad59fee41e0ea6ce75e4111a4480 GIT binary patch literal 621 zcmV-z0+RiSP)Px%CrLy>R5%f1WB`KyTS7t^7#M4TEH#Gz4D28=q5&hrPoUmgK)ub3K5JGpf(`r6 zxB@7^M6@AT6*B%~VEi8eGz9E23Jn9<0CEsxEeqJ2KN&%? zyYCs!-g(a;2Xu+Kx)6hw93M_iIK%GpgO3bO)rT0k*qIruG=v$9lmr>X1lSp-Z@bGd zfA<5@41D_bJ45^G8w@MU%^5921)|xYTAAd6Z`1KbFUxxanSAj7u!5}Wk z0TYJPSQEAcP~n*g&J5k_ZZfzVNih8V_n+bI=U>2>ea1BFG@X&B~DIs(|bmOg7Lg zU>Jf5M`{7aThuRLLB%$xq-9`aybSg}sg4B&8CdWC2#{F-Gq$xd_aVfH00000NkvXX Hu0mjfIM@w~ literal 0 HcmV?d00001 diff --git a/artwork/AppIcon_29x29.png b/artwork/AppIcon_29x29.png new file mode 100644 index 0000000000000000000000000000000000000000..762af5c7fc914652cf3b063dfb2d35da302b4987 GIT binary patch literal 21328 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 O{IHN-!P^6ePyQdpuy9QP literal 0 HcmV?d00001 diff --git a/artwork/AppIcon_60x60.png b/artwork/AppIcon_60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..bb46ae75035fa88df1057e17dd3d55b2a9c19276 GIT binary patch literal 1597 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 literal 0 HcmV?d00001 diff --git a/artwork/AppIcon_iPadPro@2x.png b/artwork/AppIcon_iPadPro@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9a8cfcfbd8586914ceb8b231343524039c2200a3 GIT binary patch literal 129434 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 literal 0 HcmV?d00001 diff --git a/artwork/ZeroTierIcon-WithBorder.png b/artwork/ZeroTierIcon-WithBorder.png new file mode 100644 index 0000000000000000000000000000000000000000..b7f06d76ebfcbf835a0ee57f699590b1ce887f42 GIT binary patch literal 29866 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 literal 0 HcmV?d00001 diff --git a/artwork/ZeroTierIcon.icns b/artwork/ZeroTierIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..17e60d587da5167203d579a4468f4612fc403cbd GIT binary patch literal 125598 zcmeFa1zc52*FQd|X;4B%5o|2P2C>B!MM3IxAP9=xb?8R1K#;PfPSA}V*K2ooD_FqE z{a^b4f_m?L?(@9wbNzpQuXC@k_sn;C&6>5=tl7-x2P{K`*QxWD4IYFLaT8gtl*zDQ zL{np!5|hbP;h3K4(-#b@yLIQz&3kum3GbkWKurHtQfhKuP?R`1HKi8AgeoCMeJG56 zhNSkW=;-fqpS65Cme6`#PK zCTm{h*xsX9(QzzKg2@9_I!f$=@P5h3OJOo~uu5Bry*aROdDaI^8KR;oPm|I4p#(5Ri+1&iSgG0|LpRh=!$&-C3vd1d|AwI z!l-kB8_LB&QtkX~dP;E2Hnub`SgI{4JiNkb&g$F(Nr;pt$vYv8J}#AnNhy-NeFyR+ z5mJ(*un>OXT_AH<94>wtA4L_({4u{F*dIlr1rXS1f z7WyMZ&_V>%D!_|&kT^RB580XG6(oehFa_2Wlvn^lVyr>g6zZ`QghW8KO+kUBA|z@3 zp8mi8{(XJlwg(jN{u)#&bv!IaZM9kfSXf36 zLLQMGK7aZU|5c|}3gto-S&n7)9T{X#wj0^C_sC#-@`%9~F-52fDS{hl^|hG)F6={n za060?!=ehpVEHMqfD}v#OAU)u1uAvr*u5oFEv%hF-@{^6#;Ek=SgiHNM}nAZKE3lW zd7R2nj;*(Quf`UoV%U`~*_b>=)drTWZ3Ffh3)l@muJ?L`DWg?wl-R@~;5T@rydDen z!(>q^V+D3~ET&X7#wxJ~BO5Sfq{>*19cE#&rf8K4n{cx!I?bmgT8T}$fGITSLKh5} zfu?Acx_-Plojkr9x zOJQ+V^~`|Etg77|Gm0e9(l(OPfuWTm(UF+})#99E-04R|QPQ@OlASh%5@}K7cC`7G!HP5>5^?yR2%^_i(nHG zB7#)1T}qZnV48t{usIx7JX4RwV6fnY$z;(P4B#IgEEbc^Vj~ul)q@WJBAd$;vPiBh zHhTwCo9E4OV{v(aj%VZB1B1OD46_Y`H?b|7<0a@bg6}1m zW9Z6eL_;Lkd=j6|@a{80z@X0?Z0*g6Vzy;)W_Ey%HpVj9uI(7CD5f!kKf1es(HzTU zo6q7fA|YDfVBHeU;B=b7h3K{n{sb$23!2g1g$>oQ-ORjT!_-vA;7&K^Xxbp?ImpLL z6G^Afv$7LFYYo^QhEsg#{N5w@jQK;`bMP+lW*FG97WN;r(5tVp2OD~+&)~UsHnZ)} zrJu1igTvT@Z?$|UJ5!61F5WE0R@g!r?1eUC7qA#RnH0L9mmQxT#U#Q+gu{-?8#$TF zfCrcb7LOmnBr-VcNG27sxUxCy2$+IMrZ!gq)5v7s60m^+I3wvWiyW9!=vN#fc>)Cp zS->dRTrLm*1^SONSE3$Q6_QkQt9qs}#Kuk&OIXw%l)V zDr_tw{bl;Zzf4zRlmA8flwaw8F}|=P|Nne^{(62@*k98}6Mea2ur>cdXr#|SrEieu zGVm1w>*MSnua8W8ec)R;o^$Cc-Sl{z~aS2pEK#E8Wcb?0V zRAl9sy82I{h$aJ3MEw@S5|9uhfefk)MpRgdAaBteejDuqU(j4HrXiWoc|#9293 zWU9UJNL}BRb(z!A=tr15LPdr)BLrft91BB&k1%pjiyXT;fCgG@I5b!Z$&o5kIkpq+ z2g$Sn>$e{J0>s3oUdI$+O@IhhI|X(Q#e?FbQs4-g3gk-1-g31v^ecp-#D-18WcW}v zLIC-8@+jp4H`iF3Zzo{;GkYTf@wN#}k zM`66{`*IxJTgrjvD6j$ktsp=Km}THM2pP7h7Y3Bqx>MKDQG5n8y{0O#vj`@n^|&-( z%R8#oKnjg>q?v-TBf#{aYMufW2>+z`mhsg`V`Whv-G`#m{!yBiDDhw$eC=`PjU1hCi zv45!t%8dhC4PJz@K?W>Ah=h<27)UbCH54^MWneRNsZUl>YjB-c*${+i8bufs#3m-B zP=+DW$EOeFkPkH8w^AfUL`in;ZfT$-6tw+7DKV!sF98vy(!4;hp9F*2k}M^NLG=kl z`=v-E#N}p*_=H0K<`zMHS-_6=z4fTELFT6tubmEIlxukR~aNUA`uKHD%RClMz8H!&j5n ztVk<_RzPa7lqe~wjHsZLo#@K^tu&&7SXn3uZdBTkBuuO$$`R!s>%urK&dmuIBQOy` zrdZG@@~TR9N12V@; znzMQ+>X%U_0#yRI5w0+?(d6tSB~@0QCrhh$bfv_UgLVaJky2Apr9WDJEI(INYUNR# zBPuN)PfjWkhc#mGa8$yVfZELS3xlv#Nk0sShk!qy@W6v;+CBm!($rM(7L!8jW< zA*ABMLlkb6C<3n{TuK#}MWbz{Vj&@834Adkk>pJsD3k0UVs6D+})ZA84^{h^~Ij~h{ijz>(*UnJI zrCU&3S?l2-=N@q}$&bW48zF5cF0<)fA(j9sHV(K{RJ@1iTPX_tI^w3{;v@p|xJcX# z5fzm7>RA-t1klXtD&%vtP?QU^T9qv-FB+!1r&z410q8+gxd7SkJ5qMU%IkD_Riv4I zLRlj{XsBqjIbqDYy%x@U{H&2fW@#f8;dED8w9J}K(A);K>lGeSfG3FW>P`x+5mbs2tWcpsBh^^T`<6M z<}60YiN$8^Wor8_;J6^<<2simWFl5FXyu@Eg9^I@Ar6>mA<{G2o#5sc?T+X|rXkDI zgNG24!2l(f-yM-7Ndy`-lB7#UV?bwRa{QRUO+cfcHY#!qdAy#L~I=Afrffs|z>qc_MwQxv{fK;v%8a59M4h&w~ z0p6gyGWi{hK%>{BQW#uQa{-vJ4VqG!V0R`B7BC|4^l(s!xl<9?B!qaI@$5n-iS9i> zTaz8vqXpJ&cwor>no4DG<`5?F7$IQVV8A%y7;c-s-t@1SASRh(U?TwKTT=st#n5u# zw-kZn1RbqfrF&6fTE1r2q+4}rmCn!t>&3U}9lNxoL%Vx_SG~Ti;F|^t`WWHX_|~16 zO_;)KZXyiAbOhtwY7oeD?|!iWgYjq@WCn|C zYQk=rzR_ryHyfWm8!*Q3*cQ~exNQZ7M>FyE$kNT5=iS!Um&c!?uQjV_;x*(l-H_0A z+}t*OThw14$H`)if{~Y3M7KsRwhs(1AF1lbz`|r z<0UhxzAW5o#sgu6&1ADZ!?H&J%a}2J5}nIofwbbYd=)2|Ndg<&LMigqSY5O=R+n#$ zDSz*cKp_5kAP`_!S_k4+6He>cR?h@->l|Ru(e2pLqO+x?RdcX}&>4b-MW;?3&CRH- zbxjiLp8le)uD(Hr2f1AH3w|^}sIRZDtNZfl?h5T@B^8m-^e=y;=eE|I!G7McDFYGp z|BT7ie;q(0JWguNK!l^8uSZ3#%l!6Pj`@H|3D>$i{ma(iIh9yBuB5|1Yt_GMJ&uPS zXvP=tV4=ce{yM0zJDLt?@P7@}q^hucWW2-wJ^X#jzgPZ)U--Y6Hx>44eEwp1V7>er zpPxHE|L%JKAMl@lk01V<{Py4D=fFV!t^ESu;0!2{I7NZ6?UO{zXKyJ z>ayo~%@^2F|1i|meR_9yP0M}?djJ7xnV5I%)XCxxLZ^-$JG3FU-mf9Uzb6mCMg}6q zpUNAM)>?YdY3K%D<6X$ z@pHYR1`gw%K?|Sacy-;S80gn4gvs&um#=Hz#UfJ8``6$Ua1kuBWMxf#{gD_%x}sDy zM1cMJ0v4enLF;bCAR?IBB2+~6n?}mvLly#!Wsu2K)LW&FYEGGfNPCbFWQq(#CZe8SQ9sq~ZzSyQR?3Z)3j$X2ygfEf{XkESL-|7D77NI47+7BZy})BAk0;^2BJ3Hcl- zzFI59h$@-#Fr*&@+a(xgvAc=R7F4i8lJtOv$?YdbUj}v~R~`h&0gcu4W7;^7(g_p_ zi6A8D6NnTFh=JrGu`j`VdjL@TaQ_ahVW%Zvpdc-xkp+cBG&dm$kv5r1Ky5eHz_GzT zK<-s_hqHv@eu$(EM>#{+iGF{38wRfA%f-U5ak>a;QBbEewOXDIGpYjo9#uOT_L_l+ z+COJO2n}QYriSLF{ z#haF<0uLY|qG_S=cOX}At4zTvJvf$l%Rp3Z#DFZxO<7V^x-x7F(xRdbm|CU`X_X~Z zr32NZXhAFdFtF%0){z3SSPmSq5Yxe89o7mTrqTgIsBS~hM&THoR5jvvLo9a5fJj5> za6}T`3XglxV8?VwRPY*;?`nc40|BVN3_?2KTGkNR3LS}~vk?`U-NzJ(U(s4}Yzfju zY)l^23JlK;aHyk$rnO*`a37sxL@Mh4QLStZj>a?20&of@PiQJQNu{O4#v&>S4k9$^ zO)DfC$O?Phj)1J*W6GUP;9X#a$8wQ23czGBty%%kGOpioTK3ai8>AY!{`n6foC z4vy@GAk+n1DR(p#n}`?n8w?y6`eR!a3(sId7@Q!q&PIvLUZdY(71&9L-;c>! zVPzPwU|pD;@32aBeNTkuwZ_uqm={9BFy-b}P1uYdfq|uGFxK4IMDVz>1$!JO`xXaH z-HJ$UUt-E_O-fa8^xA<#Tuhj?(5`v!Xk z@}K+xtHfRyl28UFYlW3#)qn*zx9`eTV(+1CiQi$X5QPBleLrH`6VcA^u*Vwv@B{XZ zF%iL8UaL01Vk1xx914DiRbUUmFq!pT-yZ3a(cT}%3_o(C;2T1#a+O$J7lhzk^1E{7 z*g-_00qHek6M&Mj@i>Kj-vk-98X>DMEz<_nD8rT^Wcdj{sA@eGP{cTduijP!CdWiT zbVqPE#ug|%E3wChWPFV!z+%7&9D89*Ld$<3S{arG`A=!e)UZp<0&_;FC%9j>UO1Za zry|rB&TygrW~?0BkF-z@CU1?^JYS+x@kQEd;VQA3&IpaiT@zc{3eRwai>TDgngyvT z7kGyZTMLUh7x%?%!D^l_0e_#3DOz|39PB+YfoVv1(o2rOET9f$KYlN*@) zI~J|LY6n1P(s0hy%>T7zSR~Zf_YHpN-cmNOe}z&t9a_k1VgD&Of2Bj*$PbvT^=1*S z(t%x?2`P48)XL`FA_WdHRdu5vcJM2=t6CtH3SBA7C%D|-nW2$HOc{rssaxc&xA}e` z`9MKK!N*^*2hjUe-Q;Ra(hm_pUPK0i=d4(-MMVA^-0e+3^PqvjZI=R0(Dwp#KWy0w ztRZbM$X--(AV^_|AVjcH!+VdYT1+Y552%AG8k}A$Pp#+=5C8xu5J<3_Pf0xtEH0@X zR&@XY0#ja23~(B10SB?|22Szaa;gC&CYkaO0J2m>xeV?qXsNNgAPtq^5)?@-lPfbJ zF&EsPg)-eH5fZGJa%B!ggS@KL$WE32nY{Wxk#}>OWOiJ@&(#ou0S#4Sa){SR_!?y( zN0R`;De%vnMwOsRbI8V29Oa z^!XF$QJ+46n}7^gtsvKz`nnxR`{RdNIqnpoQeVXV)m7jVpa64m0@C_&BNaS{8otOb z0(Ysamn#(?KYrPTa3zkc`tLQC%as9gRS6DT;Up8Be2L;b$up=9KM+Nz5MqmR zKp&KfBCzLD5;Q^@3x!C;5z>pADx-hRXw%iU;_mG7ITu&rYQ0GYKNK*=Ub2jUVV0Y-) zRF0%*`CNLMmzF1EHt1Rt*`8@$M7p~Vo(h#pN~_WfDEza2kP7AQ^zzw4)4PwH};JEwWe-}yhBodLP%#h+-u|x!AWP@in96cA8 z9@RAAR7r7xSR~1Yl*7{Y5|N~+vMehxbfpJ{gr=?t+;OO+szfT19ES8mQY}$_WpR?f zy(y(xO(eA$$lF#>Ss()U5l|DsBSTu5y=VXpm=n24O(bd5L{bm_zN&oD0YL4;J-y4N z^UZJ!t|sc4l1W5kLyek9As_?K%u0!PA0YQiyNe3S1Fe8pg3n-2_w`#2?1Iq<&e|X(%$0A5EDeBAd3~!s$!`~EGkR|d{`+w!6+1k^g$#oq`jy@DoKY7>2Qu;F^@ph zLON_oCBTKPCI@%z5J}35mKfu0npvDDNrNnD;Nf231(F)FNv_Hh1-Hr&EY%ZBDi4jr z6UP-x;Yc26AF`xMbwpJ@py?rx;^N%URyjf;rJy2!3JsWE{uQ4Bv6br(g-l#hEdi&L z7J3Pj>PSS@k$MCg;#7)~n#$iT)fSiR)B%lb>5<%sR`3X^c5YQP4HUzT6{1~D=wz6w zJaIRWQ8?A2$X4h`91YbH4AY9liC@uLqRQDIiA<;vN3{aOv#6R4V%*STaN}?6XA-od zG=@M$R-$}KYjCtwOI&IP;3bvd{ND_QZrLCzF$VY8Y3X7#6jHR;h=|%{=1X=qfp6Q$I=t_V%76n%?>7WyKR{@y~ka?v<1 zJE5F{14dv_`T;903jylbQX+1REl#A65nTQIu3SlR0>p1BZ;i!!Nk-A7KVS>@>XFdW z3Q?A#qv7_v0%rjROr3Sbb}3eolJ=^89gpE5L9-O)CC6 z7cjk&k^w+iKQuv9>4pgHa_|+>L@;yU9mxATf{_&4AT+d8+)RJv>w(T9%f6>mNnr-) zuWWpEYKoH-?uF5C`GHPF6-yw0Y-4$eKzwEP2z3(WwXPKwhq!bo=%SLm<~3BY64uoE za&hZ51kd8)ouK@9REnB#lKf0F0vb^K&053PWaV^3q3kS%8$^vX3d>wn=>cVKsQ8{8 zh>H_|&pMQeTUZC&LfvBs`-dnGE*P~eC*Th_Q=$@LO22}W@PawO?dDW{$CR{ks}=#D z8D9=V+04Lzk4n11cx*s44*0 z!xnIeR9BQ&y`?jt^>>tsQURR?`)Tq1ZV0yANe5v+)%ct?3p+tlJ&~kB;z@z)ux+=N zgF_m=0rwFX<&MO6%(i|~5IIEPaoLWxZf-4H35sIbKe9$Qx^#@#g0M&vhEy#N!CFSSENa6HKEX|hYJ(Q9U7J%dv5AQkR zyn_2ua&{4@72808A>`%Vg^c+^sYab?Qf=TIO_H+@^bD!wGVWvwgDC`UCAWg?L6p8qvlq4=H%KcFn`!R+rnCHu5p960! z?|?;u08r8VXSfNxMvj{d#r8+Yox}5D!*L*&%jbJIEnXquoCBXq-!+RD<8E0@I1Zc_ zw2eJ?t~ZCxIuA}@Y&M7K#t2wA54^PI&G%#b`f#qm%|~$X;&2$=0&h4Cw25hs?Su%R-hqh)?j(U$ z(j3no)qh~REp1?5GKtV*(13JXg3WL|Ee4!RGx%D(d7i)zru*_T_=wjSzlWhkXU&1w zNnH9K@aKbNhkql$1!5-i7?S_sUCh*Bd@Yh8h7z)wLWUlE7Qq{@eTFai*$Elh5TD6x z$AGJqTuA~T1z&Y?RBp-r?u=t$W_Lh2Z7Ahp^0!t$4bR6Qu=Cc`x z0C0e*4~~ak4jsTlj7SDO4Nm@uxQjF3OozDfS&RdK+7HF>n0ET0(LpgWY`vAC?*`2}WIkrJK^CO$ujGN)^3=MYla+)xx0~KeFNY?>~ZZBZ>FniK@ z?%jaD5>T5#v)FtdhwF-u8K2GLb6o7;LKf#0Ea`@d=;W;#zO(i z=8qsl)z&;lDqvFp%O8heejK3OuvX=U!#Wg9p@HQA95zz`x*H<6vnU{Kj`XHSv_eKO zwdwq+WJnm#XYAG>wO9;e5IP14;39HM-{5jAT`(5JU~N|pBN>3nkjU=?z;1l-OKt(e zGhHwU;yZCQxFo#lsRS}=LuY*hjD}3y&Hw~w;3Q3fG3@VjY8aLJ1saG7t~%2OMV>#82RT#X*nAgsI$ba9hCre=f*BFaXWP z@g_s@aHYI;wE$zegW1`x6>QSqf^nxnrO?>#N@Kf2-{7WsbERA-SODO|-WsNP#`!P! zqBr9-tN|MPJr3_1&XsXo0yNf3pNIzh2m^v5lbt!uFb0q(PAA`%2J_G#5rI5g$ONML zYNEbJayo!^#QlayU}=!ilpl$Y?F!=zOQX5eM11H$s_XY7?eQHz3x`kH;DnF}v;&Kj zUt=9(r%$Wrj$88$d&@LDmPd#A1-!37|QnLm& zHj|@SYWM;d*uc`$e8!-qQhX6>h{}@pb%ATT(1yWky}9+_)+i0_kQuyPyOls1DmjYuYH&Bm`>v><^) zGT2^ipumxQI?f@1>Cy#5;N8fR12+R&kic}|rb{PiQV*Vn>89Y7bcJ^_FAhDt6%uFU zY!04c%3$G)9C$v1#cT%=#;*Ktczzh{23$JMPxat30gg?@zmMQy1Tos<`D}Vft8zmi zi7A+lr_p9M?j~t)S%BjPoS%q#xWmpC)CwL1X$(GN011psI!-(~zOAL>c)At7b?MkK z`5-x%!&Q=|%?j?G;1a@EBOrKW2De)9y)A=j4fi01!){7KZAZBCcx+~iI0Cz~*Vy*> zwoUBE;xIA*4_i6ZI@y&M@J!5jq0VVDgjm(Oyt>uq7GCnV|U7SJ* zxth7xq7Z?nLA*v1)`-kGngq~Xfm!A>3eHXPbq*|U51amdVSmj2DrPrI;<+Ga3k8Us z+ai(U0=tMQq>Gw_cCg#|u{@nMGCiM%%k&`hbGW=Fq2I{|&dgYI7z{3G1)RC=7!%IS z{FoV@bGf+Q@cRVN8*oix?IO3yxNgCYxAUFn17~LQ=K0XwH3|r4fU7r80B2@CetvK> zjRh2X5x5w9+KbC!3I%Xv<{k5d<-y_!xEJBti-6DeU@q|Yh9fhUkV9q){5SE>LshFs zAqGdt0-emqmB)uGE>@sC=|pXq#YMs1aAvlSH*YcbJT!9QD7$q(>R`(?*H*^<$JbWS zukdRGevQEYnMq;h^iUS^&C>TMc}I1;GF70lveBeOZc|!u~vv&?cxIJgxpa0bI5AlmFs|1-J%a z|CPQscL)4wa{l~^2MIiG|9hQpY=aye$Nz)~;W|#;zq(!1+>!tMw-R&tlLioQXR`mi z;J=wuh21qke?)^M|NV9T@Kf!d^8e%KUqAc&QTCJ1Uu8f0{P`!JzyECigP-kx@w5F;es=vo z+yCh2`d_KApX-07!v5I*?&ta+{(S$-pX-16v;A-30P3guAHyeOQ0YJ50R5-_*PxQy zHvAL*=dOR?{j1T2N%%L@|7({I8Z`?!{u%7=b?@eP__EH=ynlcj0fhhM`xkrv>iz|O zKW5IW|56Lo@aH4y7yb496Zmrk$aGshP@xk3gzEodfKRDnm@2Eszqo$`gaCJxy6t}R zU!cMdV)!uCpORiP3BvVe!06jdn#EeUdd=E(>o;x^1_lNN1qX+GAA(zjAJgFamFE5x zT)$eqm@{X};I^8+wbb+HPyh07s{DD@ze*wfjm|gaClE=0`1ig4{&li?$H!)2 zvl0B=sISFoGW@|inMNRd{T~w`_^#H3rQY1-iOmS}gKm2h36T%enFwzqdRunw>I9Nmo@85`+-A`PN*0&Z%ldnIo-@$*6HgWSyDDDWNNzx z?UEfg9-UYkHEezIyd81}`epg&r#-J)*;PFVveLbtw*1`qoebT>qoTqF&I`9W5dYB4 zg0xar=H@%xpw{epm$(JCi#M<m;Eb6UAE?Lpv0 zO)*p1-Lsdbq#2QBIlR)h$#U#k@V@=I2eW+_Pm-U_n!A~Cog-V3Gw=M;1efd)Q)_Le z`&W+lpZy>R={}~7G-Kc03iGupF6o(aH8<-)Qh!8nmWVZB5AgfH2TG)xe>$Cggnzvx7){VD{r&%nu*`GhN+S>8Tz~U2P1|rN!({R zA$siSN#3zH-c0z|rf%xewmqgee&BW7xO!8&q~8`^+%}lqr+5C-9sG(V{x2uGJh^d~ z@ti&Vyu(=ctZr>iFF2^%J;(94WA;h92Q~#B@4JI%%eRr-yrmmHits2jZO8PNvkGK; zKUD0$UbXkZrpd`KXQeE*Kj_%aCH6>WgOkZ`SuuNddHY;ALflA`G;|gYN$G#De)x@v z!SiKZq&5|K{JX*Dle2aWs-hQTlX#}9CSQF(S#~;o%^)=`0Mg5 z-mCgeN)&a}y*9AA+pKFTo3d`6cQVRdIzX7s`tsYRH!r@tp1Az6hkZyd&XcII?fU5b zKG4II9n(>;=(uF4+i!^{HfgbYsdmKITq|D_yLe^aIThM^!)85nou5QnH}Q#yviyu* zmy!4K9jel1BnY)t4dY2V8=@W;U0N4eqo4k%=3~*R+e<9xXOF((JS3&Bs%?*mJ*Ovq zh}!XdNYU>Gdpq7ex{dUlam8W6o9xP(jK2M5&X5S^+L~*5ZJT#e9X!58! zLT}{lDErTTOHMB|%v#vbd}yHDZ-ed2a^151repWkFseQJo}(tx-@RUP_j&q>2fO;q zww`)81c)c!G5n~WZZFSe-gEDUF`rCSTSV;ZDOgx{{tRcD&Gb7&`;JrgkqWgI2uDU- zy5V_!SXzYamPub*ZQkv{zq71a^AB2Zgk8k?jhMz(AcH zmqq4p7iFYWM{u6xU!Ty^L#KP#^C?p zzYiMh@3(vN;jMhqk|{a?;~3e7^Kz?(5(n($SU4m(Zrk{@hMl$eqPZNS|2D_%-kz6L zz1zKVPS{R4Yq|mrq&sz=aM8MVNzkS9;MZH zW<$K`)tNq*bz(}aGG^6vtMXqr#kb3{cX^k8H@~LNX~XE#!RSDATFJn(H?CdYJ}K<> z)~DUCSTOCfu4S(A?|fodM%OoNdTA2t_n@@EZTv}k?JH{|){NQo%)I2`zC789=ljFw zA9Z@=IzoG8ig%Hg1IA~4JeWB3T>VkQwI2$Hw>86h94XvftSHmVj_k^CE6%xLr?ct? z;kGI(n>gT|tL6G7eKyANJ_nU`T{?Q0(7Q{ab@Js7XYG>z1t*uI#3&DVaYS*OD7M|7g- zU)=5#>TW5>SkIn5$)`JIvcs7~v)gC9hE3c%(5RQFbjLE^p(0kh5x2vNm!S=9Cw%B> z6FJ=~)`b{QQJc4LRD}9v=LI@0KFfuZLn{Ri>~Y$Y*3a_eG2N|XP<)Pnh1%@x`e-Gfv%^Hu+)g zx062O_JgP6W&EQL{ErOE8N8-y!6?fkW;Lj{*b$qS9-8h%%g!e9bho}=)=}(*T(IT_$j39$h^GSD1B#Q=*oT$iNwQk(R1LsV} ztSZkOWnmWPBi_80dUW5yusQcLr*2%AU~@H-uXuq`+N|q*{oK{agctrXn_6afmh*?S zwkKk14|kt=b=J{o+mD6!e>d@2mNp~ctt+j^!U2|(1Lj>0h`0oQ3!SH)leso=(r4!> z%rEb)bVr<)$s&C2b@rZ^czVaPT{Ww-kBqS$a`#h_mQBAE+aK)Fp4I!{g+7CiIMi=H zOuBL-{mQ4?4HjoRuWKjiyy9qY?P0OhU|ZEhUYh#&&`FFwN2*%QVtI_oLT!@)yFc5E z%OIPMyhMK@f3mn^>dj+!7yHD1?$lwa(TMnj>^C&Pz0KRr0qA9}WaF3_N$M$424xdxrLMFh>TPz7n=gIe*(FLktW{J{FRD_-c{7(dT^&4-66 zX}=GixMQyG=aP8+b@dao6G4%jFFhE}!atR5EX`)qVZ7 zQ5TM}4d?dPDtnhbO8bC|Ud_9kYVZ3w5ytNpZY6~p2fzQ_$^UTOja=E*lDdN*Ek<_? z8FjBsWc}-FUK{RDEwo+Sb671m|5jw0S#8++4?Z2ZT^@g~-PAFE({(#1d++K8FB3cH zxr@$B7~1ATi2huRN1w1@b>y{~$GzK5HdP!ux73C~Eok5F!ZDuc0{2Pn727!9=N3670 zjl6VYTv}Hj@}%tzrzcia>z`b3>qAC|@XtBwx~J)PXe-X&yc?JKRIlLrN>n;1Bz$a` zo<-1-=!EC*53i(fSFE50`+4m4tw z&xrD4pVA~3{XU%3di^YZ7a}>a$A+TXvVc^2Hu%;)CFg3rD;f z@Ww{2IGdAev8urQ!APaawdi$oUH6ZA+=J$9_{gdK;hGf_GJ88%ZWv=WJN7({-gAd8 z!F{#PtQ9`zXI{U*K^Bw|zl8qmm`SJsYr!n~u(ebBvl5SuAx^vSpkyU=wOl7I z!sCeS<>;Cu-`@hR7au-IJAKR~ZO!f@c@*KkJR;YAwmv z3mOt_usUX9(p=i3^}n?Zxf!X=cVCg%?ZJY#(c0JFuf*0QsGT34Fy}K$92n_sxSfV3 zN$+=d-QG~pW7X!^pw|x8_b9;zD=m8PV~uRDZFuukul=(7%QtoJ+DUudwgXSfGZqcq zzNlltDm`+CkhjD4rS%zSo}ZIGsofI)M<-bC6LQ`6_j|PI$Xiysp}RX*yfiz*d)B^J zA7h`TkxMw#eql#y_q~_rgmTXa-Y2g9xT=@m+c>>Zch1l6y6H*GDWsTf1~^QCDNP4aLr{?d^JTUOgHz`6NBQ z$nN!|Elcmxv+14NgjE$sJNY}R!c=?prY)^h{f2s9v1HC|Us4vsoao#qv+mBDr22`Q zwv3&X*nX1Z+BS>)vinU^ys?(1U)b*(bLhZc&o}n_Cy0|@ST8qDio01~b0WAbV@>3x zT}3N>J>Epz%R+&(_|n?w^^dnt#5_z=|h{YWfg?qF`lx!sh-Pw>?ij zoA`DlbF#x`SBE}{7tNnhZmPRZ8lEz(pkKF-%haXQ^j!;jT(rpk(j?#3@uTtE0oN03gZmdxe?sjxZRlGv#k>0zpFvdnYp3nzPS(l#EE?q> ztXlQNQ+@7GX_Bfa`$~FZ`n3K%bI!=`S}is>cP`NUn1z!A-E)gbSMkYtN8rL!tCQ2U zlveGAZR>iMP`)o?wY|Ew{}#FQedZD?y)Of35uO8XYR#{EV>+$cGU^7`FxPhZ;#)Ce zZd9&5K52aY2kDISQP*7uM`U*$%=cNL-n6azlP5KwuC6-ab@It^N57Lt7f-?L@89wC z**W%o+@k!ak8Q$w(?dLm-W>3nTyc5r&VHZd%fmNn6_M7xJ75{NUT5F-+a{b_M)y~r z%GMcojdnJ+e`&ycBW29V`w3M#OJxm2pVAOV-ObW%B=v!7ZOf{8kBk=4+PtdGQTi^{ zpZzR<^1eH@gNMu$Z4Vsra1vQnfu3A%oAFZMap%VD`B4_pz2}d4Jz&y=_#-Kd0k==R zC+!G3)g|QEc#(5>XvsWpX~Bcw)B>)10Lkd-jXZs-v;PO9jK%dhHR+f&+AbW zUvobonOy~pphyUX(DJ`a0*e({VqeXUCVc%P@t zsI%+1J4qM9W)0={+;gVR{otuPhiBKl5{$lcH_pvOB3gX;vVFuVN9zU8&W;K0`MG2# z=|J?*uzSjg6}~6BF1pn|_F5!o_?j%Mx>LK)U32^>>bg0@=eP9Bl}DHEwjFoTM&wHv ztJ)K^&HUEWBYv1xUf~q$+8sJQGd7y!tEWG#VY$@M$DUs~tSevos&w7hXB~HbUT|m} z)?YGfW%XJgHD2){hQp-L&KE+ypb|YF2v|4Sn*Gf)xlAZAO9Q+}` z)7$oy3DLN7(v;MTZrkpe(De9ABIX(ux~F_8o|d^F-LS7E+5^p zYjSYk&#FFOa_;o{+@_!Lu6cLoNYciSqs|Mwl#?Fb$M9WLPG)WNNXDRLTZ1Q7u^DWWt934D+;Y#MC1G884 z%GFyFak|^q6`RS*>X&oYEwFJLUt6=)>GSUfltGrc4wgCn`n?xrZ13P~KPO<4j&|k2 zw0DJjDW7cDJR7`r%}4r82WR6KDYMTEkA6FMACXPd(``Gu#<67O`obDhW`0(3u^B;U)4LJUw6=9#`wB1H$p>h zjC~UAydgKFY?-Uoi(cBRUlV+0o;bFekJ(M$h?yAiR9 zeKW_o>$drKZP3MyD-FAM*?eTf zv*pS;_MsKVcWG;nn!dYgY*98ZY}&mB+U6^LLf;;Is2sWC@wALBt2||ELd^rKnn==c6)BcJ-o9rVEg>N!-vKT=K7ltA;jy%b-nT8Vo4ic!J-Qn zFT}`i4U;hE8LyZ=&f#jAXw1Ew#YDS4V>qWK1VoIuk>C4N$w#bL+b-@m$2M&7pm<+f zn)11bD;Z#&Kb}%G%0e)}dX@X8Sca21d-R|y8xGn!-c?W7*fF<{;IjMss}G;`HD8(9 z{dX_pk><&Xi=*akx^OflEp)JDuu)tm!tuoA6Q(^Mq}8W-GArfF<&!#lS6RedT3o*- zb&=)uPQ!G9Y-agb@CvtGYiF?7lsn|o>G#E}W$(;#$3L~Q?E}jHia9Z?*hE98Pvm{I z`3w3cW9=oc&RH*3FY}3hV_3GGwp+gYE%ABImK?{-^+!`uZWyh6*WDuOT2;~X)e8@H zX!~%b4vn>E#nF%V6AT_)Q5DB#@NYYYlt0ONwz1<#X#n3rqJt9&>0@_d7+GqH5p0n_qYH(gpoj)H@xX zUyXS-rf#DCoy}v94T@NPcx%w0URqDz^DDBn&@?X}8dG;RZ_(*Kjs3hWzJF0%}uiS9gIdM05>yH^h# zg_w5Dndv=3woOR9S6t+KX{J{LWu(z@yRiu)maY3ZF=LX|Ai=$~j^x7;TaV@+G5>hu z+%==%c-htYKDuxGyIE{0OkdqVm1I43I^D&2a#C@PS?5D%ItT+K9}Cdlots0(RPOGk zCg=r(t)l*Uqi<iq^?ykZU)cgDsaT00>w)o{@r_Z>U; z4YW+V>tlUVJD%XPaBy@GWy%`6(TJnC7m|@%=3WoxkG++3@8Y3%{~rKdK%&2|PpJ!iS3rLCGC{JjS8!Xy zOWpTOoz~wcg(bhtkL=$kBPe>}{8YW(? zvN>fv+~`&;|9ho~otAPj4e>?W&f!nWA4gk&5KqPrZ{0$#6u+{edTDuY8(ojm9wK-Z z&=SH!i={+)nxxxsUN42;vtipL+AwHM9TNo_WQp%6vtdmVdurCPjo;mK;!NEbek!U}BnR&XJ z-*gA+SyOxPAId}kb(gOw4b(gMo`qBYK}&>##LD@q3-Ac#uNl@AW>5FB*cb_DM5@e) zRo4V#^UyPz;#+ac<+J|*-rX=0%ykEhGSM~V0@LUhI{chy9N3~wy-kD^Mb;COO0Mh6 zla^&N=v3baS5_(0f*3Z@lcd+~&&hhYI<^Q0>WT}2*_vvBL0^uv*7(85&td*QM_z*> zT5VuTCwqJL*0oT!_cw(CquXVD6?Z{!<7iUq-lUPFPVZ)hXwj^XsLXc`J>vWfvQWGrQ+ zHlgf8|1?1!b~)-w-67XZrIKQwLgQF=TDvS;zqifoGMwrvKm1t?Xs*#ZEY^p|b?Q^m zLWdE~uW&DHn7Ub>RTT~0o&Y{m$sYt-;7Sm<)caRHB21FCIJ3oid>;kw$x2C=^4OeM8WqxpcA6SsG;(Q^ zxsKffH+to0O@;kW}klIaZ_ zRZ)p95lQyGvqH1W*OG*#BorGTmq*HJl2|i9s6r(ujqdzqRCa6o`)Nvu11Ka^l1U_5 zoH}yhwE4Y3+zu9Lg`iyRnG6SY=U;=mP0lRNeQ*r<#qUi04ECP^00000000oYgV0n;wpR(zUdL{t!UTdN&`p9{`UJ#=T$ni zgrnr9Nnp(apx4OEA>Jt9$uP(lV@88+NhBHK@<}9;Ng3Gzzm&T70*r?aFZRL~9_2zj zQ+G9ekh^Zgp+{dD^Yn##z=4N@=!+{ovbl-?000000@e{mN_ko4kuKsm45T+sA@z+f zkhzbiegpC?qdAyyN{?Kt$}uCrk$Z%kR=N^E4rKu-r~ipD?-f@k6v-@Qk+--&@xyn7 zre;R3-kb6fMssN2wb5>zJ(gwwQs7Uk11aH&W8fbs?eJ<**EtNm4m@o?)jb=$V;A<6 z^PlYmPZV>a8b3)a3;+NC000JLu)Vc4gvcM_k}tr+VZeX!fI)z~&Vl&@V`$diyKPe* z+m?;%@2SG>ZJQBn)IcdFs*OYjgxH?AyN~a;51D>J;JIp_nr&)o@3gh(zk~Y62g7Lr zGHld5634qO;mHmOWLAi7uY{?pXH^3<3S!gI|3Zg{X?6m#%6`F%*F{)RGrcxn;pvY` zvQ>Ad{{{?g1Ig5Fe}ht*`-YY5n0tK>ges)is@+q@syFRZH6Zf*8r6PBcFG<1=13_e zPUL|ZZ46B?Ch9QUxVc0h*R4Ljg+(&&sRFy6hW5QMr-y^%bnj*vo3#s#>u_HIE)y0F z4!c-_`mqs`*50@Tpmy^D{mIWV4s4l6ZQBr9%?NqXO~%E_bg*M2gs?~88!GgXwQHrk zV1XEi=hY_oq1)|TLC?_z_Pu4MGus>heRdx*a{L&@m->3t&$bc1u|1U zwiwKZsY`EA&f#0!_r&uE--8fYA9QW2=*{}BvnwBnf=$$mVQOC8&y*bx7WKrSl9935 zxkZOLOoc8hx%1O-#dCdF@DU>GVy5;L5a#-eOmh8QjC?amH+y?IN52eT9|8uUh0TM(W_oW6X7 zpNTf8TyZ~E1e;1u!|~bS1%AARAs5Hn*o=L>c1PjTsLGsmW2SM^wRs?bKT^c0VEzZb z&Au0^IL!Q9NtY=|u<6R>G~X(c_vfT>>uxlJ)r?kMw~yu_+e4AH_0t6M9mm&hhY$Y{ zfr8Sf?}9@>f{S`Hi6yx)ZJ>NEU13NGMlGYw%Z+F4JK#}yOX}f8#Zv4WGcZ0bIgyN7 zlBG342{tPVaNPv5c;tXY8DqNOmf4r=C}GHAM%@1lOTmu5swh;Xq)Cp3V412RiVP!; zHi_u+5^^m`)F2Tik!9$wxhvl z?%8+@tnQ34Qi?M--eZ@@I4wW4fT$Ba7W3yBv+cke%0X6h{q7V`tLRgOQ3sNJjWtvH;lfTBRd-fg`3`MmU_X z34(rgcS9xGm1>zPtvz(m4Dd6uI}5cdB_zLk8G4J9@=uLuJ>WXb>)pV{MYR&~+^>>L z<<6l*h}DSB%K#V$b@LRvu_6vYNm58qiC)*~!Mu;!0h-_kVixENs?~cYyE&`@pNcfW zSM=O9Z>Xj?vRW*E$Ny^Z>gnBk^G(MZ|zP|zVP5gf^#anY!)6X561e}nQU2Zh*Ix9 zoTTr9|8?rVe?v~1MGxz-L;rudyqfRw7JzYH9W&P(Fe;R0<5o1Iq{t`Ipa)PL43r@r zh4=qNbaKLfiiBY9=J^sMUmJMAAV$GnbTYmuFd-Rn))arKw4t16=-fH?4&0^cbj?T_ zIkl%plq({?_U}^wz>M>XF=gAvDP=Un{MLM8(cVqc#*lC8D*~+q!@nx@=mQ1ap8=Lz zrCUQ)bStC~tK{WRk@P(hj{`xm9(4Wz^QcE+BmzW55-AElet-ipatUukj)VhlNhFjqO>+q(l1Vj! zh7!;_i%Lr&DtbKTSiqHm-*R6GGOTYfgg=B;Jsv9z zFoD*frxCR^gvckQopFzTMhTPQ0vqyzCPmQzS{E-rp?rINJSap>Ho(hP8sBPGgwBgHyP+jJSu}S-gx$_JqeL^$l5zfN6klm!?O0@i)(zP{Q05n&cElIR}Y``38Z!XGQeU;u5tq6mYiMy1~T1c29CjrCfVQi|=2I?-Z0QRDU znyKEhxiYcPHV!MxDSnsz&)!19b&-_TQy1c@72DZCmLk)aAqAh_h`|p~&Ag`U8 zX+gsrFT@&w5mI>^)Xk{z*qMp#1KNct^%D3i9`?0DO3eyrbV-DfoL9heI5k~}2py@g zauxb_X}{O~_IZ3HT7)@pKJP{{eZec(22F?N=c7du`(ttx} zXeMkA?vV?yFHn}GCq6p+vJ4zUAqWu1Pxlp+tr+Xy+cRg(8%0Hgg7iVZW%8`9&63sGdKE zUIhwWg|rTiRf4ZfTg++jqT;D`6I8J#KHR8H#Ol}CS`6bQDda+{8n2XlS;@0XubLqD z!h*J=A5$KIo$Zf|HoRsiQJpV^`O z6l+|v$CK^=n!*m*p;6ho9qJY1L-1ov#J-8f_#zYq$AkrSuYyr>-J{Uw^SY$`)4^42 z+i~3e5?F3CC#yd7`)Z>4kOUf>@Yoazm&|96dnPnEPfyQMEGA1)-A`8TMy|ez7%nWr zwy<^?YLymcd&4wAfAEFc%h0l+$72o_5@7c$eJ%r7Z1vC&6~l~LBxRw8kShXXUR4lHT+N+2S8Ih z1sJr`f56l01;vjh3*gp77&N)vuH1s)x#W#314t@ZEtL$Mu&LA9UZ%YU1ARO+6PQij z!$2?Y@c0qCSVZ_ml!Tw?O8q?(6X>`8;9J|FZ#4Dy|7GuG(H@8La~O2>G*ZDdsc>Eu z!!6829$Nn=t^Njt`|}75=Zb=i75!2}Iu9yWfFuiOvoA5Z%JbB5wGsZblp|WXPLt%Y zK;K@41g=_#u3T3b^m=m^3Q<;7oPa(A?Wng9vVH&xE>@lpid;azDW0?f|w{{-1A^C39GUDOqE@6-wGN5cOcL^1Gfipzv>855dO9P)o2 zPH?RizS+^hqgnl8FO?!DhKnZ~f7*~M0jvQYJV6H5h@Isv^EODx_}%yaJ#uA=pPows zl&b4kuM@jx0N%m)FLW|9>VsKL7g-U?rj~P zhO)>RDeGQBdZ86)t~en-dbkKe`Ic8gL{xew^8gk_)gHXJZYTlLvm_li)d)P}6MtZw za8prezt!x3JCAbI?QVs5j=F{P!9vKX{+3=;D-3rn(ygQO>tHl#4F^rv*?BcoF_VrG zCb-JnW%`ra_uR9kYNC%so`o$BBV{gol|U9Gz!pD&XcjVTr4jZ%a;x?*vfuh>kfXB9%2J4Uz*OZxS>uGT%%~llG)I;5d2|)7{)}bJV5M& zt@|9XLj)d{1pIU!O+r;o5-*2NOhn7d^MqaNQs_RM>IZHX4aQw#f>kmLu1&@!l%%UP z(2<}bH&qpd-NZL?k@QeOgY$UcT}hF;SOF%nwz+4PZ#_k0fE*+5vAU**A|(*-7x%Yn zy!NrwEWsnXG+-IOz{$NC&2F&Qy-ZH@uOql!)Flb*+;gq>xco5-PIw@WhD_z=M)5Y-Gf+!6@h$^`W?wcn|GHR~QCl0dzYjsN!$_ZBJkN^eY3Y4P#|L zp+HLTK%r$pxL8PS5@B_Nc69$t3`TVzSz6fd$^sIRBY5i(X?{Hc><@r;n+vuKZvP#Y zC(3J2U2GMf8>T43CN*jDPIt6ta-_{s#|eydk6q@o+B)SgDS1oEUN^*o{MbCQMp7l3 z*+~ke@tM=$_9qhBC-3Fo-}Otd0TAIqw5$w8LY|D-ADFsRF=*PS5SuaTq!my};l$3{ z;j(e%lpRJXyvYrauMn(rZ3>n{CeP?3``hWoRg9M}xOA%jNB@4*GRXFw#4DOj24G@^ z%1vO)hL$Ja`91QU%e@uy2(t=BOPs~S+ff2u5yG(v!uZHCZnyA=Gj}zCBG}hQ2{Up5 z4tV|~00u$R1f1a=a0p<%J#Gs(e9?uO#|dTfxm!2@v=n+>o_%@VuFBxE%m@G$y0OFz z4>lk~b86lxr(;JQUoj7|ikMvfc&^+>_=nj`V0l1?xH+is(7$!o=C3e1-l`#K3bH{5 zcQ{cE3eyQArfcOuZ>uj#?3kLpgK_z%Zgt1=gq;-A77|8R^j8P!DNm4{Xf&scvwktibJb}Fn z6Hciqa#!FDY%;flbHiwabW}-EDOVHR>(t>Q-({S<9fJMVHO4-rmBH>=`x%8O_gRdp zhN&&ItjVzSg^kW4#9=B)8y3|ppOUl6Zn7lhTqc#WH;`oDRtO{3Bs>JBOmyEE3)K2})FcK$P7y>>s%NHaWK@lIiyV&?SJ<5Q8 zdN9+t^=nR@m<~MP0cV02kqNd`Fgw9-nnIo=z~zM&=2R)Tr?4^%VA``F$8UCw{5ikS znj!>?IlOQMOx7i1idKj>qW>BC< zX=Kx8lPkt=8>{%w0}xcX70{AA8qdrwRLJ79_T|$~A{_d8sDAn(GP~JXsl3vgE>tDh zt!p)nj_XdLxq&tXzX(A!>juoo&n&5cK9U9PPyG?!zCVb$1%Uu8$gGI1HM`t}^kH&; z=Jzv!3WA`PsGs3V>HOXXo|6XK4wy^XpsL_Wt7qdv4h%^R$Waa1L<=*&G|IDx1fT*O zM(1cyj{Gt2R}XB<6f+dYp%V=mV20y;uTAGjSfEiX@qO`U_R*7vrRc%(b=!J0WyBLSc#UW>Kkwwi2HlbKV*Uxe$^w_k&)aL(FY zI28Kja{n99Vjy9WNfA5%z0-c^0+Pv1b7RJm-S~33Y8EcloDi0+6deNnrvQH{k2l4& zzbI=+Rg7L`O8*;oHoTfbH^v@Y@@W7iY70_i;?9T1pH`%kxVmiHSzvuB|7j>KhyP_P zQmF?#HIA|hHv8q+0nST5$HII`Yh7~LQB-SqAl9K?DN1_~fIk-w9xb~sNTC*&m0cc0 z;PIii9}GX;=Corvbmn37y{Z2}-okA5$Aeee$o-PPI?cWH5)C~sL$lc{ZiIpPAvJkx zqFNt(>?|oR1p2w$QO@eCC;wS01v{cMFr>Cyvl1GFXwyTnk76Fkd{xP#k;Ou<1PfBf zkQrM|bUWPTQRS2Xf}v4xbCVe_#Ny1K_o)_{6Q5RWI}hBS)Rm3!z12*VbYo*Eh%s;iFa}x;+lIG9pOR2L*^p`S%TcQy~-EMr(q;``m=f zRPHy(n4|sBg>3gE$?K;NrSz*@c6v|f;%wJGr4>;6`F3mHH;LF8-HXvr*vZ0X&=#)P zJ|BmYJfqrR_(nrLx@NGK8Ni#p*VlFwC&phEGTw`x&W z3+eW>peO^zEf!Y8hH?p$cneM}&%{MElRUjZmNw!&&&GkED$o@x8eJ-9_?ZglrxrzBT7F`A0`o znj)17n44(X>G)=#gz5UAsCZBcvDY6SjHJ!wjm1m?VY~2jWTa$AqDpi6e74f1T0ydf zi0bI~tel9N+2hpRlT8S3%OUdLZYi^Yu*}+R%Dh80g7e!e9{Mv9%?>$ru;=w<3w6WY zH_|8(F;v1Pvr4l?-@Qk7@#aP~GF?(x?5O7h%`!jbry1Pp1X?`|QeDRMYqS3xEntU? zrPZMe=R+=E%KO-)3xhKv!U>OQ_j!oOwBuqA{~hgc+z3-AgKXFtEt}u{F#*(o=aCc9 z&<3dnfV4g{+e&8L^lgVFOx_&S?^K|9=9_0I!4n_Z34_e4MT*7yeN#}&XtM&zMX>;c z;LW)RIj3=MFMh&xZ55nVRAiy%KttUo7;iXU_c7WVKNv+(5yJ1WJ3o!~?3S>>Co0>x z2(f^BK!&AaN%zw(wMgV>5v8LXYi7z);o&gHZubLkdeZ5@!GNQq@`2}4lp9sE;hKu8 zqT=Zbv1>|5JZ7hwDcv0gKLNUFm7CCJJjU(VDI;{B;9#{?Yd}d1${XCl`GG4DqA;MIP z(Psw=;(glX{=VwD;nVQJjiRhPrR>;8tn&@)h+^MTb8$>~05bef!1TnbNb<%%V3Z2P z>ply9v5Vs3q0}I*y@3J*{wE{P9in!ju?x`6#K&DXFwO{YdtRp{Xpw~@Q`IKn_|ZBY}|rOgHB`QA*)3}7PD%dui?ahQ50 z)}?1`*%qZ^f!b(co;Rd`0|@<{2Nr4p+M`y0Pk&G7Wr0+9iYwjN6-+6>(a!J83Qk_i z!^c@qaqY}wJfZ(Iu}zvDUa)>Kp)1~d6oV(E4s&sYe^lj$@!48#OWTJ(UZg)yzgsm2 z44@NWz=g!uffdA=ieJ-c!k@7Q*AtXNKM_`dnld>P2C^0ponk<*-MwtjP0dMNKl0k& zKfBVpep4$m1jEoWr-xr2yq*|HXv^DC=+y+N8C`b>e7 z8Gz0*4!YtK^6v#Czy2$Unn6?(qCn%)ggi%#zN^A5N`v7Z2?X|`xd@ZX|7xrtn3Ey` zL2-5Ac{a78N+v&1Fgn^d+oV%hlNM66vIMyyh z0zdSUZrbk=raOL2Blh}^)r|-AglJ9A2?8CWxl1q}L&P%4D(*1y8NB7QWZfuY1_4X( z2zWOeW1RtmVe9Y=x%FdBd3>KlAnz!+_5#Lkg3Ukj^_1D9_2*tzhpVj^_p#TdAmBS+*F55&H@!9Jup`6Pdtd2uGoynk255Y6 z(})nzePip*OHd5|QDMVsJ{?>2cWZZd`tIt`RRet;xO&h|qy;MO0fkNB_uz_Up7=?1 zh>b&eS?)YDqyxG%;AdV%TC^QyjBUEn5-MFY{FPHneTIqVhitqSo4NEJ{a37x%tAMN zpBL9By3qPrwPdN#DvX=5U?jm{-nsPj#hg`CN`L?W0000bAccg1oFn58_arBt51%EO zBI)tY$is8~A|kij5&*$vv*q_rIMW3wGsy2Z>Z(lO zWRCJ8L0U!b3`)2SFb(8HImoz`H4EFHCV21($M#U zvTG|Mb+1^^=m{)$!WSu|Uf{(32D4Et*4`8#mRE^`<(FNUh)pE1^iT+_aLxUy3q$l!d$KD zs=XNFpHPcjAnhwl8b}a6Fgpfi)U7;+=?;a_8_TwcXM1*#VTbr5e`HFt>JAM~yQQGE z@anFAc}2iA+^Zn9;F_*0B2Iks3fZR<53M7Iw)_Cgf*W&b5tqKQgXGMMx{?+}V_hws z0ayC4c2LgvNy0z8qTr25M}f>$+7rLo&sQ`<=-$Y>>e$}g=9?*5ZoFfD0z49Jx7?$E z{&rD_iI&^dv6K&|^4K&}?~WFPV88)ACGs-R!+%V_S)LP^Y_??M|8jm0b?)a~3!k`# z=MQBlg8MHI{fA_rARoL#phMm{3?os2Uktd$%2pa;DLoIY1*sJ|d94N;qSJxxiBoAu zvY%Bg*w4C7Fo2tg0LAYxJ?N3j%Z(H%nB`K9sc!vEet+Itg2;Eun`X|eC+C8!T!i1l zV1Ew4{{u9Mca1vK_{DVsU@91ejvcVEd5{68;6L5`d&9!lufu!l(u53Df=Cb@$-65N z=XS*&e4Su34efYD1v#Uy}~)DtZ%}wlG1`rFwA*GC&MZko=7y_O&C%RAq-~c7D|wnaqAtDks|qEgb!l- z9TT{Kchrld8@i*?9QgbSSyR@TJWCxP+1_gd>3RFPffrPiADm$c0;SvNzfUvk0W-2| zQXU@j&|dN#GVpc-gBDopdcJAmBL)lY5s`c|jX2&&4@qPR z1XM`!b;i;i{6E>m;uv)|&V2_;m-y;)+D=_6q0hLn!?=3+0xD*gopw{m87vLJzioHg z89Xe&+(0&7NbYTj^>*oI!?)%}*`ILXo@a0v z@n%Z2q%;iis)ZLDUAPO&MiikLq8!vmFxAb1dQH2^a8|xNCsYO{O=hlvXkD?`lGBb+Rd!=KU!dvqOE|O)V<89icsD!`5=%ox~^N)^7=MslEiKDZj*mRwGOufe3cFr&jr$+gn;6#eUOF8<(P-FKH|AYGgh3^sI6)`(_#}{)v*czH)oV4c|WX>4) zBaDHeA@brv*HnOAfmpM!Ft@iKG-O~6kVL4tOM?T*tujnY;qtWfjw@<(+9Qvtq&w15 z?QINf(lAKf>T4s`>p$lRC?d532AM6vCsD&@LL_OO`Bp26$@76DGIoC^EHx}ikC9`E zKw4^f&nk}RLx8E=`xqSIby=|YeeuFr4d_U$+A+%Ma=AGdV#_-(K7-7n#; z|6#9~{u+(^HB0zvH}KTZ(ERSJ)njlxX9lJ5rr&pjm0k#_xj{?~d$mDCoh5zEZf8cW zwz?}s@)jEQzSC+&M!BeB^LVn;{waMQs7>S1=Ct&LKc?@g!Z;Y4D67I#X-4ZjFDbA^ zH!KMWp0c-4j=!u5E&Bfu3+L}BES^lW&$Ga6pYpHfsZuEX;?yZ<0hRvEo&$)1bV$yK z=P_0r6XCsGRZ9T(egl1OQ+;;<>?0|=i`bjXb zqtF7ze~Bosd{UzFAd{Cdv`i!*P@!iEe`uAxM4yiuB;Blwxl6F!k=p*E; z#_EujORAIp?ugddy?w%qnFqh1`*eDPtqc&Bf;%HV7d;rv@6*G)|*)M=xPXvH`MDo zK9jnfQd;ON6HFyu;1Q3;MA=X(LH&n6?~+SyWZvLfZ1y2P4}}SE5GU2YJ{&&$xbnju zw0LC%`9cq7#Z%UmjQ2nW2jSLLC@BjUS$3vgb$!3C!$0p9FUZ&_R4!+hUkRv7O%`d$< zA99QfB-=b2dAHE8A&N(inf$k^MWcCv9ZL%N(83t5NU9=Oxf;`d0s7*|#RL|z+w4bDU13j=^Sf{Eqa~pF+ z(C7?FyeHr=x=F2@MkT%s#!TW@{p}UPZ#|8NgH@w1u>5yGIXZ%=QZ!pzC%2Ldrpozp z6^6~5I}<>%@_1{g(?Uq=f)h9+V(wO&d1#tP23?OeI9L+O-j;O{BC=KhawMJOcmH)l z{)l3vr8TRb6cJi;)SBeUD^OAie@@790+K46lIo21lBsD$i1^yG;oro&2ZShx4OY`$ zSeOHMwBo5rTkTPA5%BHEZLdeA);&%CFE`p#fNm*?h7^X%yx+sJl7aN74KimBilR$* zvMV21FAXp2e<+4O2Nr_vD+iW%iFUjn%%FQz1&3Z^;`1@?OTk*2u`(;)NY@~6Ru3M( zyIbQjW&Ur$wzXw68Ssp4h#>AwK%V+!0E_g%F^+|M+rseiID!4i{``|IJ!6gMdd46k z@vffDR>mZFI5H{8lpgDR(|xRirdH&C`IMV3Xb_B7mL>CyNYrw8w(iaqokUgwV~eaV zK-iF`P%sYQNRVdjrHsG{@U^O=r{aGb$I$D?-m{o^X+FR|RAUztF|*2D*K zs?4TSx)QDcg7wLsU5tQ&xTBmwnAagv@99&2gXu$Gdy^I%_9a|fn0;PdflkZ<|9|<5 zjsvaC?00}Nd`E0H71YzahTBBjQ>tx)FxLRoLbQw;d4n%6>n5)b9u7OH~|D7bVSRUNd*@%d^r@_;a<3AfE#W5DDoF{Q$J z4M~IfH>_OlTm;G9B>aE_8f{n#W=jukZRdkv1+p#{FHbNiJxg#in9SO|oBiYRRrm5| zX=Hb(Uk+A!u`Q%E&N;D#c=B5&j+cN^#PUmKOeb#3ik;kyQaA43#L|?5Z>kR|xpr*! z%q^6(K$LV=f3CT-k>-Oq%oNT2)#?8E<>mX8cjD@D-2#R?ry=F(O*`GBfpg97s5A^E zBp5+l9I~vQ7}>XbDGsx=lG0*!qR^-F+wwq+dwpMCFK_ar^Td<S!H0?FnB`(xDZyI=K5K*FrPyhe`0iPg}Tu^RKu#g$1 zi+Ce!N&zv2b%h}3?myfL&4=-MH1LO z+;%DtKady}vtA4f?;Jc~c4@_x#rw4McpWYwfoms&ay4aEB2A5YIzo**Ffnf6G?_Kp5@`&tImJ z)u{Qrfpms!qq0;00000iMLw6Df;ESHNFM7erl?g4*b7?arL$97yZ;g1C@Cq(TiAU8m3^QjJD{KHL9c$(_#S@1P zH0*v3J>(OT4yq>#QbJl3{I}^%huN#X4amD&#dLW9IRJ!X7HkG~n{1zT>X9o zR;9cGPzz#T%G|wc4HaiQ0t$2^Z6bvg;8L%-l4#HzlfKmh7f+L{DPIuNXMgjiA4RI3 z(YMU_VMa6{3tFeCZ6@CrPljWvNXLs86j+P}#m*zakCSdn{LuS6BXg+%Y>N!T8XNdB5|W$DTTgrKv?U*U;qFB z000065TB?noQc+md|ams&42my4E`SiMuR1ioP>+O5|qt9NIm3C~fwtNvx z>UE5$Aol308>%Cla3^2xC~qZ%?jDgu1|qX!LHUQ|eo-iW=(mm>ho59JT3V!x8$zTV9eK5@7z9}T)1bYDb3&AH}k z)4ahn3TUK_1v=vJCekOnW>Z zci|9Q?I0z%z4IXfoGApIt_|or`oe%7XPApRNHJ0F2_$Oz%||rNNfUImRh5r17`hW_ zHn>Fq-}zDg2PGxZ9j4;F131NlztFifw6lFQ|8`3>H0d&Jq1TP>t7AR+otGUs+bbk} z2)t|Yk&QCn9P|Fp&|?TdMH~6ZyjCvVpB$NSxA%d9Vj}1oe8Tw(@A3Fdl(x`66USZW zlLoI0qds^u&Skn#a%-nvbRUpqC07#$y^dxdwvv2Wi}fb5*Fxcn!)9Gi>pvu@`0Cb( z03u3hYJs~;qdejQ-bSgut>cF0bGikSABMb;d8dz5By@vXep1i)OkD1xR1^86de3?S zopSc9PTm+gV9m5%pp7JazuF$U1lVyGT)2}ZKn(l7rSpXzR@h0Xr8EGB#Cj;=gW)%B zYd16Hu>1c+-GS7Oi4lsQ2yj-_83o&<$9c9DSV%O+X@(zBN!y|sD8TA_z@+J*lPQAw zUhLY+IaY5Dw6ti}P+p0hdiG0u12&sfMf0)D`oo7CqKuc=#P>BS*msbmM!1Ry;+su9 zmPKE+{?}d;d#JlD#x5!;G%Vnw;N}Bs9B?LbrB#&>FfxarUp{XqU0!=x1X3^t>a(DV zD#1VkfLOm!#K!Bwh{=4bkNY6Lk~!r4Gzz!%!^@bkK|Qe^b24Cm1Wb7STc_tvmeg=b za3f&BTgZETHeQ~{lDb`wh!?%(=eaE9HCW_rLNrp*=EcTAYDr^Rl28r5ZVanTW}S#v zEkO*lE0pmj`zKOzw0>=Us#6983jQvb4u#N_v1#CxcN+;6d|VGs`N69LeAIgYdHdYu z&27`0(&Ob$d`awAUP#g-Oi;~-$~~56IAk1fJ=boh+_uZT4+)H&y9lsAtkQd_+mx%i zJ?&a1xp}lYnhx?_8?R4Tq%(IJGjgo_^GG2@V3yd4$*+aDhx927wxBxZ>)9wx+?$;H zWOy)M(rK5HKlIW-d920f>1C9C71RJNn5hElkVP@?xX-LbkBxh#8h#@zX$Ca{E!*m_ z1DZKRZx%7y>Cv;i$&-FbYE(ZX(405V9Zq4N@d5#bcXDRO5mH3xOrOt2R}y!xZWmNb znrpw(ia7&hQQ-iS*v(v0>>a2$fgf))m=$3o++2=xWapLI;|utypl1}z`uB~@OM9pc z%9GR0Uo#Si93ZrT3rBRhPAoIa+5sx7x=)9Vr#?Sw^W=^*(82d729H;jc4~OJ2N>k zzIcFF;w%A689t^Yl@$lb7q9KStur#xs}~-!$cNiLWSHuaU!zp@ zfuz@EbX}Iodx^aC`C&G<6~#KbA!IN1pQtZp%)L{rXwkBUxoq1u_OfkbFWa_l+qP}n zwr$&H?{iPz?(}0P{m>(suOpeGGG=D|RrP-n5=pwH%;81PAIK_Qa($rA`=K4>a6__`gl4G=HtAbRtWMq zMBP}*mcTx&VWv4eNj`Q^{al6}qrFY~O7z>x_pkt+ML&SN zD`(yuyj=sS-Dsyjgr^_kdG|FpcNSskWg}3@w8SQ>;G~we&j{_U_hjD{46lW?c|y|I zywGivw@j7-d@&4V7E%!5?%|`37Rz$|W)cFcMyH<{>(bs3qrd*vdGHTZgU$0- z->aZ_!u#fh35}=z}Si~j#6R==;F7eyc zrrm~9By&AOxfLuvog7QM@aU{`&g)^w|31YHs0dG}n9LE{oL1|px~ldbzg*$pZN%=^ z_YN96zF9^8)3WZCJFl0wd|@ejw#9$2q`sKz&g50%gTDuHfNbm53{a5T;GD`%HOEO31*;_ky^jLycIpBL;#}cOt|My% zd2lCYq_V(L3x5@JmEcb;N;C_0H0*6^ppUY<9=MtQ^fTcfp8n8Q$pOZhL+^vvd@_U* zSn_&LVeTGwdoCjkBFWmaxn3t;ks^kz)d0ztcM)>*iYrh-hlPqu*IX_eClELG`W|@< zHICvZ)rdrLA223S#jy+OHfb=%Sk;A)qtEbzKizrL3`}K}Nf{7KP2i?T4s~QQzFm(>Z#fsd!5MKcF zF#T|;9}_kywSZsXFBSq(wawD;ZX+|O62sS>Gc|WM5z6w#@gxo_D>v3_3vJqM{FS;r z!VX~>!Hi4Fr`MUyqmWY6NkSbo_C*=Qg+M)P7|;@lOM%xA#lL8_IS}=09PnD9wf*5b z1tJ5by=W4P@v_$HELd9x=^^+&fVj5J26!WAwo{6E7#evGoSM5 z9F{m5?N#Qj1VSNA!UPn8F3wR9#+bf;EjqtHo}cBA7Jl#FpwA16Xd7GTz1~p#-YV7? zqx_t{oiocB4MY=^2ZScc{z53mJ}IYOxGRm$f?ip#U0^GbV=^z%`b*Y}J*wLE7+av- z(DREJv?xuZQ}N`X6j3Ms>z=sK9cU>{y+AEt!6Z>j-c*kM-6`8>y~A=jaKBf0OmFA^ zN7D$o%{MbN*-A>qZG%}WVE@;gt%TXIT2RHqCUqN=M;iCF#t;vY(F{~{ws!4e;8{x5 zO0BeKOJp7yZ2XPcpw=Bia4KO_t-s#i=Y8`Q>Sb znxM#Czn+u8{I(=o@vgX$DLAi?ScObCL`R#FWeNO~NdRCyNyEyM#sdR;8TOe6HF<*D zUKGT#(A=-@(;S~mu>4!u}J{Sw4+Vv26w_tK#}p5ulT9+sZ_qPNJI z43i4z6$&8`ceHv~$y*G}p1~4jtTQTlqvF^*{Fu~_V0pOOUj?S-{s4k9pP(*xT^Z_( zhP9#buYaN+pW1Gx2*&>TEkLhjRmb&hYW{T?+n$QB}=u;}zI{%i&!ngFn zgQn4y+*iGBiD@y5>dFXm%D9iY>+In>+XN7d`ANwBvoFVIOj09zfs`<{u_878^qG=3*|LQevTm1uL?5~!Ty)74<1p5Ya%MjcIx z%f)hd=Un2jl=}WYTUfcKXS5Q#Y4=U{3~@Cz$i{)w5)t7RB`YYy#!F_fK?y`KTve4q1&B@fOwL>X7HTg#cUjv# zmdQ=p9S|S-E#FelQOr){t5V3|r0~l)d>@ab_20pJ(%^zQV_i!E-E zC4RSzZDm_vln+>(|U@Zq;(ydk8@Xiql040;PDDIj~i}9%EJH@@zNadCQU>o;I1ebQo zY@#Uah9tW?^d_4RWwso`X12|1!lRk;vAHE0)HKe~DSWN{lDhuZJ(LmT2oo=etBPGo zF~Ux8D=C}jeLdvX4x2s=WT0bEOx%@r6OC7XYvV7lJ5<=HCYi^~-o)&ifmMF&8(_Gj z^PHjC=Mg4XF){gF1v8Pzf;^mKGv#+%)<=(+Fv39q+DsD5#YB}fzNtx}qzc_UsLl(K z+#U(@CkF+Wh-iglgVZN-FQz#tagMGl@vhkKg)aA+l~Fk5j+mAI+9~;Ln$?j?rhg(6rZ{WVLHT4s z)ns7;kLKpwNq~o$=~EojJ`R*cVGR-Mr*si{q*q2n%l28XWU6N%>5Tb@|;r zjdFPM{>f4%7CkxNBB4>YOX?q|m9ZWrQ)h%l1sNuUXW23x0JgCuW>Y<2lyk>R0D zcN<}3nt5s=+h+xT7RGcS1F_$!z3@OA%G5oE`m(&{lCI4+Gac@04C|Zis1t#9VeX?*B;ZwH^sQJC594Dw>!b$qL4#`ftVua8VkGR?m78 zXh+-bdu=3xFBSEo`#+M8!nCet;Atul!s$u??G}}wH#+%raa@n!GqPh554|^S-=R%K z@2aD$Jb^8DS_ zuaQNsAzv0%3O!)QMDBBEfxOY7Iktcgr{ebJeTqm<5c>F~Xcp{5stf^$_wk)i11#U+ zDX@>*m)y4KT58ljWAt+D-G{NCn&yLU)k7B;bb~64E9{4onUcn`gy}r`FtjxDDpCj+ z?TG?Vp1K)Yq561ys~eNP3~F*_ zO#P$sc)CtYpc|5f9w*GN8xB~q^Q09DV|ZRR968$=U`ga7a~&=q>7boP|0N1y4wlQ0IF z07cd;i;=*sKtM&~*{^$GZ`^xqQ=yXJ&;Q@3xSt(iZk@+5rPM-tx&c!0t&>nP9P3Go zeG6Vhn^dDf5am&1_`QnIh4)yp)(1tHK^1ER2=)F{75qX{lmwvgk$Xn$hh@s7hRBh1 zh1i-zz7A&?pW_lnK2SG>y&zE1du}ri<}a7edGw@Ou&M$ahVoz5Ad!V%cSP283j|ZQ zn=YMnOR%NxW z59QETVHi^^EzLvBUs)F{eeH3z!c0AeJ>OVkItHLz`DqYVw<62*X^Jcpy!mr|WIH^;WotI@-<>ONp1TK2o0QaJ5-OszNyU?@Yi#!@#crwRA z{_!o<@Wih6rtd6&MHK?t)S$qP#p*V-^P42vKRMyMJz{0YZ1^bgvN3Cl&hPi{yKbIj zfnXouI`HjnK-Zr&SoTP`ab>b}62}ay_mr_$*Gb-X3B%zuFB`&oh>VtWc1gci&{Vxk zqg?Bja(TUwrJPYiV*}QiPAn_z8TPlto(@3sY8>cloBDo_{VS}4oka3+5-kZ}P9MAC zSo78;{tgd|5%Sqt+Zl=fYnj?UxuFp4MNSmQREQZs!yW5(35%PDVwKNN3OMMfw?AX+ zDEo^l*O)2j)111^O=+=gkGFZv9ubGPt1m>9W1+8IIpbtc* zfL0-TLQgBUfJQIbFESh4MqnpLdrhHf6VIc9V?FlX@h$R@Y6HZ@%hwVosyC#38t*(v+Uv$At%IK0c*OWB4?P$n z*9DksAOVWZQ{Y6i91zQ@DsI0f8X~$Qvzfm{j;9{(3m^A_2S$vkz%5c9C{4*mN0E3< zL!;h1=M)|DzC^z1+h9A%I@NKt?(&AbN!JIiY(AitR+TycH zfOONy%5F_z|Ez zW&4>56&3GKD0r=*R0OAW{xFtlX(xg)NfMbvasJ%sEnqZtp}2tw{cG{aM-FMikwdDE z8XwydTH2j#1H%O+f)J4ep&z<7^mL@N!8{@ky-$1F&4MF@#5~xjt{mu&7@eYEoRFnE zC&+Ntu31xp4L}rd`?Luz@u+(OU|euNC4z5)d{i9c)ls87tXObnCUHXA(2sl$|8UEx ztV|o=9KNr%v5hrFu2u2pFL&`q2dvQU)+(;-mnyZwHb{D?pz7Sb$52gCIhM$>G0{`U znaPKrl8WL!Bh8PkLOm+HG;QQ!n=lJ z?bF^OG&!0K3rR5_Fi(I`N2=X&(e@yHN>hDoA*#IuqmoLz=C?gH*Gs7B-MC!1l6S2h z%XI*$%kTekHu`#2@b1kF=pPkciHb^aqU*C9l?zZtwldr-VxqcKQAa;yWMVxx@Bh$KVX-JQy!D3Zx8kb1tJNau&vlGePElcS% zAMMJJ2)vUA3DvM>if8jRJQkrM5ivqnzKkt5jjd-SyhRyJ;flELmxF!NZdteXW_XI; z?aJ+s4$H)imc^+SodGZVKKmApEbQ7#QHTftMn7+2Dt>)@!u)hZaTkz-lRy)>4)_!3 zcj@p@THhjs_BWm$6)4z$2e-x%OVU1{>IIo2B%aQHe@Qnn%@>S2_JA)_TpH^zjs?rz zrNcrvj5q3VR;L@H@knY5GQeRz^>q_CQ}EEZT)J0QjFrQ16%zl=oekn}N@KSiiut-V zgM0XMvCKpNU3Fez%PH8JeRFi*J8d_iW*LtbAwtL!9Z*w6w}LL4O8Xpn&nE`HMz2@?(nLPJ03b-2cFv zg((Wt6A*b-0lsUju&veD_XoG6o;wn{`ZiUyaqTmfP~3?l%8ecw59gsD0apvqd&dgC z1Nzr%_V8u?S5wYs!}Mig?Yjy7y2#fW`qP}7&!YBP^}7PUS^7vTcn>Vr_Sg4XR2UpP zw$Zjg`zu}e{VFzI!LU;u(2*c`-)1ZWLDGb1-wHq2dUg8IYnN^M456*sz+OzuA`Yq! zZgKc#?yjNYnj!BDLo(#U5B6Va%ha#;*SG1Nq=UL{sVy8&=YLk(8qMufh!os}U-^Ym z&V*FLGQ^pgipv*x;F>*Pe1$G<6Mq=^;3EFHQ4!pf1)>t zwF@fTPHSW!R5?K)UQiw>`{VZ9Fe-CzAz4uqj>NP4gSCvQZfUK&RPwv^!T`Tda+ zg&1E_#b}5%vgZ}3mY>`rhf2JROSNBLQNZTbJ3E%#rl7A=S4N(Z5qU71(752dfKM@C z!xf6uQkkZ_N>KK&>PC5g-n7pAH&G&B z>|taV$*)+PLx9}JUl0K41zvVM_^+~h70D@?6;B!PUpkF#)1w{{1Hi*WTfjG;d{ft; zqnnk-71*^N2Yj5XokkqHo;&xvxVi`YAI0+b$&g14%B>_Ms&3DGp)IPD_hK$%4lQE^ zb-@V7XV+Di49XT}K(_fYn-O~50Lw4?$QaBSujVCPtE4Rbu!E}nsVIiC5?e6vs=R9D z>!^Bw*j_FxL6YnTTPZ!O_#o(8__`UObe{;x#aID==T9GqwJa3ri6lLhkb+80NhQo}0sowNKOIJHpthvHec8$++2bBh0CW zi}*bsFNK;Fs5>Q2iiPN*Vfr!{avME$vcs`YJZtZ(ZI-hGZ<{j9IU$2{#zSs0*|LqL zqB{Wj%O(l&p-^#41gtCL2Usl75kd1EXYSId4iTLS3d_wD;$YE+ZwUpZ`if}ds|e=W zIwCmMmR61Q$-)ug#aQV;-~o!4pvtux)<4~KAS;!-N(A zN+A>c&)Bxi$6dc{jFd(J%_`Dd6JD^CNGPyTa$b|(;SnX6gyH6Wpk{LVqhZg%6O7yC zVEpI+s`cxUe^>FaeLJSw@TiK}?uBS>!g?4uqDk}SYqd{jb%>{zdb95!J;uB>vtpjJ z@Bjdma$n*z5A$vaPugAiPO0sY^byF&ntqZ0oy|@Zf+x|C+QI^)G&&}vJHh6+_frE~yl5v{hBtyHu?xd(sWi6pvJR4jY-hmg(GIw3NRDeO?X zVXdXs0*+LG>!(uZ)e~Xw&OfRFfImMRqW> zG$HBB%GMpzZL|GT$(EGuk`XGSwS=geE-mbR4u7pqXxoEe+!(LeJo|35x{TKi2-@je zM7|lkHCr+NWKcjLei2d^YuKy!lasU9FyZlSi{$G+V|3j?&_xyiFy8J)4`){)N z->v_%{r|52pOY@nSpJ7}84}`$u(M&HD*Y|M(HKQplmgJyVo-fTLMKY23<(mZ+7kTP zl){ngera15OrHm%s`qX2sI>Y{1( z6GsgvVs$PVy{p50BNY&2MMm$nU>f^Y*fE&rt-QYcUhcc&(EISk%gWBd=eipXRUiGj z^lDA!WnKn{otYCvL%=)72>28Q5T6U;Se1CeT+LDQLhaMf(_+$sR|>d~Kt%F<05##0 zf@KC-@JQ!vU0C^|;UKEtka*kW8ruhQJR?-6434NxkdCxUJ{F((vz^~o-zx`Dy5z?T zYy6tpDrvDg#B~5oZ&DD(S-$JT^SJx5GwFW|zZ?95u(P}fHiQrQxmYA8h2rH*<(?H* z&Dv(Rn-L)2Yz{tKgwZ7xn`~CMf}Y*yR{?P|T$DI9<|&S4i2bG?%}}w}v*#ojT79$~ zWe{svbN--dtO3NZ439@l!g^3;NW(#Y$86DbR>lsFr}g@~9?z7Y{4AM#FxW&J%k`Wur}7mVaf?$=nEG>D*^$SSPP3f=oySc61gD zVu_=lS8QVve-?S2Op!b`lj1uez=3Z!xaI$P`@U4vV-hQCAn`NkUt&3aZ6V{8N_(wG z-8^-hYmX3S)V$}P7s58_`tFH1ncS2KvpMTI!NZq*S)pTxp*&F?7KZqHd`~97UT3_z zoUqnfZQo~OQTx#{Gf&PG%EdaOO(QHq#}z55%&Wd$IM2qi!}%Jwub>REk>h2v@|$?8 zrmuoFAX~hIqGmr_Wah2EY0^{KbMjvPb3_UId+N;Vi~^6L|1f$ zoynnKe}jMlGRKlQ^Q}!+a#Q4Dy{qLwqAW9chwyTDgX0j7Bwc-My6U=--0d%l?J^Wl z_R|e|vNy#O$92hGFN=SIkw6Xy3IG7rT_@C&`@rM9DvYZs122_ga{IP0;*;O!BE)gU z3GM(BDHs(z;Fvw49ULF5z8z1DR|f_AR+b3`Wxy@_%=N?1j>-K1z_Gt3rb`Ap9l3VE zkU(PcydMn^=+sLbg=ljC0GKtdXAkY)_IIosJ?#Mjx?6qH?M-LcuzxLMu4qmF`bHr` za@jJC+=StZ{r=e;v^ENx zX1b=e1`OUxCLlMVh_IuDsYIX?TV`b@=z{Wlq_S|D5dHgNq{*JtZgQQ3*Plme5|93J z;vl>+rp2{K2!JAJOv=RYRPUPvq+lz5XJj`NZcNNXxn8Zx=RN;jy~;PD7ZaMp&L9RP zvn!D|VzX<)UlO@1Q~|QXvu%XP@rTZC>Od?_vLk{Q%76DUu&B~-Y2=PXn=ztAmU_K4P2f62+4muOL744C|Ld@$#$}+J`+3@Rn zN+9=-m_xTgrtPkQc{s-nrv9YgG9Q*XDeQ#mjAA~6>4w;W9*syIIVtstpMbiMFI|%N ziKGz;ENgO2mi^PRX`~8|o7>tXSI*Az*j&O!X}y#0H6mqJ`&{O$$4=E+8qC^#)rVKy>L>V(rc)W}s%>WqT6zRauBUl&B22`9)ul77j z+2t9r#*P|(|Fm40cu!TsncyK;G98^0J%vMABA7IhUK1kK41j&;j7x@CO z0*K2Qka2k`4R&aaS~QzRJA0JFC>|a)mdM=}YA2O;L4`u9r(X~vcK(&=yn7zbaen@m zqK3OqZUo30wnPhkSba3c$X7`tkh&G{~6oAnZ#F{WQXT ztz_!qjkYGqKOlWp;ouj|l;G-u!K%$;d{3`pWw;#`aA<;?u&;h}DNW4Q&JxyJk#h;; zL+j=82cZhXwo~=lPfkMoOcLc92n--y>cl3$M7jD|+Z~h=vFh~<4O@AK6%0ws&x&M$tf8L8Yob1?@(h$-fg;35_36z3Tz-q}#!_ z7pY~d)_U6F&=lU`E!&$ra%z8ybxIXXgFU$YM`bnvbv`CoByVlc=Drk%!=&X9_!@|# zE+7t_B#Ka0Z^&4bPhu}d0d^!^qOx(Y6qL~PWi{Uy`z+>{5#3zVzV3ms;8wd)CB~75 zSe5tbm$;~Akp6Fl-PDV*<7ASoz@bna^3K@mFS{q>L|@`~klA$M2?Fk;TKV%_z0vgM#ErCCj#)vFH{Md zGjhxXx|M9z&Sl-bc91{fhpIm}#Zh+Zwz|eLcEinQtbB@eo0l=c6m!CXzF|_ylTJ!W za_TOAYe=5#y1xvJ(N|GA;?JxojIKK~j3|4c#9tmpVL2gSgXCe8vN@zB3pR^7(3EM* zkyS_F;yny8D#@&~5B>!?0B>@c?Yg5d@gmFrXLM20IQp_vSZn_#n00=&R=Q|Ae3V95 zfG&}#_l<_S`(9?nOj z5QjuYg5gU*?bgXLWYGB2DXS?*0YvtQ2FU`dK6R;n5mwZofOL%b+v(xdla?Dz9=?FgCZ{Y)F_bChTAJF9){(;kJxYD#=vhK`$0bl^| zc4X4YVJs~|-Tbd2X@>@VR-fIZF|TO5u9piy|AK?{4!hT(h~Tdwr8xVoiI%=@wpjve zxeOKuQH-dUnC`tIs|x|UFE+68qhIX(eulB!!2)<$T1ic~`1&54|A8|GmjA;g$$4Sm z7)QHWw12Jj zkqE&r)e|A#hiLvH`%zWLTFmhMMt-nOD$$>5bRv!-Mo2>@1AaXLdV5O}lm*79Ep9fu zyE!wvIRm5nC3zF@rK3x+hG)sE%bSE7xdY^Y;enH9hJY6o?QNPXN&T_M*n+XgbS$fC zv9>)SNX(zv=Kaeu-$1TJNOGd_f5N@`fRiq5z(6U-*Sff^l#Omh!6DOn8^l9LCxTN9 z6LB=J{v2pzo?=Km2I40oO%R^Td@;3-9#-}2>*Dz1{cHtqR2Kyo6cT+{(IXcU_qiD6 zH9>vecDhF>_!v8O4{}qHxY6jJ^^-6*e{}-6DB$Zb=}#capbIbYkz!g2vN`GNGm_2T ze$7uE1%Bo@uQ6|d*d!&9Lqy(bCN623JbboEPR30#*0Jtp#DV|^g#NO-B8X&noi9b+ zC}mE3Z5QXb&c#$t-Q=v!Jw4S!iXQEY#siIL1RQiB89_JQE?lFG*u(l260eD?@fXZL zy%-b*I<%$GT!xEv^cz!CTzaxjoo=`qb=&^482JPQSpvQU@0O967t1>(Ql{B6jSL~6 z1v|of6(x|@=Y|te3FIdy38ydgKiSrgUC&ZUnHKmH+Sa&r!~hLodBJ32*EfA0lFWP5MaW;ce&Fxu@k)AFn)1q*?jd&=|SVuThK{U%B0wQ~fVze~|qk>{yUA zl=2@mF4Hk>cJ0Qn7r!Yj?|#DUH;6+n)xf96LN)d9G1mhtfFEHWygY>AAM4u%>!SeI?NVY66kOHrIs^Qt~y9i^*@S=su;30kS z{$S|rkM<=&sGO`-f93;0dR#Iytak9yAOFI6{iM{06|c@b82nQIX^5?Mx`b!cl@#R* zWnHGo&!m6-TBC9?_}2p%Mh}?Co$3PLYeqgg4;G(~N=h|Wk$Kk%qMKU~YS2BYXbX44 zMvq6VB$MA%FPMV57@}RlWf0TkwxDTf-n2Y?tJC}tjvikys|vE)z_jUU^DFo_$(0-y zc6rKIY+cOv`1FyD%VWs#h}1^0YtK*CU0<~@3v9Y`s(zb%Hf^5*@@ACZyw8`UyO!L_ zozC;hl2r_|Xr0}l(D->1pV+f@cSCGrO zj`Zni0XNA}Swi7LMp(2*sDkFLe?~Lc&{labb6$N7qQ|sI214*UWMb?*b0uMvoaBH> z;XG0+eStCR--ro~Zt^ROB3oX+jxZ#Tk(>J7z?GuEKC|QogZo!dfQ*g~%80C=?@&&l zAs>f6Csd&Cn!GM+Y7dJQ76-7irAQVd_71*hUfeQ$J0`a59rcWc;ruK9|eC>PvSw!Ilz4Oe1_bUVhv zqTy+IS-$m%A+Ib$8ZnM3L{wcBR03PK3KGymzPPmyYmw-KUQF+GMSO~PJTw6J%2u2i zh3G`$!NiHYRCbGjYH*NxqjfgwPlPTwPe%Bh+^^)WR>-Ru!!APs5GHr_9#YeZ33`@b zJ1t1a*_xV1RG`n^1#ER9Olfd&8@tFw27W={95~c+P5{wg-E|}=yeJ)w(43RBR|?~i z@A%N4Ch3uCU!=~f1FUjXsd_H;7f|hyts4XAnxYN&j04$eF0==C*DTY@n+(scxc%uy ziqIi`W1?s;y{#SphuJ$;Rwtta2Ckq|y=;gOr^>FLV9R0eKNR2PEs8MWBr+ByZGxEC zf<)uPL&JvD?yvv>m@qa)ukif4+Th)}58ZXCdycT$tAmqGTE}o;vv{;|N{9kAx^Z#L z!%F}Z+#!J(P}m`J#Aw-3ip}JPRm@>jbe0~muu0|L^WqDRj0JoXCRtk?f1a+Jrwf_o z%EBkHVwu;j+5e_B0fLl$NZ^XbItDNfAFNR^ z>7LtZr{^I?ffv3Gyu;7_VJVh@IFm2qw&YGu^a~zEypWv!mA4xFJlVnvZbc)4wfQji zxHH+yDh)06C%L7WpM7=Id%?+YeY%qiTv-{LK|(Z^17VsJ)2bT|f9;TxJ};hPPjl7r zb~AjbsKuJR$FN-vph_@i+?#U;@v#^FC91P zrW|Zc_GTRRVQ|9y{R$wr_)(@dA&7=nOhh@Pb@O)cJ;SSl4kWe>K*17cULd$9;#cZ) z-HTI}NGkNLy{@C_eG^wZCB3{zsBmj-ag8Bq znJIdL31m{502P`;L?%2%=i3EQW9E*&qgjk!^IX`m2)*$%=6dP`@hw^KkRsBW4+)~7 zWPC7rvE(k#Tq&@ogtH@N8l{@8$<8=uT=`1xr9aWgn5Tbfuy)|K?GE6q$k|7IP^+C{ zwtf@_D+us9T5~Dth&$@y%U#0P9huF+FZ;~0**P@q zB(>9fKO=nHTv0h{h$g}x8paWk6Rz|!AVJdZGH{D2*{?iGi3U)&okk1h>AyeH5@rL9A#5H>=cszbIE0UUI^m7K-Y@jyc^uaE&FcaOQNndeTwx_N|EhGwCZ&lSn*p;Pc|yl3Ws~_RSD8UdgEB9LcKgb@)|-%$Y#GEcPC4)dQ$905&bJ*4##AD+3rPv4kGWB6l9ko(&%X5T`;8X~DHR=7Q%1SQOOZi2m;*Extblw%?)P357hg=Ntuw$ zPxU})fPru6UP?1Ch;o*XR*U*@Qs{4&;5?r;rP_*AmB?C&|7x(Eo&&AzTtra6mb3 zQkZyJ4fUfwjPlN>NWvJ;pUbMEH=pV&M)OL%3&|bE#G1zqC<`d{D?qKZtN{5ojD1&< z$weS$lp}53^FhQ?NlZYsi#@sXnjpD1wo$@Z0gPC*Hdj1#mI5GYHz_tFJb=~^QGvb~ zWBC+Q9{M9PjQoi~jcdDbASKS0r!xoUuiB30{>&Q(QD1i%Pl~jepb$u0oYV9IDIBXknR9Y0)rDBoOI z@I&SHrYFqnoXG{)$9}b&VaxK<3K$oP@mfya(=YOgE(&v0^D8Tb47&I?i|YS)6ir_6 z*j?!1Kz<9EjFB#Cv?afZtn0wxgvLbG>=;2LqcXdwdgHi2V40!V9*Gs{SdLE{+1UI^fb z^E{80cE?JgMZQBaoMjliD6!J6+A0I!Fkxcv>sVSqk-p2zz=qlzJGwKjjpg$JIhipe zH9lK#{Uq0UiD2pDg83!?V_F_!4tUWq*b>qmOs?+ruHtAuXPo3hvZ{nlhSU`S1#?33 zkWaDaC(Q^#OrFph3Iz{Y-+;b{R_#uZHty?X7^O>sZ-Fc>)|jMS$>9^kyi?gQ|F@!sou2Jd%T+s*E-U9Rw|)UY?SI z?O6jI2vBIr$PCVGoM|!4$GTpnTxx=`WeStI$)=EiyHJf+t1(5i%^VXO;}ihN$hK5K zKfeaP9{m9j$x|d(S*lb_W;h>b%FP}SmklZe32RuX$L90T&ZAU z|HVTP{T;>v1Duad9hR={auH6WGG{5t$_saDvkgz}2a#4ePHDRF+OE`84OjXorLX<) zUr6qIk>XyYH1OH3eR2zU*dA>ZIJ#I(gUM3L<@_UEDf1}GPd0$xbra!WtPQS*Vfg$xKjx;MQmj@_k0s&^tKEf}| z9ZMKASRhErU(5~!FbA1{GCIH!Ok1~GEhy`t1DE*lrgvn2?66v}EhF z1b|`U57IyMOF*V}v4Q5i8WFe8VBwA3YR(aL7~_QOgAgGCICEWb2lYv%nc~>v;7=g0 zo+!dItWB*H4Fn8e%IvwoJc78NKFWrQS_YKn8aQA6{4={8$W6>cyKBYt@#?t-*K#%J zLp9`wFHr}MiEhWUQn85#XMxwpQa2!A;@5E>&xhxyy^5njWWW0lrwOlX7~~&0Grdw3 zaYn2>SLiVyF{tz#5AXnzG`|ZRrV#zZeB8`5v^WMV9;1McP98)FJa~C{Dlp!*=5b3? zT&z9pnij)m921K+HkAj$mdd~r9=it&55F}D-41NchW#%R1I6nf6!hiiLbl$&(;zMg zXS~{Y!G`EKWkRkTA+`ziC_Wqjp-6~%zgqHZW?iZejwwkeegi-wRM*RyCV)bei-kJ3 zakm?=+$e-AMX&@AWw0C6UvXJRXP7Av63C9E9?)p#A~~9j2Jy%RGf+5hTB4ZYBXX8o zR*0McOHVqdoKw8e>o*$!4-PDXVtP3+YQ8y8vSTLs3*xUsrfAQhjZc@K9P3LO5I!y6-NI`<#5>P&MoE< z-Yud)PRp^)l;#kX*F8`eyYEzicL0|jxV4LE7pmY8v0#)R zZ+kAWxHU1z`v*%!?r#hONCDH_PNV>bC#aBd^aiTUWwd+8JyubEwbX#u+4aLu!Jt;V ziir7DfnL5K4nU#!%&hw~p|aUDl;suT=dgpW$?2ji7J_W`LgzT1aY!tP6G9A^|2!-` z#AY*MXCL0cG-R7&S^ZU~Ov{MSH?!x1jZO(a&nx#AzT^m)d?0!{*JrhpT)XwDva^56 z&C{AWAJo1hy3F1gokI zZt;mJNCGmsx@Q31?M^55Rio}2POono`>0seH8ScRtNCI4;F^%8k9udNSv=#cg{ybw zrGJA-INamLJ}v}9)on|4GMo+l_ggg0Aq7~CWZ7lPA-qr<6VpUa2|5FM?z(W$6K?Q` z8ySO_?KR?xGYK?o-FVppH$R>LHPW3M3*vm82g#oAGJ#St`wsCqd)q_L9hSKt?4WDM zqY#i&5+pEA-5@_U7)EXdqUv&neo>C8PGqdsk!8B!>E^_-e8wDXkWH4~ZQF)F++%S7 z`8%l>qfP7um@IZ@2>_2RXQIHfr{V2aTP&0agaUVP#3`S1^2RJd9U5Eh8iqVx86&~J zOP2#DE_YjSH`-8YiXx^FFeLPkVUYe|L_54D0;k+Re=(QymI2@WLG52op%uM1`vJjU zKZgj~RWo)LN-)cuqS_+_6HpT zn(GJ|MQnU72QcpNmyQ^Hh0hLHyqSCj2RGF7&y%*si|BU`#x7X|F)u}LQ{FyZgxht) z?XHk$uzy^X;hj&Xw(2l%MJHPTczutU2sIOQ3^+oe_Qd02Ul7k5pRw>irL1VaEZ>}2 zPFP^0uo+6;VglbrUFM&?l)Cn_@D!74fdc%E#h7iZN9_VdPx@H}4ef(zVM7@sdP=sI z$sTh$f$rN*N_Bvfl_v7#Y(fnQ!gWW!&0BFXc`IG*>U)fkP{ta(7Xh~odGWP=${%F&+*U{vbNHQt{azSJdDBBDm zqbAC6)3hhMhfxg(jOqi_+)q!w1TthxdohAfbGu^RmG0ocHC4Y(ZFc$6fw?Rif+q0} zOQQ>Zo^DJ%AHHOs=q=kn_sCjo;4n}mvY@<=%TB2bE1^tOu@}bL7Sa(}A1+jZuhR=> z4T9EY?k2%sab*bmqDIAEAKc)8rpUJm`j;rWYHY&d99`f~!G9N&TP_7WuN5 zs9;=Ny~>g21o>W|Qed*9Z-Afpp=2peXv8qt+_tFhReAZM#&hNKIm&sJy}a`6Q} zEoCyX#&y+O-P;8)oMURx2NkT(V|V$OhUQFiMjKB1FaUXuW8cgtWm<3#h6ohOlAs=j zOah}=p0IPFxSqF0dg)L0hp;PxgP-n9r^SqbRf?Ns$@ zPo#}XGZJ{w*BFV>Qr;NUC*ELvXVezc5~fv|b!x1> zs;j%%P96H?gqLR`c5|81W3QIFBVOfn=1D@M>ODX_fB#{k0mZj-64D}?|C^|BQDgGg zDMLWhH}ITxG$SMDs}_g_7Zq2Ad5vfQtRxU#bjfWCy)rTypklgW%rbDkTjiz+c6tPIREZop%R9I6A_ z5`kz~Eis^n6DH9u;>^?avz4R)=OP|ZF5jJ;FIPx42CTS)Y4OXO>p%wlS@=TnLLV6T z0U)g(VZeM`$QeD`30BwXI3O)SCB6AUZa51=IkesG99lw5Fij|b^*+^8?ePIs7!x>k z$3!`{t$1xrO*Y_*c?Hwgl!Ac{b5VUtKjGLu^-y ziuCIZDgd45yL9-*Y0u2gCKi;Rx zW7G_}7E#C`ryT(dLUlfR?8tyzSXK)G>M0gbI!VNzF~+Jc0#dM(TXTcfd=rMSw3ert#eT5bc?F$WtUM>j&J#C zu$W12c*w;DY@S1ik!BC{Y#$-HQ&joD7cTUCnX;n~VK1$JWjGQHj^m zNC4}$!;F%U8oC&Z!!FkAD)E7ZsA6ZDS%PkgCQ+v8Z-P9Y^l>=#VG`7SRN>Fx`o;^u zj)eK46Wd?y0X*?Km1HnY{|5k%KybgBqk-26L9P0+1J(zw_dNZ>sTh}`r#{LAFfk2rE6JXy`60DM6%b%A@@0AijmPG5>fkT z>6QLJ$8)xI@GCWH22i-ntE9gdEGG%D7N&N878p4(7vX9p-gCmSsqaM$k|6LzUAy?C zs`gH&=pT$cO-*pZ1L6ArJTM$;RZEup%*W%eGfu%w+2&lmDf>?01=PD#M((mHuF}BT3oj_qkH5-5Wo#9 zk? z0vmd;*!4P5*|G4hejSoES~NWfr#kalhZVCjzqiDqch}U9)8H9_DtZ4qX`uVa_D@_? zA(`n7XW|NA6&js8-^bh4oPE7a$KlZ^&C93Vle23*Zz^)x^mF0BHED_=^-f3a`hnzJ zr{Yt3)b|PO6gwzo1SK4+ovj(MvI8R*TXi%F5>xmnrCkH5K3m2AbD^ZfA#JANhLUo7 z%@BXD8Ulw2-{KLNiDrEdYW>WXp0zA%1W-5H+5m2B#Jx9?d_kMXt?mYDWhI6TEqHTt z%~_h+@&Ia;Ta!`jRmFa~cOiZdk6kvQ>$!5)kizO^u`ZmHXV3~ScT+z#=mFNL?ojf5 z6ORIl)R3X1G|1w9CVVgCYX_5~;@-Zh!d0{1C6U@HKsErSw6SU<`AU3N3%Vg>W%AHl zQOMDaj>&=8DeRzzRJF-%{x6ft5v#cx;V$7=fccyr=>71MTh;gPK7vRckywrr#!;v{3qF;3a!lyi9$6Fu|lffZCS|q<k0&kei?=(z&e3FEZ#!C%x$U}$=N3MuWBn? zje6IzvZbAJ2wG^P-J`M>O=e(XJHG7PeaWxb_hgeCqSd>%m@zVH59H6m$ANEs zZ1k1OKb1ExZ{G5s=IBgG!d*h68lu8Gi|A1fKXy4kh=1pn{Roo1*XDyJw|M3YgGu8l z4XuGMjQTBmpv*APMfMv5^Hmt_QK59BurV8V)dIxwsjdGE23BNNZ&x3wekVBt~!}%mDDV>B2e4?mu<2U50|$Eo*D9jPgkvH%7}r zKlHOT?ZDMxSj#cSe;5tnX1X#t-0hf=X`UfB3%f&?^Ean6l3@UKe+!o4BjyMoS_SP{ zD8jlq!>o+fh`J-`i_C)zu{aDV`KS_6VpLY z!)@Eju__W3R8>R(0000002kU87zYDNSxGd5i-sF2+2B^{-Zww|C!@R!3nK1RxFYo#2BMm=f-qRJeO9{4p0J+bMwSrT(ck zOOu|Bn365fhV^7=!phLq6N)-nMGGcVQSlJw>MEBma(o1iJT6e?OYEc>)#j;!nbNjd z7$L{LRpE8`Z4uq*oNRU;nl_4fg5D~RnjaK806tt4&cUGvie5D!C=yH36bTt~a&I>Qd-Hr;^=QoM?|=BF91`L_;D zhb%*`nKzifyenOA>tBFb;AvqKHYluv_6m2u%AKC`I?kFPgiuCYTrlN{&3^UEaLA8h z#g%B{%=a__6l>O%a2vMrdhGsdRIb59S%%#0>m1$b__N>wC=aXX|IxD>}OuzkSJRAPu--%icgo1ejfo3{;jBpn)B}hZPVzT~6u zly~Q%Sh(SlGcjhIYy)9?S56rcjW*4iKtfFx;i(=uEj%=q*WOFvQ0kiWlQp>sbWyiP z^YVrMpU=Zc=i#BT_*Y=g5-Mek)GxMNk^gp?BoA4zy9BTx8DVT+-F3at3x$;pFrW5H zZF7>dFh2_T0zF&Lrq>hT>h-79yetv_e$P1q&yHFm$P9_!B-tmJ6@wP`Qu2)yM#Twz z$ItakJrzEk;rLz|zoAhiia@IG!6W3yzit|lOQws))p5;L)g>I}DnU0u$$qXc$++;jD-<%9tcxKwty>c|nN@z!&fj(Ll(>N9K5!(a*P1pKehh ziI4fHl2)GEei4&j!>?~Tv35V>)S$c&H~lxygBmB7xpb+>4KGY1@24q2aVz5gVE&hO z?N=42DZwHT!a%=`m#@Ima{iI8Hk5HoJO$xF2yR+6J=KSMK0&Kty(Zz-p~W_v(AVT? zczfpQn4tip&@+@bLWQglVy8XAP;*J6c`5Td-WkSZ_ODBA(Bs^}rJUUbrJf#_{J0l0 z_eCv|;Wo?RHyYvMpXU%g;~Z*SIT(|_I7^NM!1L(viN6vqGa%M6#Jp70ZyT8`s4rTu z*x?%Z1Dfg#{;7GS{QO$9>v{Kn6QP8T&*9m=J2`X7tvi&GNhCJ=K<;B$aJv(cm{|N-4U0(Yfni~%jH2uM7^%DprFO4_DZ-dD zs|op%ZThY)K{P&QZXm+8jlU--Q+9oukyM5#oq~CSDvXLPzTSif~5X1?d}+|S{*hU{nX-T!dj z|8UuF;k5aF8l!$1&;0df{58nrMt3Wfe^+{aurynIdEyISn73F6B&rQ+pUpKjR)`1= ztpp1Vj`}m#R_<#;zX_(wViY_`soHKJQo9Mv`+2BeF1aB%6{AScPTPfRl*Jc_qAHRS zG>WK3O8_~s&R`Z0pNlU6uKx~26X3N$UQ{l(-V-zUwf+iatxy!npRfVP6YoYsmyrV> zU@fg~AR5uPwy5DUDk@5EY#a}`2&UUYS^+p%wo0! zrC^nPQuqba1(Z>SjoDZ$IalttlFo8H`o8JaUE;CoO*yn1w;Tjl1^wC>DJ*I|No_4t zFh`eOY{ag_7R@mssQaP?u!pjmL538E#3h^Kr!G=bKFRl7socwgKsao1Tw(4F*zq436Y}#{A+PSM zlC>!T$?cVusyYD#<9HV7%5RGA`vq{H<#n;}J)8r0|2^MbQCR32?DMuEVJ3B4R@gq8 zavf-L5wa^bB3g<1R2_5ECLJFOMXC*NiX8Wl9X9SB<5ZKDPiK21%#iJMEKuMXXZAmZ z_Wl|~nW*a%Z;I#(_?VdErgzFfr=xuZG!%0P>JZl%43H>iMBz$vqH>PRk9sU%KC>t0 z6eEtR28h15&Op59d1nNgo_r+J<}{TuZBk;2&?PQfWeVmDJk+vfR3}L6o0#R&H*D9R!VyH+~>K6lt8gz0}ke*a$sNo9r%jIUPAQ= zn^sZe@*arQ|9RHQNt#gL3)x=*)isS&X$v3IU-W^8@K8-btTq(#m)0=rNJBAcmpjeq;33LvJb|VIdZ_~cVt^Pf4u0AEqtVv#cz$Una8od3 zp1j698?`E1{$d44<~19)UREA4i}|!gUFaS>fzE!z{MSHM+In;wtduqMpeNV^vmcFi z6uu|WE^A~&_S9?oXb&h**Ps4a927>|hR@0c5-Z(+R)IIGd>Ewy8j-8@&fz5%2JI|h zxnKs(p8Js+M5(kmRWw@o68zTN+uhtYiY)e~<-6PY<6t=P`lP9-{6SQ2WL8V26`e~N z<@QwvxmeZn$r(Cl>*W)vmYLTv3FZWerU5(lJ>}jFl&ue65*=>u+0ac-$aaQq9ib1i zATfVSyP47zCSYDAfSu2D=)KvoxGXGn3ua&Iq+}4Uuh}&VIymVPtu0QGhBL{N#X&*9{u^sf93hJo}zd9l__Os z4O2nzE}(cdIQl!XMhop9e$Is6xI&o2tA^qDwt$QtxZwQwt&U!L3RN!sv!4S-5$h(s zJx>*j(cc^J(I#s|OR`PwZo@_~w?5r?)0VO1ncq68mjZy)%}{sArn#WXn?ol}-A-u} zpUMb9i{ffkYCNHcNWucq$_RH^ddFPwN|3JEi$r))P}PYo*0o3jf(eUj22&*?aDw4$ z>qGeZ7D3{b&L_rDFV-?XN3HX`?n}!lSJc7me2=7l$W>TZAI7z1#H;wAdB*}YK099@ zXsGn>7kcv;%lT6SBC*Ww>&bbu5cKq;grBKuApl=ZuXW`(1AWKEaS?l}u+BQs1 zH|yi)q&>p2NwvzvJapq1rcKhr9+L&qpEu8d7a6!8qTFs?BM6^4|mSVtX z8cLP{U`kXAYMxecmlTpblojhOm3K+2-_l}`XLMrUs@C2AWibu;g-bD?BO(Fr(n)|Z zy0|BC{M!Y-TWTMZeXS>k&`TO9u6s!2U5wR_=~S+h%!d8C?!i!8$8d8^SsGCkU*Lvs zlD!_()55qJNF|Yt^#oW8u7Vz-Rc_NLTJMO&?Ndfd90k?CDBFUCMhJ*m)HXU53p|85 zd2;o1(aXII*s6)w#{tp$x`ZMVW-yQepog-Ws`5yYXr0Em_8CYw;*KourT3IebC%d1 z$5k2Tm%Sf?nk}i`gN)>EQdJ`hFa01NPN9oq6g2{4gp_*|O?)&!6eylhaqSY@f#dZ3 z4+};vJ)i$~ZzU4H)1?ljWPu&KP8v^^Hkz5VyTBrbKmY&$00003nA*H@^AQiML@$C> zv$hrlC!@jwVX(mkuI^FqV4WUwM(-J^bQ8k2M?vLey^ z000001|3%g<&e!GN`Rj}f$OxTRaI1<-zVl;h!VN@Dxw6@ak0q6IXy?B6a9N-rX6v= z3$kkBmaq@}FfaYqdkrEoS!i$`IrDdxMXDr-1gYs9pd<*xPh)2$@DKnn0000K7g91_ zu)_Bz<%ER2BmzeE2Xw);=7UbzEpMxCtKr|%HcRvv^#(bL)tBOdJ`1@9cu*ebw}wj9 zT`k{yoowaa(jsV4%-0kua<9J%gok8Y=p`L>7h@f@4#(p9u!U!Z)`NXyLQlS)_)8>| zbu;iGqa+$+Lm|YyBv@>7x8$?#+ z5fnO~Ug;%Kzi~Rv_HXsHYza2M8UH@C_ z$Xr;lE7EI|xBRTlg2Kg>M;+lKS-%naW%yf+k%18_5C16E&-oJ$W||*$XaMXe=PNxB zeWSBp*YQ9A0004R7u-P_m2KN;VC=6az&c^}u?w?+wxiUL%55v09$|LQW!-lFKdNgU zXzRX)v7_?D5q8Jx7pcB>u196KAWM8jZWe693LaF6G=w*;OrkcDhP(fL9c;Xy2zFUx z>ZLHdJevBK{@L?+PHRf^Xo*{cF@njtMq7GvK8!H~&@epM_$uHghXgeyXC#$C`p)l> z_L5E5nNuGV^Lb~`^ckH)C=&(rVk$NO{W-9o(KqY`MYiLO6M!Wl zh-u@zxh{XYks9*K_Bo9N2)4I?yW{CUSb~6Q{MHdB?>#C!;R-6a#CZ7 za-FzXZK=eJOK{Nl@xg(K#X~4Y35r_2=K_m4CSwe7%$Jq6gvGN7-YT-ZiLhNoy5t8d zsB0B2sgQ=lThjRf@9PaML!b4AZzXi0%?~2eO+yQJyy`SyG(T4e7S3DskzMS4qx2j) z2k3wPQeq)iIp*61?(BSJHDYk^h&k$mEN$*F5Iq4KfstX)yIDV}R3=H?pd1Utz~FY= zKmTnebpIS@%lycyW+f4e(vXD3tdkyP_7Bsu1p}(DS8@7yTqPo7lf<7X!!E zm`ooGA>5?+{360T>2UZjXO=DdHBp{Q zK)w`GSd9nvJ?i$qb(EK+7~4rB{mEE!3bcHk%7cX65lOYrSpw7hnLt|n-&V|?JTjBX z$=Amnyu1O~IL|VyW!Q#)B4+ru&*zj>_;FF$$ctgpU_$SsZ3UM<)M3NXhf{xoT44+X z0~Ga~kga_eC@19JwH*7*W0@sz z>p|3N`_C-TxYPd(zl_DHPck=6fDF7MbCZ?w=rQaw=B{#S9MbkaA3c)o+&H+BL@lH& z<};};>U`CSrJNI+tgG#=#KY!zd+V>FtKFjv}~2=iS#4;QEQlxJ5&Hx%8?PLODb)$cBv);_NjM zF+^L(7$cTjt>-%-y>TzxjW9L`M3MLgtKcD4j#1w0RA=r9zfK!c+iF zy-#<#X2J+o5_QP?q?q_jx^YbJ^){k2_g?q!%9HQ9W+Bn83UdHs0Eh9cXg^Pb1P)nj)i(ayRQ`mF487g@Bdyg73R^+wRKEkgKb8 zBo^>%lT^-W{(L{)A8~D4)Bn#JP2D?1e%i^)Frt=RyF-9dFCHVO-(Ce87s%W zkbD=-?iSb`bfYomNX%(Rm|ED4rwV1Y4NSfDYLBF!lu_Rrl*Cmo9pi<_q^SPT9L1fJ zrx%^aHQ?=~W&w|)tr&SBF}Pwv)>FQpR7^wZe?wf1r}Ir+Uno?{Wsn&7m0ld8#`)kz zM!>Z&+D@Ycu#!SYiFXMS5iq=358vq$<3VM3H!iP|C2qo`F^%!C5+yO&R!5MW6y1V#`N*LSvtZxb~^5md6l)wah`bQ&p1YQDShEKnvKCNtsozuvamo2H~2Ezvx(MTv@Yxe?GIY`$2h z6UvFT4n1qMY7??DK}7c6>cKQ7m+}rKj`|aIq{u^=pH)Hr~SMbJtNdhgs0ISS&GB@q)kPo<*QIcPAwA{Cr9ah+P~h&fKtIIc1# ztn}>8ZkT7fq4RDd@WALHY*6mZ-{w!;hqD$R!=s_?R+i3;6l~AS>}h%C{vPjwCB=o{ zNLP78LqZ$+2tZu_a7iLFLW&VI_auKg>e(VLLr{i0GTTF>#D5Hi=rEk*SmwHj+!l+} zxMuuG0T5^4o}me3_g^@*84wD50C@0NuYL(_o!Bv0_Py?D*NCwKM$GNY$S<>%ZSq5T ztT^r#Fw0P+SYSxAR2UhhC3v1WO=q3GaMR^uK8A-#`c3yg&&YPsFb~TDkHQu~VudTo+bYnSM^JX}wt`{|ejI-XHKSupdW?l|qoO z|7MC&Vmv(Ol#yNRJKX~RMdnW()e!$hlEX6r{dZ}NHIxA#V$Tyzlo^}Qw=H`2q=Ifn zXF8O81NLqf<5i(^m)s&o_HemS5GbB!@PTv8@Z|0|>PF%4&P$&X-r0a$wS+lBZCYYD zHmpBoeh)XnQBGK&=H%im>8yNP3IN)?m!COz6tBLM%wxUg3)F$E;~{(rqTddxqbf6P z5#&v_6Gv;pxa+~mQiQ_o%-{&7aQC!WbstjV0jjmF?=kS-q*Dfk1H#o6Rl7!-wFBJX zKO}{UBaH(eJv+!sXOC%Xq0mh1KW|^^q0s`dCH4p!x_^VAT@mGoxCXyj5qby2H|9Tg zSv<8*l&9Q2zxbqjB*Btm z34y9GJOFO1Kmy6Ba@M!JJu{!#SDdE1uY8L&w)b`e19Ff|;^}#sV{%*AocG-M8IhqnG?`kb>S#h}84L;HcwZ(5`i!h5%2G z-xzF`r`=J2=S#mvRb?W`V}kCLw?8)wQjQ9s+`{v5(4EOat?Hp*SVu8+k2o@w`|v|1 z<1{w$w8IQw_XNn3d_ikEx8ZH(T_M~Eaw&SLLlmCaxHWB2-p#z|(LzLd642mJ4$1jS zv({1iPfgM`!Qup6Gz(ZVqu3bQJXVybZAm6Z7T-}_1e`nQeDyR_=O2Q z)@|!$e?h0(4JuVJ<3+@i>CW#IUREPak&O`i=u@BgA7)2q`{&rGZOPj|`W2-XnTy#H z)`v$Y{~?Otp+gjz$o^~ak@Io1qJkme2COL!1S<0+J?w?uR@P6fM{hO4>pGe}e*bxlh0gp{Xkh`t?r zoEKTpEOKZjN2ao)aBw3w%%jN_k#D+J+b&qj;2E>l8y*L~@ULHtEQN|+2_p;f7I$A9 z2gdkQwx?H9A?N1Mb`OCJpNRT?JFe%6}2TJPJWdDze7MmQ{vbW;Cm9 zsTuUAMj@RSu9Ba`QA4%dLX4>BLJ3G@<_2{8+JBGKYOk4lw4`bLH~GUq>mAPB$63ZdLtI|v%kq@!WiIpj?a$tDS9Pgh4I*(re>tzX(&&59g+ zKkfj|+3^!F5ISvdQWq>WPI^)!m3O$Y3$shy?{Ob=`bxPDrOHl2b=gb6qNDPHaH!Sb zJhxeb81TEZh}y_ETTeAA5OplbvLF?qxf#N~1wCK<^z12aXMCc_>jR!$&JrY$CClF# zyM98(2~neSruKc+KDKQe`u4Br(wU_+L$Lw{3x8obWL7h4t-;b`cf639pWpvMF)Uz? zR;RR2;g}7AkkgHz^_8&QRIq6}=@NDqcGKv%oQxJ@)Lfb0B8W8`IYiQXw0xzEW;mdi zCQE<-7)T7Iu#h}sL$J=T1xwwQ#-By1-BW%4CDRpyXj;AEF%y7u$zL{z{j{y}WU|*V zlz{i+AaMxb-nersMQo2HKkU$H!2B~hQhE>mVu}{|7znaVDHeEc@{vN#-{j#pG&pG4#wI&x6vQ|8|Vps!U67jwch5xN($g zaa3UcOS4Ae_bG+*m-x$*e=J^S(=yi`oj`1B1g}t?IQfCOn5}KG{aJ&M2M#JhZv#+B zfq#Cjxl?03ajzX+-06gv$%bSq@b{<%JFq#VPa3gVk__;XOAJ2AGJ3mzxZviyVzeu( z_IvD_CbdErocbTQ2RsJRU{oUrTVgz8KhXbq48@6i>7sN{nP(UGAJKOfruwsZg_mP&bSo&TG zY3EE(!-*eqU&5Qk-;t<@p3n30dpovz904$pMNMHKW?315O-vE9FfCw@mE&OdaudBp zh>qo+F2h{%y1Bx%pEV}ybqTnn??$z%Ihhq?YtOI+De2b~Y`@dmP`PkLeBhUNC6*4Q zeSQ@?Hq#p~s_9baXI4#Qf@a;f(~ojWcam^ZXTHn#=E3Zr$kss8p8&8S>6kSEL|$5O z#s()ZVOEd>y~;dAU-?t2c^+AxjkUp7uY;06-Z!ZO`g#~x9IZxY?mf^wp;Ruar!5&V z0RHYG>I?@R=2?@-ZEm@)MY~99J&@^h^ckc zXZ&pB8;35>1%F>4_#w>9sT3t;b8q^5K}2kyh1QdzV?*w8*#atW02{X;fb;?MVhH$c zKmgQ}xR)>t-NXNV*VNHP2Q#WZA1Ke$QQ-o9RP!xOZ1krOi3X7Fx(R^zRL zElKjO!PIlLBHMVfoMa`*2w#+&ZMNHOw%cvC+c(h1imjAwhZGtmTX&|RnJGkNQdNh>fE{~zh#J4f0pndr$|qyE=0 zqUu!l8ifOcxr1Ft;02XzvGeuMts@JCS4Lz~`Hm=FF$Sx(N~Jvr#}Y_%vn2GnJ~Bar zH!u$bx`J-fhp#)W?daaKE3WE!|6y6MfSitm%k4DcHP-4Y*)hSlu?a;N$lD35H<+kx7Kx! z{y}yz4I4j_~O=|R2{OzwU>mQAM&*@9V7fD`%#}0uNz)ZHFh76Vs-?wDYl_ zPLuysDH`yD`bkXE{h7y&edYrTO@A)MbX!ihOg!|6{PrgYw^Hf;%{4;ChRKpnR{rC6 zSFlG^W9)2rKM03*Au774rNQt$f}>k$WnjxF-D}0m!$%TM2(d^quCuQKwojhtaFPTX zJ)>CKcJAF0;8aD~S>=2n^Y{%L7)sjN+9{X96!%VguPcJ6KtlJnYoG&`B^Q(pBFa^2 zD$h4k2{kE?iI4M|voFtu8UmN@96 zHYsY{Y0o23?^)YFiKu&{y=Fls?wnDuq}6N&oW;C`5ez5Vis6Qg@=*smy*Im&2Nx|luP7%`uP&D=P-mK%7g z@i`nj=}m_+KmziiUq-wxOSsWPSAR7Qn#v|d2Dz!P4gtb2n7TvEm_ItI*dAZPd6Qo~ zq{#-)`uRY+T*mi4*+5gr=y^~A9tTs=(uT;nJ zGriq3$!cLPqe?z@SoGd>3e_B{{nY+pP=0ABi?Yg)kPDTXt&Ck(l8Tn;QFo``5kGp* z#-41T#`Y9+JiXruXyjhOWNM2;`IU8ERlLPUNfI0~&+1EMX5qXcQn^!p`*c^Rs~2i@ zU9~q*M8@^Id~gL^z7AWDkq$rWg+-OboZgXhen&?y>2ck759BQ?qe%aM;*5ziohDmd zk}dxr>zPJWw&_nT4x<%+YVe6QJGT63z9Ay87qShD6F2UTx07!&zFdf1E3krLB(DQ3 zzmvADXLbUrc)QP>*w2%)$W9Y+^$97rT(N3{opcu{euTit(q7KVh}<{;lCdLOKsDpn zxL;E?R_i(bolkgau5r7MdlI$wfn_C-xKjhRSY6c&V*WJJ2h4xTyMF~qhQyjKV2uLU zlu|N%K9;N@Za=qhL~-14>~wQ|`o09neGL%n((${f$>>7Oc$etA%;cB*b-f(Izfy-> z77LUF2j%ydu1c04F16?kv79;bl51^JmON9UTM?Mx3GMD|g{K!5x<8(IHGbm>huK+* z^=Ak_H8{(zaymO%DMx6_uB;tE3StdZVw$(Te&g`l-C+$sK!rPu^?ci^GHUVeXDm7X zm)d`;b-cy=ur4@%FFUgVY5L3Rq#k|F_}i?USU|A9*1_B_eY6QiR_AyW|9|Fc1#0;e z5LI6`+M?<9xU#fJMAJzExzK%{c}PO>CtlI*Hb(J7CIXv6ut&zaqfYlRh&EPR(|FtXPWM**Y1yJhhHpVlVcrywB8}i62k|E>mDhlb z;pt};0<3ShRS{%OL6qK}pT0DKs-0so*R{Uzc3@+uO z@6v*YCl*Pyo4Jn9SvwE+l74V*t&z5+%kBWp4=(Za4ePNLHj`VW-dwmxmKDQz_`qH zM^o?@*3(e#zHd(BuCGj)gH|Mo_C_h+$FxyV3$DcZi+0^Udg=KCX)e^_*%NF59EVLG zS8=i+WU-1&lUe&?r|C!l;If(aq|V4?alKO6XgLxnp9Sv{xE&%ce|mRd%k&W+TE-Pe_g?=RhZr?}mhq-BG$E z@&L$(`01rl{e;7Fa@wPy#+c`;B}g!lc=B=JWB$O6H~(oyt5Y6a2^8*~x7>m@a`GWd ztjkvvut1BBIeMPDV9H1#Ta@}&Poc|H6O;K~1>(%-DzZd2eGTBFDfF|L(ajFDuN;U=nVc62gHj&<{7W{a%;FX(DH`q23 zKLfn-uY#xTbf|CIjrfoCOuXjqF zb)_nH%usCXTl~>%tprCM0x}Y`;ZT)#L*Fq`QG;XV*x~U+bc__df9t*xGNO#r|3wlieqxwe$wL(Ii43t}{38{0|dvina3m1xM7P zyu9%rbmQ7#XIw-HECq6dm7-6IeH69MMa*O6B6MfPX(8z~pi?n4N~p6# z^;^L>)Yod4Qt8_&PsM(+ne4>G(&ZltQ~4u>w7BV=NuO?2O0ml4OHjDFY@tThn(aDY z)he3*K&{#1+V1g1>GV80Mi93BBWCM0@=x0*V~E6J3|`?ii*U;s7|tZ- zp7WMEQ-2bK+1J{asyoZfVhnh%w$Y0x+(2scn&wK$4QSgJm?QQ^2RyYjr5NIa-)2rt zhf2ALtLff3>TvYeq-O@Uh@X)lBN0DDyFYQk4DC`9_e&r&KAW;oIv~dP(XY>e-#4HL zb=Jo1_`o&0a0C905y=LMUfC5ssG?3f2Du4|wK@&!hgio$j=Cn(*`r-Zbz@yIrk+A} z!b3MJmJb*A$_coWQ*lY8@_*`WUV;pzS=7ec2sw46QF|9&u%6Y#{Hj+8FWQvb{=JKCyzn^gGPJR zB5m9;_IUQk3!Qvgb{Ui?q$(i-W?~+{GxXr-(cYKY%N5*uD^3Zq8h*?zf4_`su)SB) z4kan~!6PkMb+k=Z!jQ!fB_@P37@JbUlgRB?!nB{e#^9yHK10~+tN_D4cgjyTp62P{ z`6ELZl|*TvTaGmt{#y4q%SuYz{*wiCpGn&;*zO*dr+m9KOL=)Z!V!UVi^d#Po|?S_lwdLhqz znCkyazyWn306H!v*H$-N&Nmq06NOtZQFn8%22@A=`ELFlBe0!kJ8Mg)hyE6dAs_q2EZ>$_k%D8;NkWW9kWE54|F#P4+wg_-x)T7rG>GeXK2V}>0GM!VH<*lD%hukF>!9O44H2-ARhf8k|2%MLTcp3;j!VeTBz7MGq~diMLf6}ZKXijm6$cdW2?MCqI>{Ne@;*yk8IpVn(#6Q` zCrFSaKt4;#@jWVyjmkgOH5u=~{s10(;}-+%7JDIr;6?|z7r98 z*}$`Had(7QJFH-DMq2<3000000L*Bl+b6FyL5sPOAt?@SkY9Gf@q7_7{wTwN7D*`F zk3x}uv}nKA{6mDMyT^R0A)B7u{!Gq9E!od`gY&b(*n$3+;U-aJRhd z5k}YiMSndhQkB!P;ilW@$Me@?G)J^3FmQXn&moJF-9}aP-eBMqmNYva? z_(rJZ+O%D1!#QI36RzXb=cbA?k*q1TwwAWVZTL1@hn+p4*IM@+AS6`(6Zyu|kSF|# z9`tV@vt~K(y=*OEm@S~&vi1wC?J~H+B%*o{RN`TQe2bWZ#)oh`xJRl_dS_4o025CH zVd>qMsLK#s=(Jr1!p-JFSGb*bH7#S9fLYuAO7G7%0vM4Gw-wWm!$I3Dr6iN|)PU0T z+GwF)tkj6(K|_R^M&*&5ZCs=$;0V~8G7Qb-v5D|ew(&jVOa0qzTF8T5L8I>iq(bKC z#;CZxAtTgdkd^|e(MgxJaYf8b_>Whn%1W_=<@>kgo{a5Sg~#wiGedzmm;jq z!Vsv!g>8s&E8JJ+oJhDHZhh;^xD1&@xrUWNs)5x~mosA`P+k8m7S+|^*Sc#*pLhKE zBaTRP0D)pFPpvQ<0s=k_zN47MUQ*L1!`0p@$WL%IyxEtUI6~qXnAa$YHR{XOcX?oR z4~9PL>`0@5o!adcj%9+9r3%85Y6~LS`dkn~Ew0D4rR0q`#0d(lwx;bLz8saK<3%~Z zn<^+pXl^y#iD~X0QgpV$p0N`+AnhTt`@X>z7UX+X60YaXW=-kPp4}}tKxcuuL+PBL z{RuW&RuzZz94Tr)_oc1%<$*%0;%9B*k${UK-t8?>EetMnh|Q0w4NwT7FMJ53vP*E~ zTo#1Sr?C*(Y|^gjN__FMD2NN^T}m4jGiGC@qwG1_`aJtzFI{{;!43kyHV{XbrE*Rm zkT2}*NKF#B0R!V(;^>`OHyWg*WSx#$AM_7+gD?W6HT)m`MpcBp(%#OiU&-nm{F^Eg(M%9;hoyid{| zVnC~GaA#$Bs8+M7{BE4-rk6LAAJ!fTvMZVjfs*^;za~n|YQDQbCh}L%N?;&C&l@!L zg;iGx=+jIUuhR0te_Ii#^4h@iBb{`6RN3$RV&T-G3w>SVDvwFcU}bAgb)9{D=SkZ! z*`R8Wb8Z<^{EUk2(>|8B3oPY@EkkzK+mR-A0eXFV*HMF;O?a$Bi%EkFk}kc?F3H{U zV+-9@E>uY!pzIVL>Bf$^1fAm3xFp55r~rQrMp>bs`G#6e`OJDHu46RsIU(S!A`#s(OgwwwwJ&#~AY_1; zaENR&?A?ahf9pmQyUV$$KfU95&xmbd z8PA%t=i+SDCMannGWETsp1U@CZm{bSRwEzx>%(;{QMpEd!;}F3u)EX=Eb%NtK+1;s%jIhxM+Z z!oT}_eBe@dWx7mr_t`o0%XC?GA%WcXiMtv^c*(fumYoI5a@8&4VgbJKjA%)u5S=PH zZsZ?Lv(V5;87x&A_7BgG)0r6k*#4Jrw^UXcy$bqZDo&dF;C!*?E?9-b+rqkm(i`N3 z=T+pnq%96929#&c&T|f=sF+LrZmEx*-GEfU9vGbo&4CD0FZuEP}fD=B3RMufnsLR}q zrS>n1@b^iamrAnRS+crS50qi{wWZ3qA4Hb8;#R-ccmQ|>n>g00%IF&99S-~C%w`}I z1E`2Q?EZCuov5P6y)>353(7C8=l(aaOSbVY{%Mu|{&GXGaXt_C=UymFzr_RPz|-; zFN>QXnx5o&@I)pijwbDvURZfzLlyr*rfIh!y^I+WaXWRRvxVM1aH-q4l+rOKci-gJ z4oA)Jaex67r`-X=et&6N&^LohUk-O0Y>;l6`nwaLIm{}9L##oZkM$UzZ+WsqGM9nYR)%$PfOj=2vU{KQA&Qtd~y)ghw zKJAoxILaQ_`C8ajUKB*76esA|ySY7a6Im|LDvvZ(P~IQIUhmc1m-LviZwK^hb5Ya_ z*ME`lV-xRH4x0*97gSpD5q=})6UeU~pH+yYs?e~{OGG3l`Ox7o{)asxRVG{(90!Q0 zd0eDr4W zTfS|%%Z<8$h&nK!WncK4mn9xL55YR+!689#E$!vvX^T!9=!q<4uW<^yV{^DV=iUR( zpMSn6a{?z)RlQ8Y;$pAxoDt99e$%y4&b3XNIU5`!AFQ3eL@H3!r&SWeye>ha_XIuw zu9Nv|@KW^dO!HEOdqqFc19O%REtw!~zL$}$KxQkAVeQfL z4z0^ENzkm>ZLfPqSr6Mu8|KQ8JNzUK*|EnHILI_6FoA$FSNz{WRXGC`b^CVz$}as9 zC9!R-STwE!&~-|w z3kdW^f^c+T5Z7H(FK*s|I0D)I62j*9RR|L)r!~;5qJ!TH* z+^c5Wze9yr!KtHSJ6kD`Qw7dP>6tTIw$&8KvU0$J2p4dHAx4GKvP9vedsO8>X0!`g zk{P*6B7YzmsrBi!gM1lP*El4n$|(5&6j}!Gg?}k8S_H4njE_fZ62&YaRLpN9fmQdq z6gRtu+bWV$@SFN^)ik=fJN<)oVjxeIYiH;r{3cSGz0!75Zv~I5+ZH=x4bGXpy)Jsy zBru9}H2+TYFpExM4{HbhR&7QGq}A%TE8RkvbBDYB;y97SEEnZR&G#KxGe{h{UwL}* zSxYn_3wSho)UX8F)P?o!#kc7}q(_m9MAi(GB(0{}!R?c-_poqz>Z8m;+K8$nW|`yU zQp2U6rj0BIgq*d-g%9eXZwMBg2a)HSW5xr(kiUB?E5ne`i>^UZ(&|1QqCTk6X7B9~ z>KNbhUKAUIf_i9Qv@5D4k4Kip;ioCyHM9AXfRU8Kne_6nA9q4co<8>`CE&ots@}r6 z^2>UWikM~>i$Q3ZhNceCi;(liRZt{kUe$gy|8s&nc9H-tu=q=;OdfA zR4j$uB%qA6R|+T3S5{|Cy$IhVIjw424mhb8?l4^2ZI}53_OQ!6*3#GjWz<4-i5@=b zwXVo-ntEP!)7BAvx=??>h5Y)Ix@V)VPG7pWqk00vZkzr#1Ha<_fR5~(l>C?({FpiY z;N_8Tv@Be$pTaeoZM5)wxSj)7`Egsl)%&sDoVYlBUU7JzG`&ajht%fTF6`LO3f^{^ zZ8U#=xK@Jq_dL`VJmkieN4>2BoEwvYZ-2|R1!^2;*`l@yf^y)q4xrhLKg0YH9~NuP zhuQHFBw$kTxBB;W|7Y__W;ylj*gxA>h^e9xZW}Ii_A|-$2jB!jyhQ=Rk!e6vFSq8e z_jJNmo1~!V)T^jcN-!Z$2b-5z3{AQ6Co-f@D#`U0I z`O|gqY@t1B>RoJ-x|*!T8YfgKO~mgol=5>A!tfl3x&%ZPVOB0x{Mqvq3QFA~Esdv> zsRgm7b>7@#29A<()3!&(HxdAgy?9B`Z6 zVy#Qn;n=;&ZJzVRESDkj;bnFVxV{ALCZxeQW7DBNToYS@AM`1DWi*DXRav zuvx?_!%6D{J!PsV1MH*$U}NdDX{bEax;`Jor^tDt8 zIN*Czk?+eE!4qvhGlCErJf$!hy|F??!IM zVRL>4F|-a}FqXlDG;WUG&l_=v70WLGfi#S^UdKZfSDh=4bGE@ed<_9~qh^u)qP~=F zwKNyeFmcnfq&HJ`RQN$ipG4$cL-zdTJ`Y&mqfh_9|E&l=9yRDW)F;Dw=@!B%EjY4} zG`)HOQ6Gl2qm-RMQupvPW8)EOaTn-X&Z{4%nGXCUG(cItluv~h6$(HK*4BxOdY!&7 zMW04@kpq9K&@Zdux#PZ-9C~WkD$$YV#bosi%l5E|^=~YCO%kcsAn;2ack-@=@`w>O z9b6oBR7zy|knb96`gGWx=>a4--jj7I+&i@p0P(C>a@r$)8~4XMkMFCtzITlsgkG}a zI^v<(!Ecc3G&>LmYvr`jm7;JenGel8wyWj22eo{i?*`~wvUGx1*zg%!?oJ)*Ar;sw zCD!rly6D??rNfSbN`W4SsM`z*BcJ&22oqk;Ps6uF+}+~5WTGj6;WJwkQp(v0A~{c<)P1;6hyFsF_SY_n7&z|_ z7AIN?-*VoAd9tM)mxE%&6tCu(M^>5U_mj2%gHtx6p{esQ(_`jiZX~gT6h11~_-H6G%yK zz(?ePYd5hhcQpzO*n^h10y8;de3|yc{$UHvMFBG|n@aK!jXuDtnFKg4^xTTxUh7e( z1aSJX0=2<4u?um$KneOf+&rg;xxlD)J)(AwN)8STSUY0n2iTrH{WK|pmfKo! z#(4c7ZWbJ{ggG6lJ1|*fmyx*EOKCE?!H3ujD}QFh?l7stpmp%V6={}EJgJ8}Q{c&^ zT#<=~HBx0f;iQoWN};2adU9bBo=x^hz)n45*L@z+0vZxj3GtG=oPd8h*5)ge zu`l*=vF;@yV%^*ay~AX(Mf75x*1p}AiW=e5aTUj42=9~tl;^A6d!D1ZY8ICw_b>|f z@Yu^v+saTyc<<9iphuF0?c`=gA5`v;qYk^pQ_x}&6+~bJ#Q;(1V3wdlGO4ks{Rb5r zSGtiMLdDbmCo@rLa5P1~Gm$YmUnQu~G|!3Y4@G$$d^zdY7xNv5ylgsS}#(GVOXY z08r`v+5|j9y3$KFOCL@yZ+q8A>+XU16{qr)R{)}J8<5-`BE3|KsBq;IB=kR-QD)n^ z57a)zo#fQ`!K(_MSMsY8^#ztmuhR6Be9IbZZhp0h{~MnbYWgGQWNZt{VL*lsiq029 zw4XiDbN7h+aO~=GE6v?C)JWSdA?(|CFTlOXI^McgX|+$yYzjp^pq9~#CB{h6FM51< z=?ekX*Wu_XCU&4N-zv3`b^Ey(cWDtJb?BIP-?i1Kf&E-JHqiKNhltA#Av2NK5D(2DaB_CCo zY*b9PNnt}TE5e7-j3vjveY$dO8N`PmZw_0j$4tCf>oE#y;c(DQ;73&t-$)K4BphlM zN7K+jCCURnCv-Uv=Pg<V|ATuQ~Qp1h5B+UrH~k5dM%uDGrN$W(u6fs8^}P58R_5kn|;I3Qgp zo}y&97c)VK>VDu*<@`TIWiKVB~23zIqX{)FiLNMs8O z0Rm}>`faWmlfF0Xm`1nhZx6t|0<_1Q>8Z>?4q>34H8672TR_HbKYw?H3uvD{nFb}9 z3N=e0D(GCeYVdO4`j`~U-MRs^RI`*O=h{2F(cx4U{S!96;884d^f6B>|# zri;Ca6o?K{9T^cZ;NK-qtBXl=OV* zlD22YDfN|`BfOLgcNbkJ1J})LiNq%}LPM?;H#6G@qBb&wz`RCOTcN%(Az1apE$NgK zOx806>O7xk9vnPDD4u5b$ga@8wl$QRnw^(VolybC%6{n3+&dlD(#E~aAlgYM zXY9=^xe<(epQ1r35Kw3e_h*P#pB4asA+%sLw!`Khe*B7mAQ3w~!EZB48e7ozr5g-X z;y$A9_V)~ihMuI#Fh9yF?1Z6*Ov3r3WsEyqQX`^$`{Y%z6L+`LM%0F>WZR&(Yhi4f z81foYhg&obW&Jltex|P?T%C_M#m_GHBfw$RuqG=-SOjfjNZjdgyBMYoCbSa_Vlm2Y zJYi`621uxx3F-)s)@vjnfu8({Cb@;&G7GJh;|`P{EYiPDgYwXloQ@1c2lCcH5M+SV7M?LBojRKKdaj(g4mrHyI;`#6N+_ zKIsn?FL}+A2U~!>IOdNU_6aLl`ePD#nnjJheuY-o74oY5t7i}X=j2rAFncn`d^MRD zsoH^zD5)A7M|YIsHt;X!3~#HB@%UN3>7D&O0%?pNavD}1?kn5~^(kPI;p0ysd>~05+VrXNE9K z?x(@2I^P~(Ceu|ofrIYx(HZGg8Q-#HdqRQ5U%aKawe$B{3LsGzr*JdtRDg->+8@4V zvc*nOAfvd@F|xmZz!11C7-EXtL(H&_lD?pN#L>iCX3LGzY8k&-lwE6DmVbQJQR9rK zPA$pKEndqsu3?W2Gky6_(gsiLq0&o+n2N7Nzayy7VvC03FlD@Tn)Kuc1VWf;6JQ^j zqWnb7#@M#AM#>c{(XgB(BF2}IK0^5#AD3nWts|z26Z5{&)(w(8;t2cgYkebl{v4j9;m8#iA@yd zO@zy%>Pu=08Dp}swlTL8*Z6LLJQPDph+ijip2V^}yIL7D;O@zbl-RcA!ATaU;zLc` zk7Y2AIZ+HlF|StCe7h!rBoo-|Sa;|>~L#r#4*{cIVOVv7<{ZSH99-<(NX-8)sWz>_Ex))YY-U9o7i_q=hR-?JxTmSnVsCcj*&|GxYy?GD9C4Q()J2Bzqy9G*LE zEQd;hcq1WNdX-62*t@6~*q_1l`-RkX(_x5vVQkyqs=4q_t4T$S8UNxUOSmwki;Jf! z7CrmvOBpuR4D9?<8}%|xO#%D;1f_qt@lqiYS~ucrS123t&zUl&h6EVm;(;3lm;y}u zAu>(>meX}4k$ihNgE!(1ESHf)c8Y{6=Vu~g`Tm87{Q*pR2dHEKmvm*qaYruRUryVA z&`V?(`$eSxr{S_yd?X%wBKbem#-QZ>J_TK_UFgq_1Q_BIgr^m5+EY~ixA`43aA~F= z%G&g74Ba53bgV&xOl*~6bA7|@OM79SKvVkkc=jBWIQis3vhj<@hX2Uuez+B$gFrhw zb9o>JSG@GKH4A#irg$8O;mt2%DI&ah%B=Yi(qD~(utYM-(`|6#Ii@dQzjo~uT%P?H z#Q{%5BQUMFl#3RiP%H~Jp#CLQ9$N1)*noOJmyc?Nih)xQ;PNSn)6L@2 z3RsH=G{s}tuwD#;t+wfWJ$BrTe*RoXSEv`-z9^(g8fY3&eUJ_^A;JvZFqQ^hv5;qm zU-gjDmp5M2945Z4i_O!-djpE=;6C6n2hqfoeZSk7*Lgc_yHh%&jLL8M7*AGu@y6&+_In!N^A#g?<+E+%JQqZTlg zX3fT540M*!s!X(Wi#|Fq^IoZqi~GEMWkwrtBK0Pr0Ot_5xQg3u+X{0cfZH_uZ~&E* zQ4IO9qApB}0f~|is zkK8KukbJKz$fwsQ8*LU*M>s7{atZ)tPL({EaX0g}^fD&43m}^!KYpnnMe>cAS(8E_ zTZIz$G_wI(#4GF6ecI+aH=ug2aA#GuA^-|m6c$BTeRsZz!DOjOIZO(<=h8iU9Cn-H z3V0EY$@pfksKzIJ;oVjm?%p*fhj*bhLj>GLF~vU>h)&#QNXd=L*k*xlT#xTyPcil# z0N(As?ugMSee`4kr3QD?0JY*5s5ifmABvWi;r&SoUGrvXXf)%8+M~?Y%h_Zp#$B%m z-cu{lcS&Hm{PHDC4!|UWZM_xr#~K(3T?i=R+?M6bGuB*dmrJrU8RoAhknc{00@TC0 zyN3jF)hu^j$@>+`K^12t{h-JGQ50}U`yl$J7hHb0(r7J!u{r<*6o33G#ZVsz^!h;53T!1Fi z-f}W91S{?J!kMY+j_T_%U_w4F5f4!rtmvShOp=wXBTGVPh%yvF5(6~irurOKYKtS? zvPROBS=GO(^J^3l=X~&V>eZ|mEe3LCqc=Z1Cr1|kLJSOVWw~aL2TJ5mlv-JI4@oLm zNlI2t&qDaWbRkX6iZKrt7$80z({k*)Zf#`uGnFrTa#^Iy@==`+u05G9onT53xxyJj z#mSlzYmJ}A#3^w`lwiE9kT%UI@Eg5yYBgRc?`fvAS;JON*O{c0W38M+2x*HPdO#P< zao;w99O(!}F;0$0$%uX*Lw=7ycnHqq5UFJ-6DSdM3;yoFpsBqXQ&7L_nNB zlm@J-#~j4e43uh|O9WteO-51X`bP#8jTcU4Ne33#BG|9}?(Vpb%KflBw-m6b9naLa zj}LIvCp2-Q+%`U33uJ&d-5K^abm#68UAY&@pLTJqMV)`U} zi}~`MX#>vK`uwx`6rVdQB-O>IY;SnHIKxm~TDdgP+LkGZvv7k7rikLQPVUrIKfD2u zmLhBB#dVZR?g+fcr}q_c;t z%t4&fJ-Z)o(HXJ(zQgH26%~wv`+ch13K`JoSpdMunLFdaWC^NgB>=Kb9{fB;SrSs; zWbE7*4B`rxbd|J4v4DF%!2;}sNBn*JiNmjq`C58;DRTJ{Ss&kQVUJ1VM=fq?9W8;L z&mVzop*n4r4&(Nt%d9C}KUQP=)E6NDvA`70KC@|ChUj&n0$);(O-A(&f<wDyiY8WH8h1?s;_ri3_wF+9PBO6>If*mCJTy#S z1>C|sWx-<3)MWP(@QSyZxyR5zyfPH&zXT}a7)J^7A{W4s#zj`>8bD4BY9@}gw57ww z7eeAyy(pJ6I!!yHDoO7rXK7t*+MRX-Mor^5&MVAoF4z3ww?z^=d7gjGrqty+0}a!( z$98Jh+T+&`nkZ~%pIc{A+_TIAdo{l+hCS&(g*wY7#4YFwHLhVS=pkr=d}#~xwn>KH z{{*!z_W6R(Y!y`faspV(#mtUoEOQ{HX&8 zRr7)8ddMJZeG@0t(RCJ762GG{LQA=rHm=7GK93d{*JIbwFcOymrL)+iI#`KIB(-5! zP=9Jg#@V=?UX@@-3%601&3A()HM-^H4%HvuF}oCu?5Ui_xWvwDif3L6_$Dx=g*0te zV)t~hll`XQu<-v2?}QN1wP9O>U%5N<<$8hwO*p@+A5bn z#V&l1x;!s#q$T(AEC{1s$-gp@thVVuiLtCey;kna`6kv>!7o$e_k7Rd4P27F^mQmm zoJ>A7JjVKiRi>rS)%g@>Y>VJB*8!_g#;V^6p8)>y4J=@Ga?l_FUJ6cbFt!xNMF3*P zU!b5pCqyaBJ1t!kySWtpZa*#AxcG(GZzg_1+qPj5|NOzXYtRIe9xtx>EvOY3cB*3e zH$X0SHo}ZrI-&4w@L;H)!zEf|8t;L!<026KiTsuJ*}Z|Q^ChIjMRn&Jj>6-+^XzF@ zg@U5!v->Y88V8|JJ3QWURogVKtMbs?TP%T9+SZU10SaXp%HvFqOQ?s+CYOAk zos{|rcS`}2g=1q2ZYxQ$<|!SvIeWKgtQXt#O)-)c3IT$3OEF@D8dLwnzg z7>(5{5#!bFwrQ7aF6{UVe}t4f&Z2h3Y=~Spq44i{iay%ET3jg>44dx}r1VnfiO$@E zN*NG@=4*;6KnojnjXX8}Q9+i;1(C&tkZGBocT2X(AoJZ%hRrq6W%bRXhs5lll zvz8LOml;MHVL9fa7&F@!a#{@E*)?YZi;sO&F7eM)Mm0CBmaV~ik>cKYQpEA6%UF>f z?GytfA##_b68}VO_3R7)sD}A_Tum%d_hI+I9q+HZ;2gvC0m6 z^5;#mRH7Sfe!yW#mbb`D8vMz89D;>M37hwauY0ce5F8r0(8PDgo)oj+DqfQqfe3XNA?WiZu8aYs=)1o>zyztSnq9KkM zCP7AjbI)tqQ|wzO%r^Gz{Wb2n$>- zz^SF~=4=5d_zNeXyCu9|yzt$6Y>)>uC5aRp3X;(K!L|dU*fKAwnhZmXwil+7Tw^}O zC)b610+KL-5emf)sC80T2Dj*}cwX3pyE+u+EGtB4G@96j=A^I|qLg5(rkn=|aYR{Ph{ce?smd2@V zNj$5%d%U(U)6%pzInf%(QE`9aU|vC}1A^;Z$n(iD>P2`dpZ!xcWbxLHRyQC~r$1{r zP*wEbwnE%@`UyP_Pe5^3FS<~-ZR$;&<{~^i0sQGaW*4lRVt-yMCW5g7Ufo%mAE5Yh zTHQ{#T-{p%^6Q@ZD>1Z9mB_F!-h_<<{w%b^m){k3Jo7UjqJuOe60=mdJwCUN57${V zBav#P6aBIYwn`=>z#vlI@b<=A6K1L!Wo8-4=<;prIcvg{LC&zQ$4OirrXFa)-4H}e z<104cM9JCwRldDM7gqmk2l2dI?&-YW!mQ3Mx2Dpb`D)gowq|zvD$Ezm?6ngWm`5+B z%FOEF+C$c*WV92eD*nMN=9ToCimFW;jq!n zNk9(MuQ969gudsb32oro_}=KH#cZ3JS3mgkR7yUosw%Z_^o7isRIl_$6NF+Hi+t-1yhdaI--=9_#J&890nUahvBQTVo1QE*y@8e1mr3TR8>G zL9tK_S0Ki;4U55e_UUn43X%ZC*n)@W)68`?LaSKPu^QiZEp|+3cp#wK<-phKklb^) zUkmT6J*r1O(0H_Va)sO7of%Or#NY14Tin|0I^!@XRLjnJk!sQiUIO5*DxmYKR8~|V zYZQfG!7hG6?6{4PGhV%|1#Of^Lq=4L^MJEZj*bRwP{CM!$H1Ru}5DJ z=TYheV9t|>Zd8M%iU>}5`N(;^M!|{`Cvg1VeYOm8K2-Kp4o0bN)h}34f3`X%TC5cJ zT?`Rc0|y40)FF(e$NDV#!`JaehIo}pI1V=#xQ#tmkq7(t60^OT4csn^Na7v%QvXOP zuoaB!+5}l?EE@9t#43I-+%2L@GMYoB)H#ly2<WTPQ0-14V6BR#tySvG{D7eHmU0DG|YSKGTnDcWn#MqG91; zx9R486gY%fFa;a{okCTTZYJuD%jLK0y8U}42~1J2S(H`@@MI_OgVJggzKr*j-kN!H zA|NQe)&(JYA2XjiAf(C9ImJ)M^atiooh9Y&ULFbGaRYtPXvX&s$gxMn->~#5?>tp0-=Iif;X4l?-ximB+>ae*F)_?=b+^9-MgZh-jnMDFypOY{em_^{)+WNrjo|aPU;Kx~<1;(deRVKp-}~ zSb3exb}z~8nLd27puZ~P-&XwmkyzPiaNB6OHwiVxZ=`$i@4zA#&~`=qu%hrNu?Ey$SKBEGa) zq@rUibQ4uX){=HUlsZ}Ep9+?|Z?_nQe)x(~8R#y}N>u9lcei$TWXJfUPwdK|yE1Ny zq9rv^+*FRq_g7tv&XIe6B?I5@{RDidxEI~;Wr7}uT@NOyDJz<#W0U$vRkEkmtCMG> z5zH792iT=nO4i=>kvCCzu3|6jps|61Lh(y{jx5m0Z{%@<779FSFG;0-=n)u~Oz)n0# zDlQLg2tZ7hbzE7dl#!)nuQK{MMb3awa#9v>BumA6Ay|dM!DM zCLEH|@8n2+LOse}R4tW7S?@|R&V)7qjgdh*b_d};qGdD((hO+o5D?!5+g&+i72^*T z#&`<~w+)_XSFTo9$>_7G}T@y?hsw zU0S#&IM!!QKD$s`ey)^iyEE&>rp==N;&y2ABR>A33BS&9=Op?6fkz%Hq!Oh(XSPuR zhk;`A+Yoa%qeHOY@i$@`5Vxh#115}4fey=_qW2`OFUV)Vc^}h$F-3%yyzvCcM*G4c z(oncD_P{*`a@12?T4|r&WKjeVpR&7O%{7W8pDjH(y?AM0cdIL#25?WM;&E8pe!TTj z5R*j6n0ahkR^q#$a^t{iZC-zedG`i~a+3-dD?)ge?KJk&vWg4XxjSob{Lzj0W>#kt zq5%B%XPPdCQcY^=lt>F?m-#1i0=lSJwTJ09z^lfkfnZnt^`+XD_bNlJ19SH>B6&YTbx;Gmo2IE7>9Lr7kgFA&037 z;?Vk{U(8~s2uZqCTDk(+6iCd2+UB4Ud1JwfIeVS<~c z9JM!^Ul!5rHz`z#0p-&@_*Y76xS6a(DIs%o+J!xUcl5bjIc>Bb?r+jN944yi^~VGC zlE&Mz>C+rh4azw1Xt!C&N24b-3kK~2u`QpjT7d8hGecN`svNncusyOCI)Y|KP>3 z6!nvjw^Bm7jN>rD9!}#UN}hN zvosiG#+%AV74RP^dp0-<4*n$?+H2>YDQ(Bt6h|Pj5pay7ASevMcnoN$en3ofqTXKD z^EM(KjDatD2iYMYYV4V@ZSx z+m3~)0k{N$?rs1-`j8=*AAYhix@28|uFDKx>PJLzyOB!vYQ|nw&QevSO6MjdR2sT& z>|u`wfi82NE*bF-DY!0wX-nr`X$0L&1sOzrA*h{gt6Kso80wO+Cy~r8ZSLX5e5Gu< zS5oHUna|)-rpWR@!tBpMz3f(Z@fR9Qsai~k-v^s^qS`usW#l|$Y27TKA+tTG1jCVz z>vftz#am)*j5GFsc;IfeuI=`&m-h8(O1zP-Zb84Ntdg4}iI0&S? z%ywSZoLdL@jr|5EGFjt?Hh#Yg1h&w_FuGofV1ZAR%qrG562c^5Yob!r-5u z=gvq!&JD7;-Do4Xd3GA%U&&mZbH|kppOjOhXzRIWf;*!$dpjlv2j*qh9Zdt&y5QCw z%yuT^ZvaR@z08P-z8pgW-&;zY<~dh12|X6zX8U5&pycN_)2Qm<2oR_Ms0PIm8G}XA)a;r;vmi z3HSy`ZM(qtQa($YwQep{dTKmCn#P(9P74Dhf+vF!6)HdTQP@3UZZMow|2J~?^*xt% zV&QDlDmv7fL_Uytlz0k)>@B+~Tg@o?4IZ=55~%FhS}z2Qs8L^b${?@rZIj5$2Ra*4 z#}sOWxVy^~fa79A>4TGtk{tD*%G-Na~&kUPvWb&xr-&+hQpz ziUvO-DmVCEbvnSIUNS)CZ}2yI5n8N`TVyQ(_xkNkG{z1rqC6s=VN2?&g7O9LFvRPe17zk_ObWQ z+}6{a*eQ&=06S&64*Q!?R^LWbdvB-Z*2nb-LfHu*TX10mcv(NzY8ZuA>xEKfL=N~@ zy@?leJO%r_|Bp+GPFWq98{!VD_JCC>yDuUc=(uS&kr3=*k=d?X!hIvMJrvt^aJWa^ zebHt)4h(LfM%jk&6b5hfU4PZ~EV*W{Q6;G4qy?`iO~BdPl5z5v%!TFwU+fQ18PSS< zzFmCd)G=SPw5kv$!#~hFCKJM5i&h`L1tH^S-Pwf3uuZ>i^5tg7m=mXF;3iAJ)g==F~kzdv*5huZk7P2jHtFyGYrN`9Owc6EIscpMn1onO=b)`6U^ zgKmN25M1Q1Z>!`{G)9A*blV9JBr(*IJUqi2p(mSW2=eGn3NJZn-tc#OF%uL!6kgC- zpO-FUqwnRFv^5rb8-0MsddFA_al_Qz+>pwmR^mNtrNPBO2zN6eQJ|)RxU3|E9G?j^ zLN%{W^94ahw5H^NXsjVkI?LMixTwU!zEN`v# zR`rIgWTB2pssn(a6y;>XLukVqYzkXY^9HgMVu$RZ9R%g!&KoLKKL#a4@}WL6?ECgA z2wrA>oG>8)NxHk}5GXMk|M|TBke<&?lP@}~a;XHmY06Rqnj#A9OlIshHd z+9$LI=(ma&KV9rwpY}T_Ff2cf)E$nh>4`^Aa!hG8uR&4&ea#S`rrkMk$piP>?-ybO zGK51aQ3)s@B+}@`5Es!GqEft64Z#N`TVTlI`(a=pA(7(v9SOixcJ||4X&V`f;cU}+ z66Dqa_Xp6D37n`n>;}mnFgUn95jI}ez=)(FT2uC=E?du?e2lKGfU5LAbN^pM^(QRb z_KgK(G-mnV_-OcJhs)2xupJa1UYdS~GQ>v*rRC^6{;orK^(fI0<+pLqbi^fu{K1fr zXzDZEvd5rp*etUM>qTnU#p(yWq;NnAzxey9E?NWbnQ+G-m$9X-baJd>s3qK~f8 z(+Vs8KQV~G!9A*x;h}x9$VA{V41TZpLm)}pk-rr6G?M=p;cpKp>>V43LwO6-aKo4W zpg@YC@{V%ON|UlH6RLj~|EUCsg*x*Q2_ zX$uk^lGaBcJ9K~!>(03d|H7TdNAr3irq%h=gAbLd)~-D4a5z7sL@u`hX*ouW^3=?( z3Aa^m@+dxPjniRSGR)Q(gC;|Pxe_zbs0?ctZyQ_fFeHGoz%WaD>;0>QV0mUnw$3vH z;VOTo?~?nu1tt)bU9CBPg)0H>vK7OYbRNJ6v#l&X2$Z7@bBAPUrI_r~i$EezTB6D+ z9g(N2XwYwf^LaU%fTqa;Vn*vrYz$q1UG5`G<`il=+i8I##Fap%J2D}cgpHu7WH!bH?Qv&5c{Mz`%JVGw7L_345+vWpm)(1e%vMC zjR+`#1vC=+~W(n}UM@U=jmKH3VQtSH8a3f!{Oi#LC zGOkmz)&9kaAkRT3`B9MU)$UmSv^j?kAGc;eXCm@=IefI1;mX%ui`M)j)Io1+z%ZlR9k`u!pJSO`% z`kl!$&u<%-QQG_|Tc!BLZ5VL%{O4UT99~0Gt&Q7@XzgzwuqR=Q;CEAZ;|X?xOk@jG z;-UZ{=N}sGRVeT7ws2RV%m{I%=)W^Sj7Ag(bi`!EeuI0ICfh8+2kEMSt>u^t?hrAW z6bd?L`GE1|-y-4;nSWbL?#?WP1e$V~rUI!mrf`_IM2^kjgGbweN}#vE5LB4MZ#J;i zMlA6>E-rAPY7zr8TJz)9{+yA{B<I&_wWF#f7vTmjEYowmbdtr>*Jd)Y4W%@jb2edb=y@S_s8%TFx!vCMAnIwZOFe zL1+wQ$4mzGz4wT7T}C2Z8(P$I0Wr|}+e)M?%m+s!4hsSsOGU#b<73x{@9B!6t}c4% z`~D1+b3_VU_#Nm@=R=@Xqdzk#vZj77BGoN15aj7)x@nOmQHoE1{$#0~b>_Q;R8lQc z+|%AeSnDPuq!DMad6vW^!>-8aggjN&+8AAY$2LY-oiP8JvgGOEBK1Bu{ZF^6_Zhscy z>X=^OPR;j9muVlRcYvR8r__H$J3Q=FRd7xHK|t#3zh&Ji|F%kJx$XBP zw)i)2U=B0W_lDUpO{jAi5d$Wu|&amuBXydXgb!8g)M4HJyA#I(5~U7w{19^>7p|Fm}rziznF_ zXv~iY=4E|0dIj~rc8L42o73a!iI)lhnlvAWR|A9*J`?*}V11+QNojT^tJBJr9#v>U zk%0_dy|VHr9Z)$_V<=VCe5AVUgNa&8TzMAP{;j{MNn^|ed-*Q^U@<6a1!^T+8@RUm zz5@_31PCNp&$ialS;iUKf6(*{9O64Dlucon)L4kGx-F~cKum3#<5F=7fz0$arFypt z6<1n_+fq8Yr=3`pV7+!>L+_DgUNCtp?D@TL1+TQbj1&ksF!1ApPtw{?zEs^|Q$g`^ zB*gmLynQ%PSA2Gz(Q!O04n}|{`kX~8{jC&6k002asKtE<=y-*A6bHT4+;&&@e3(}_ z+}}nXqo)G5Rr~D4Y`w(ysR4czu)^?{ZKB|ZB&?p85~R~}rN;qHf8~B8oVnZo?D-!) z7HIXx_(TG#qhU{N?h>|xdhf)X8Pqvek2}7-cm=a{%%nU)0hxPgK~qvFN$)u=UOE`M z(xjh^EVRrXeTA9&k$f_6On5zmdG=D|cw}s0_osw$G=At6l`GYRR&XRDgq~3#bAgY^ zxkSyXQ5Tj zdmyb*vq+5$B9TMY#^@qmwtQep=@66nDK=E;>9!#fXwaJHyeXP)1T+3NGOHuX&7&kM zV{DZ7I!?e>Ob)Qtv4(yZ?)eA}Y3u>Y2FC;an$bAYT#DFJplorG+U&Epe>`xXWf9ll z2xS@9*jpz0fNgr(BTM#V9-sBLQW_2)a@lQgON9MbnS=$he*#{v3MB|(Dj;9o{AOQK zu}p8NWaV3L)u2DLQC1W#8T{?Ez1IH zJ`b|hRx2$3Gn6tKxvcl#RawD>Fmb@^^*9|~j$xATjLTp#EOIAmU2{OPkb-IJ0m2;5 z8hUpax(b!A3;=*HTIu|tY`)(g{~Z+0A59GZCu`+IU&u|9hKkf$PJ7>7hv1{W{epB8>(BU#mUNkca zv3je7?6kMx+W z>~+5}$r$}N{UV7dy3QMCasZ;GE?JkGZNmp`R_h=Tg)Gpjy65v+uZY(|7hu%$I_R<= zN?Vpk&)0Y1y|3yu#bm{J8W>>qua8*BF&{Y$n2&-Sto&4(l0zs6$A*MP250;1pi~-Q zkIQZX2*s&kA(4-aN!W&cs%A_7J4XHtvLsVx&A}w-F+SFOBk!EeL8FTs@(?d!-#=ts z>qYk(#Ol?p2@CH8{$Z#9cI&fKa@G808>|8 z#Gzw_W=wp)?NGLBZ!S(SUj(g%`RV+uz9Y4eudc zb{bNRki`3rRGc5ww;Wp*)RGklQ=UWK+eCT}%TAUHt~sMQ<>B%W!l182WFhvk=Mi8O zDzW&MPn38uS{yRp2r)kQy(lwoIPf0h-rW-j!2`;nXShz=@0}0Rs5{GOJU$)0gReFj zIK2AFX(z;8_RPYJbD9km=o@vHYHDfQYT^jw9dR$B94vrltUpxwE!{B2NK*)_&!#S; ze%9?O*OyBg7iD^9hnuN%dg2e4MgYDYQ82gZ6I|bM7Fmb8X0@)`Z07;m+nHEj8IflHInzyQN7c)qHp@?dix`2&@ zde}0u@q~c};TZr2EkhExF&QtQqw(O0$Ae(}=k)eCQCtir)s?#bu2)i7bAXFD*T7*V z)isSpd_UM|#eqDJlyy$gq8Ubr^inSDFvT%VUu%!>%x)XLZ@jOi1m)4B3Bx5UlFic% zbG*Em*uT2+WLi)3TJ!KJ&H6TdzJww(xx7YMea9MBRVjnAyj7r%ec)H{31Cf6HZix# zy|brBf#R#Gc3=vPudhqjt*;R+tCTBd&rfdT&euh{DQKrTyP=oGKS-ma;bgcdh2a4! zeic?{XLenfpI>m#U=#ZLKAGe|z|j(C6Z8W+pJsO=xf@5UwWq)f{2{ zV?^L10@d95QnMUE2!?T$<>Dn`L0Jl^vYrRh0E25)j%!tCcP11JdH!4wpK7bTjKw3? znHkKyyvhU2`^F!H>`5AE)fkz$mBG`qYKWVf(Rx0@D~_HbwPVp5sfg>(PGNmqI$7o; zaEMs2r{=q=dUF)94Xd2;oybVc*)kGgidQlH1XwEf3(HumR1-?1b7{-gy`~bBrKD#9 zr^<+WB^@$zzRP>DJfWPpb|za^8(!Kb*I6psEHvfw6Q!;42F4e2;q^zrdWnfO>qw!R zd^LmWF`8gS?8R%=e3+Yv8bo3)!lbX_XJKS?P z7BeXBW2u2Mos=&+>LOLnUDOssmsC;Dms{wvw$rMWLnaZVgrMamSfyVgt&_2QW7eyiFb(y}N68yP$ z+@@oDG#%)jWH0_=$s`RKs(+9;XF4~&!`b80T}Cd^@bg;G#%`6i`(O011n774bc81o zu>IH(XC#0$l;@}_9;C)ZsYD7tpv&*DbWz4Z_G(}oNw2GA_T!yAI?7DmDH_`O5U4C^ zp_>T3Z0GYAJS-^~@6IEHC600dq;F$uI-(>ATSS(W>Ar-TDdKYhaX>y$3`iW9ehv z)JD0zJFGI}n0WkSRlYIDpWZS{F&m%s!@p@AJ}d7i1+vZX!fa_>%lIt1EgfFVk+Fj& zFILtlz5!hwV}8Bkzw_!QnBMZojEw1FxH^F{ofS*J5!7`H%ffQbD>~!$BHeM}Ob7*( z&QW>={7pQtmk)cT^-&i(0#Q`T9I%v(Nes)ZwR1VBW!7oD2bH?ggZf~g$o3`c6)2c} zP8*6Q2Vy$4QDF=D_-5snY0V>F0+Iq34Mo*YrALVRD~=H^!(8@~T{*PM!v4nB#OA02 zS0~#n#nYgu8b5UIHCRX}IY}<TObHhwAfW$wf) zDlB&AofPbko~RTV93O`RqD#7T6m*)#hiY>2A9Z0@U*zO3;PDx9dGV5{7*pszc{5Fa z`X|9J>9(jnkLw4C+PhXy%6YtZQUS>oFO{KC=v*VqQV^WOwufeE%Y+#+RSv#x2J%Dd z7J}coVyA7nqucCYWysTQBUt7h)Rd{(ZU*fd>VcSQf}hcUvLKLp(95*=E*hxbp(69k z2%Q@6TYMYDLb%ChXJD^KFL+V;3?YT8K?`A#0z?@%JepVTICsE3k$>%+obIRteQpwz z=(^tN54BBtMGu(*kdq$$)$ltRe$1MmF;=(r=g$O+^fx9HQ~%~44ho>i%RfA~zfi7r z7kJ^*@M#5(H@%~W7!nAVIs+X%+aoO^SkmTJHB0IC#55eD6Xp2rf)I~oRrcWPk%3py z4-SPT2R~UMOo%Br+*~DGishHp@$aCQl6S)S@`(v0J3lf~+uv9M`*N*vlg^`=L6bUh zCxtxaz9SDABZbbQGIPNVg{ffAI>aHL9%T@HpH7Mvr?C zE+cso-}gxM3gbuQhQ6U?b#ygWC_7`-xlWzX%-->t@3->>vC~3*()G~ z(k|{qTO6Vow&lpb)fy-a=HjTKz>1aHQnugx*lQZHfrNP82RVf>U~#(Wl?NFel7j;I zkZFtfj2@@IrxV82e4)MkAW_6HyihO!STYP35Gd#L=NM-N{xe#-7>k&c2>n*1O6V;= zjd}Wadcr?x)@Ct#?P_Ll-~PQht)Rg}g`<-RiNJPytKNdUc73Mz(kvJmL;(lzvAA4PY^z=h;q2C%Q2f3+)siX^PH9-+4Dnes>F@NE=@G~Ji2kjSuS3FKD- z1ttGObP~WaTiT6pFg!RYn9htrDW@_2O!vaRFkpJ~cTPm3nBiS+G{Pe69Zu@7%B9i6 zJI{NMfA;DN1WYs1!SAER3H12mrAGOQD8wv4;Jb-<;BLE!me`5dw_p$N}&a8jj zNB~Bm%C749HES!mTA5)QHD25aw0t-;wCS}hyn|$0LY_UasO|{D(0|n2*f->V8rYs8&>q zf6B`}@7)+(acnw$$Ec@GO0dV@p%fI=m`k~N&#mOjMXSFBwTg;c4jxA-U)vzl>s~IMw+{}_U?O0Qeks?a@irxm-eU_sKfc;1+0u~%)%^~tl3git{#7aNYCIKUpmBuCW zbdF-y?6C=6C&0!LRR;0E@$AaLqRsJYL!O z?sCDCN-*2PSi-wTQ6+ZABc}+V5KW;yyLF)g`(z4z~a9Zjnv^4o2tI;mt+w*Ps$Xn%G?CtVxkh zF`&^q7_zlx%9}y^1Y^L&+taVaHU*P$kbXE(wMy8Kf?i8mO^!!D?8lqm@{}kYdN=L< zTOw!O6Fm%=g>#LJ8UxP9lwXjVg{=?FaPP;l*}6~Xd(CgCB`XnF^0umSW-_dL`ojsS zg6j9b*5d!c;Dj8BI%IPuSwZGeRl3WqnnkN#o%>8(-gCkYNXFlnSSNSN?u_hXQT1~e zf9`bt9?h|RXvt+Bd(iO<*(eWg_NW^aiREpz!eBdW=QA;eOAy`=b(icMNdc7mcJxyt z8IClI_z_R_=DHpFQ3Dgt(F}x`&$*!Jm{#`U|FRj>|2WxtC9orkWKJP2Sk}wEegITr z4!E7Hg|7m`wx5G0&iyyHYG&O*g7w2`ZQaO9nqD_>Z~uK!V^6>4LsQPYvToVk_sqRPJdf7w%fWjRMNlNI{S2s9<^xR2VR$mK zruvWL5FE+So+H`!URT7A?_+jC^qODggVO(-mD!iQY~Wx<#FsiRgaT&6%^N_pMP7o= zVz^NhEUJ0Sg~RJ|hxAf>wF_yQU5DLPaIK^a)?cH#0O@qjNeK}~*vkCfF;L$LW7df6PY zOlr8R*|hwoA@_LQ^z=91!15WBF03D;yYUVBl^b|l-eDrMfZ-f^+|2n0h2;XnohToc zq*KaKFLvAv-K9E8cBVdUg3bBpoG1bUz;*8TkWjPgz@Js7{E2jbMMqaFT7IILg2UO) zl$s|9L-8eOz+WD(g)0Z49MncvcKnlAMflz_RiIT|bjK$E#VX%|l+lmvp0x3LE9myE zzI-rdM5zx$LB!kxP3FClcxl3TF+k_S=m1S7xY{Edel*nA9Ro^gCl6psFxl#p@1?j` z$H8fh`$yb0T@#9DAO059iXVY(baC2AM+J2<0NHXq5&OT()n1#(v4!Gs3kZ=@3&k_u zfB+`Yp0O-Wj6$sGi}wR0F3OZJlTPuEr7KsxDyEfoF@+kO4@CIxcEnPjx+_R=RN*;;iH!k|AiGn+qQ+g(I#X;oef-Dq;O|vL_6h zD%q2g?4sLYLvddGBYrbn6VSN59n&N9cm44F~4V?aNUN#9BhSE(m4b z1|Y@#4wNu%CZhCc(k^DOp>V)4jN)e~K`iV4!Y#CW`|&5UAlUK=O_27~qla4vS+jXz zA8bl&8O@2bs-8VA8<%7b&J(ZVRjY2|3$VS zm1WKs=^l)N!HsK>wm7*8)buh^(D@pd3xM(-{X>!j(psiLfewIaB~Da4!)P=4^%Ai! zvOXt6*$P1 z^y}ZD6Xp#fgc|b>G08z%t+OlhXsNJjAU~wzJ~Wb=$jh2K?*f=eP(>d03Z(=R{-<|V zvIEt&^eONceeO(l;bBWDe*4&g=OcoOALVP-7xgW{KdF`*Qt@wH$4bVC+6!Y0$A*~; zZNsSQYpID?IQ2(2TK3CBOI%e$Mhse!*3c4n_#;WQUGLw3dis@q>?}0p<2;97YDQ~x zEX^3dg_Fc=uq*2uC@ign8lH!fpTp%~UQ;Z3egka6lw{@{|Hyy1em~Y9T~#gm9ct3* z``E3;Q#F7OM^-sWiax;?2gnKSgw>4DWv;I>%%eMN|FhlahEs?qB~Tt&@Qlcp7LDE# zI6uU|o(Xb<@FXf)6H!`qJtJB)Den<6os>o9QGej4XSQj z;TL!(Ff69)kXS5gN?@xO&bE@=b(>v(;rrG}^O!$zRq=}W%bi75ke}cGLzASBwi)sL zn8fOatJxClf7DOLMUeQnAR&Dvl#aC!6QZexju6OY6o}r+QiieKX&TnqOFR3S#S8{V znEi)5iABzC=fmz@BNU4a9j?I(M%?K`CQWI7CE|7IY5Zo}Rp|J`)+m)P+8lr@FN`tF z7;W^Q!Rvo!H)*Z@=Ef4gBXoVAHvrK&k%VVER?Y~WtTD1Dy5UM+`lhP3m~JOfKd4C} zPOXIOf>Bxq5ngLtfA+_wd+EMI)S8>I_@3Jtqi@wLoE#MR4~d_!teppc%iarV`SiUQ zg!aj7w(4AH&&3h+&Niqr^Tx&rs`-cQC{2$-E>GZTU9s}NR|WqW&}8EQ2D6w17s#uM z^NqJrc1}nR_b~rdNI_!|tP_W?=l%%*Iq{=5_Wfm((r}!+j2w&?IHhksVgONFu3*IC zV;7RGeY{XqBQNmQ%)6Y?Z)klp^M0X+1q|6i`5#`A8WzZDzs>W5tVFtyu*;?*5|fGS zW;u1?k7MQnFTGuDo-sn)+gGZ2?Ljt`oY&v}WOP~}1&F$|%<%e`=5sbIXdbquM(hGo zcf{c!vKp|~!2zdx|3fHGZi$&huR%|P;WG^-1SSP79u+Pk>#w~8eu?h;amgCq-0&c} z5pX1Fg*O=C0@OwkuWLY?hUf4^rC{+%^`thMuh&Uz!8#Z0PgS8siHg%g0;J0Z6iK2) zuY=q^AX!6bBZMny=|LiTBeQojV0@6C|AH%hSACAV{yO3ToeXCrAwr&Qo`Lo~1s-mg znM!CJqtgSnci{f{X@x#u#g!dv2naLbGRAV#+v$yd#+x*L+M6cwzmSL z@xeB824BzD)0NyjMQQhCJGcuyO^`NE68W+{b9z+FXIy?OSW&c#0PhArq!_H9OvEFz z+liEAL?w9O%wUrn(SoA59h`Tx3 z@PAm_cYM9_*t2B_dRJ+~h$`(8@$XT?>K1yNc8cZ40!0@y6~e@8VvO$n6|u#lud>@H z2O8>{CzqizS3lN0ool|{MIqL1w|~{6mGL4jt+&2ai97DX5Y@7J?@Gw<+gx7Rvu+O3 z`wx3Ex>ap#({aeKP|&VK@|FS_v1%qIw)oYJ-pJN+PdS>q&8@6fe8zSA=jIb!O9a@Q=PxX~K05B+;c+-r$G~OPP_#NY$HP_GM)SDw%rT zQxgT~&m2gQILu`%o~sQyLi|vPD?RL6a>D@5h`&hN@R-v=%uaFLt=lDLH3x4~f<#rx z7j^}*htUI=LvdF(nH$tsx4Fk6{J|v-2AUaCn!b2u?zZ64;j4UJr~I)+ci`@Zrnliy zEDN&%D2S&!B+AA-!dMFUV-$0m=rpy|*6C)ap1CR5=IgZB6MuMORbC$QqYL%XG7O0K za_V#R=^k75F-?7$13%pqlo zt1;I_pAQB3BsO~|u%FRgV3qV4onJHS1u6|)mB6W>Zyo6`)~%H`JYtLp#JZ0tWPtpF zNp=Ela)DHb;1lE^k4-Y4BThIk9rLbloyNG1feUd_fhK=@a@iJ9Y3RubuSr3f4CFv$ zaQKH%&Zu*LARovam4$T7O==gR#~|v50r&b@9hp_b?L8gQ%VPLI*7jOAh*Ui=vqq?5 zzsxH?%ey)mz^sy>X6ylLm1PfdWlavAc?DHgIa{)vAVM~*;W`_%z)(QZN3xdf$EpYj zHhw4VdyH5e{r<7GzKr<;t^b^*;B@lU&>G}yG2G~~-Iw6|R>KvVNd!WTwYmFF3^}}H z)O)6#j%2@DaH>7mK(sNK8gBpHrbpEwA*ts_+20mD{nUSGkvV>#c#0SYJ|;8t$IuwM zO;5)WP%d%!ZC_cdRP!%^t!WfrJ}{4Rt>lBavgbz&VFL!nbJ-{K!^iMQog#7ZO(j*8 zGopip#@0JjC8z7RO%y9Xt90#Easu3owLPs^)mL|gR>0X4FY(%IVVxMX#zeIyO?9S0 zybxr^s~ej58B>JY*@t(;Tlj52Jgoa^gNeLyA>kXqOvArpBXER?w;#A-0tqH4*iI=z z6Xc4aMwrcGj2(?9@ScpKKWDi7Stav^Yz`BDhuC3m;!L~TBw>@g>MF?3*h1V^d(@0L z7^YgX?)f(gMc%NMA{KSsn}8a&W_b{mHxgH>71FR0*d$a)skI&$T8g0{(F`;|3*ogo zo;Wpjex(Q5D?~}Y&Ux0{-&((WnB$J%p}lCOm@__9;~H%aS0Cictlm8M(7C}xy`{xp z(X7@wQP>Aw>JEVyHfH$||A*2R+O}-wyRk)6sj94I*v3hH)gXn{*E_(~NqoyZgQn4d z*A!Q+VZeaYi?-n9OHE(Yt{usZ1Np{%!2!uh%93T2Q)|7Daj;qO1}}cCPD%DZtXhqPk#s`MwuweZeWW1V=X`4DNLhJCBk* zQ@_sL3Ml7=Oo(qfi>?f6{5)4kAq;{nv?=d`cS&6d5RK_qG8K=c9bXJnPBpi!Az~@0 zd7o-6l(a|HbuZ+n8`_x&?~4n>)%c*)v0=SuzWN+>3PESS5zJhj7qU3Dg`2C22xf*`l&e@G1m zSob|X=)Yz&@_rhKO~nC(%&GqR9q^`ht`HrkUDTz7w7dnZjT-!%=VH6AEQkmiGwPmo zn!SLK=>PH!=mwn41Iw_IQ5Jw6t9cBw!JA%D>MN(R{eHm=31MjUzgk3vX|O}u@z#(< z(bJ?{T;+oX%c%Jh9)87wBc6yznvH2plKE*fW^Lm0IK*65)OZt_%N8&agM*k$cB0OD zOHfJ*QfhLdj4I<~i!I{|IcLmy=)$^GIop4?dq+%EUnFIA$EUv&^s6)KYmZFn(?vi$ z8r?_tEl6+?W+^6SKJU>olY+}}K~#XN!6>%thdBnRMhDfZXZWp>;wb1&Jdx2DT{9c4 zl^tx@-HMl>UYxH>6pxUyZ$Lwgo&`utx)fDeWqqHTkXilaGU!3iMwaLDoH@1hR>bl8 z1f+BMfsyxr{LUHjI&vu6Q7(+iJCs<7(N$I?F40O2&)o8jENe)FiI`6fOaqDBdp_W9 zawwR)B?NVyvMSz}2jEwZhp zRKzdOJizb*GcbwUo85ch7 zs$-b}GR1iP9_9^fO)B9vkbPf-r-ssm=00k|@Y5Emnv@e0rl^1dB@T-)ncV8pLa@{T z`^6~{8c`1?;?gg4zKUs7!fqF5xsz*#!5DsOa_FE7w1ca!_|p-F&lyCM2K`l`gJ{mMvIJ^7MwteGuhj1mAh5)44XWdOV$BKIN#k1kD?# zOA@|?{DG%)Cg@IwG5SLTH}*-5wWuyw8!1|pYEmsTz!XgOqv(AA)w?KeZ^j;mAX(RM zNxqK5IK8hbXKLix$M;(|-Aszv?slXq{L(CuWuGVo@Wga((OK?sATpzJKh#8G{tDHa zFqa$*AC{SEQo3x)^DAxB--@<8WXyS8w3WLN@&fspN)6~6@1l}E6CnJfG{FSw$v%V} z;-HU6+LgnS8g5h$P|keLo|op)44}MZkTGf&w--GM5nf*_{)OVx0?rkVgJ99(O$_9! z{~~-_W=#qH5QzYnoR|M($XS_f}Pw4eLo; zv62&^Vc|fRm$W=;yP9EXvH8=VHc!F@4uOXczDI=WDsFG{X$||x(SI(VKb0)`}Ds`dzTVni`e60ROZhDfbW(NHU30aiF z1mBVQHEyxuP08P?oDf&QopywD0DkB6R+<<6Ip~c;r3$)zZ#sDNHc9XSGAr%j=HxQ} zeuCNT#JzW0F%>4#tysByqBe&>Jow_S8&RiKoKh3J=4n`nRBYqbC=c;HDQ7R|>H%qM z3u4NH;oAK{w!$k{EG-5MX{icRn=T)$CywTS%T4mbPUQIf&Q1cb7~`6 zIWVsCH_s2nC?Z+QvC}F7gNX{XfA6LzlAYxrwE6NW+saXAYhtbGcy%UVGI4pvt;`CB zQI?R=rrY~@=J(2FTsu0n0nj9kl73K|ocsG*2l+ntpdyqvA*!#_;YIrn+y!3A^j_&T z>Opj2}{fgcInAC5c=z@;lA4KZCxtK4V*>b`DkwE$X@1+}WQFX-cNbmni{z-^{F zFH*eb6d0Cf(EcLhUX@Y4+V&##oBuDWLgx#R^lE}N_KVgywJCZ_3G?i zd)$+%iW)Oz9M8=7z4SW4*n(dOVjy+Su+yc7T`_XpMnjJ| z-|q>ofSHOn55b@#Jb|JegGH^)1rQK0VY=R!32$tg9bw!pz;PfzyXe)Pa+*znday*i zY2DoAc|i4#R#=u@)~n0JQ$q1?6Dl(!4_TEDEv?*PXa}NShS)P=L27*X4@C_l(WQ<& z+<{uP+bQIV79MB(qYMWR!a7Ck?Fbx(7Sw+ocrHWt0AM4S6_+Py2pjSlmv~|%oGq&C zFlj054pykK&x2nX{UqkNs@i28kYxP+K19x=d^7xrPdd-tmQ`I%1F7x0DO<>qG}|3JwsvSHAGszh4xp4 zMLT4w5#0&*cv46%@0P}JWtX#iAX(E${Iv?f?hD6Stk^$~wq*LoK^4Ehb!2fFJLmf4 zRcx=>(a}BEW>i}rV2eux_#vcya?F)(!{SrZlw#n8a&@PJJW|I>o4S-`;$e?ao%~&Xr0j%mDtr znp2_CyM8=)wnF)Wh0mBEkK<+{9kR^%p>tQABSN8-oBZqYvY-F-E)Kz)N& zd{|DL)9_oi`iMq-sPx$I1I-1Pf3I)EU6uW?@_$wOwG<;buj#A$*|2^n{IKFbFLv^` zgauXI()w)(g(FS?>0RaLs|nP7HQC>lv5qB3`WTpKa8HLDuZASD(Cg1vTX693Fi2Fm zX|!dW-?rw9s(i!rk&VXRw~v8gMm*;-NGXRhj9Cmal52PZ$AXTknOamTKe1L%43J*NB4U+7@B2XOE6OejZqj_^n_RlDZz;MGxzNy*3wR-eT|;nix*X~UKDAK z3j&Hga+;eUcqRH^8dKXlZDGdAQYPhFH7JmjpIXun+xiVm@SJXKU531p&Hgj5T;U!l z)0%ZPwy2x**BjF}=vl&xTZ%}rr3T{rhZ8+ z)l+5uPmH|lJ_c!IkpDfvr-CugdHKlJ6GV<@C2)0wW@~ zb%Lz75I>|h{{t8V`(dW_A>?ikU?~om|HKb*FpDo1`%0bMTRxx)S>ErXM@R_rEm!;h z^8`-d$`s@ZFxN%T7#P3Vrtdp5vHy8yneNHhc_}Nie`$|aWG`j_mfOc!8_QGqgv7# z;mA+e2P(4DPwee+*SGH|z?wngIIU@R%XkoU=Ga;R=`6EYK8FB|;K1tghVO21#ka{i zb!j9Q478e1F>K|kIcTUt)Zz`xK+}_>5T%V|pX5)iC~n{aw?{x`8nMEWX8UL{MRV+Tz_05$hl>^(*l(g8iAS z=3+#iY_~9#uT^Toh}TfHR|d>HN18JEgZC_Vsk0W_+BftjsHnk(+^TDcv=2k2Cr{8N zscFnoxtL8HZ6kg9I)nhkYyjV#;dV8Z7G2_W{-o^J1EDtEg^b@hzvtbP&M5M(&)R;+ z3V~Y&*0#e6oJxD*ZdjMSRLoZ`BS(BKXdq1(yH4C?$a|ccqi>8u#vuSC0PegBr z>@{d678I@|IGhIkp*tCII4o!jLf==0>@?pl=BST9h^9?xj#3Y*xZKHLjgr)luP}~a zvt>o4Sjsg%i;%im3iKZdss2ym&1?VC(sDsm;k}ddrVlmQR1F}VxI9So=X9-veW6>%pc%401yx)qG~aseCRtYx%-N>D(O{o()spa|AQY9 zNkRjfu3FJ|c?=t*-AuUqLBsktS+_e{6Rrp5h(<_Am5?tg$@l@7M@mQDctTLclfhaw zh*P_#{gP&haN7p9s2KQT_`E0x@NNjO*&?e??vCr@m1Z#1WmS>W*jDcul+wStL3Gv@ zr2{mB>9A@9Ow#`K%d*FR;4uGve!!h%)CGiAa?b#Qm67YtuyeV>g}nZH5~}YivPNt^ zD{odW+ZKtTfU;l;OOe_1tw%q@`5>jd?No9bcaN*9kkBhT>N}#@S`Ug~^>FKh^G?sr zIM=4+hA*4bi6$$|D7iZ{Pxcv!B^N!4v!4gQ;qUs|5jTIR`@Wk$tP$6A_EwT&!FJY- zp(MkQ;vhAepr&`n`L!upd`Qsmub)R(G1kVZgy({3{Pr0gFK(mSoH=SnF>pBl5>AE} z=Gy!N6(7CNe*O~l5MQUvb(;N$oQqKO9%&{r`ga<=yxN9bv-uhmnJ&CdEY9yc`@w2Q zi^zoj5L$tBhaSTGdwkWJl`5|(t1{-9MWLtS!MhT>XPB&9Leg`P6(X91#30}+a2w)% zE(!t&yY`@vXlpe5i2@x$FHO&C1m^5NrzSP<~Eqn&xs=QDv}sYS4v9pl7Y?_pXu?D}MLA zw-YgPU@w?W#=52j#MRftO?_|Cmn%$eklM52)hmNU2pPEx`*a@;|4IHfJk(RI}KC`@eX|CkGYeWvqroW zqo_(a1db%pVjMZw()v0m_L72c6j*pE{61o5ud?=5%;D>9OaXii2Pc=`l%Z$?S3?(tuTMc@VKr zQ2|>c=c_cT#Smu>g^A~YFSg*fFi*A_Vw%|+e|w%-)zHZYvSUP1;y7I+k(sH+)tma& ziiXRN#gW|f$qO}z%!4wN?_J0A?>kuyh literal 0 HcmV?d00001 diff --git a/artwork/ZeroTierIcon.ico b/artwork/ZeroTierIcon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2d190c474d350ed516428a9437a9f8b7e27d084c GIT binary patch literal 370070 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 bFb9|e%mL;AbAUO(9AFMG2bcq<=fM953V?CP literal 0 HcmV?d00001 diff --git a/artwork/ZeroTierIcon.png b/artwork/ZeroTierIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..4d9641b344329a3790f94206d012f2a9ce2e0750 GIT binary patch literal 26898 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 literal 0 HcmV?d00001 diff --git a/artwork/ZeroTierIcon32x32.png b/artwork/ZeroTierIcon32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..24ff0a1cc2f0a3442ca8e8c1e72aeb671f78b5d0 GIT binary patch literal 7219 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 ALjV8( literal 0 HcmV?d00001 diff --git a/artwork/ZeroTierIcon512x512.png b/artwork/ZeroTierIcon512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..d225c2e339de78c4e4ba15c802cb7ae51f4222e4 GIT binary patch literal 51309 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 literal 0 HcmV?d00001 diff --git a/artwork/logo.html b/artwork/logo.html new file mode 100644 index 0000000..69c06a2 --- /dev/null +++ b/artwork/logo.html @@ -0,0 +1,37 @@ + + + + + +





+ +
+
+
+ + \ No newline at end of file diff --git a/attic/WinUI/APIHandler.cs b/attic/WinUI/APIHandler.cs new file mode 100644 index 0000000..7192f3f --- /dev/null +++ b/attic/WinUI/APIHandler.cs @@ -0,0 +1,459 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Net; +using System.IO; +using System.Windows; +using Newtonsoft.Json; +using System.Diagnostics; +using System.Windows.Threading; + +namespace WinUI +{ + + + public class APIHandler + { + private string authtoken; + + private string url = null; + + private static volatile APIHandler instance; + private static object syncRoot = new Object(); + + public delegate void NetworkListCallback(List networks); + public delegate void StatusCallback(ZeroTierStatus status); + + private string ZeroTierAddress = ""; + + public static APIHandler Instance + { + get + { + if (instance == null) + { + lock (syncRoot) + { + if (instance == null) + { + if (!initHandler()) + { + return null; + } + } + } + } + + return instance; + } + } + + private static bool initHandler(bool resetToken = false) + { + String localZtDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One"; + String globalZtDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\ZeroTier\\One"; + + String authToken = ""; + Int32 port = 9993; + + if (resetToken) + { + instance = null; + if (File.Exists(localZtDir + "\\authtoken.secret")) + { + File.Delete(localZtDir + "\\authtoken.secret"); + } + + if (File.Exists(localZtDir + "\\zerotier-one.port")) + { + File.Delete(localZtDir + "\\zerotier-one.port"); + } + } + + if (!File.Exists(localZtDir + "\\authtoken.secret") || !File.Exists(localZtDir + "\\zerotier-one.port")) + { + // launch external process to copy file into place + String curPath = System.Reflection.Assembly.GetEntryAssembly().Location; + int index = curPath.LastIndexOf("\\"); + curPath = curPath.Substring(0, index); + ProcessStartInfo startInfo = new ProcessStartInfo(curPath + "\\copyutil.exe", "\"" + globalZtDir + "\"" + " " + "\"" + localZtDir + "\""); + startInfo.Verb = "runas"; + + + var process = Process.Start(startInfo); + process.WaitForExit(); + } + + authToken = readAuthToken(localZtDir + "\\authtoken.secret"); + + if ((authToken == null) || (authToken.Length <= 0)) + { + MessageBox.Show("Unable to read ZeroTier One authtoken", "ZeroTier One"); + return false; + } + + port = readPort(localZtDir + "\\zerotier-one.port"); + instance = new APIHandler(port, authToken); + return true; + } + + private static String readAuthToken(String path) + { + String authToken = ""; + + if (File.Exists(path)) + { + try + { + byte[] tmp = File.ReadAllBytes(path); + authToken = System.Text.Encoding.UTF8.GetString(tmp).Trim(); + } + catch + { + MessageBox.Show("Unable to read ZeroTier One Auth Token from:\r\n" + path, "ZeroTier One"); + } + } + + return authToken; + } + + private static Int32 readPort(String path) + { + Int32 port = 9993; + + try + { + byte[] tmp = File.ReadAllBytes(path); + port = Int32.Parse(System.Text.Encoding.ASCII.GetString(tmp).Trim()); + if ((port <= 0) || (port > 65535)) + port = 9993; + } + catch + { + } + + return port; + } + + private APIHandler() + { + url = "http://127.0.0.1:9993"; + } + + public APIHandler(int port, string authtoken) + { + url = "http://127.0.0.1:" + port; + this.authtoken = authtoken; + } + + + + public void GetStatus(StatusCallback cb) + { + var request = WebRequest.Create(url + "/status" + "?auth=" + authtoken) as HttpWebRequest; + if (request != null) + { + request.Method = "GET"; + request.ContentType = "application/json"; + } + + try + { + var httpResponse = (HttpWebResponse)request.GetResponse(); + if (httpResponse.StatusCode == HttpStatusCode.OK) + { + using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) + { + var responseText = streamReader.ReadToEnd(); + + ZeroTierStatus status = null; + try + { + status = JsonConvert.DeserializeObject(responseText); + + if (ZeroTierAddress != status.Address) + { + ZeroTierAddress = status.Address; + } + } + catch (JsonReaderException e) + { + Console.WriteLine(e.ToString()); + } + cb(status); + } + } + else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + } + catch (System.Net.Sockets.SocketException) + { + cb(null); + } + catch (System.Net.WebException e) + { + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else + { + cb(null); + } + } + } + + + + public void GetNetworks(NetworkListCallback cb) + { + var request = WebRequest.Create(url + "/network" + "?auth=" + authtoken) as HttpWebRequest; + if (request == null) + { + cb(null); + } + + request.Method = "GET"; + request.ContentType = "application/json"; + request.Timeout = 10000; + + try + { + var httpResponse = (HttpWebResponse)request.GetResponse(); + + if (httpResponse.StatusCode == HttpStatusCode.OK) + { + using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) + { + var responseText = streamReader.ReadToEnd(); + + List networkList = null; + try + { + networkList = JsonConvert.DeserializeObject>(responseText); + foreach (ZeroTierNetwork n in networkList) + { + // all networks received via JSON are connected by definition + n.IsConnected = true; + } + } + catch (JsonReaderException e) + { + Console.WriteLine(e.ToString()); + } + cb(networkList); + } + } + else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + } + catch (System.Net.Sockets.SocketException) + { + cb(null); + } + catch (System.Net.WebException e) + { + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else + { + cb(null); + } + } + } + + public void JoinNetwork(Dispatcher d, string nwid, bool allowManaged = true, bool allowGlobal = false, bool allowDefault = false, bool allowDNS = false) + { + Task.Factory.StartNew(() => + { + var request = WebRequest.Create(url + "/network/" + nwid + "?auth=" + authtoken) as HttpWebRequest; + if (request == null) + { + return; + } + + request.Method = "POST"; + request.ContentType = "applicaiton/json"; + request.Timeout = 30000; + try + { + using (var streamWriter = new StreamWriter(((HttpWebRequest)request).GetRequestStream())) + { + string json = "{\"allowManaged\":" + (allowManaged ? "true" : "false") + "," + + "\"allowGlobal\":" + (allowGlobal ? "true" : "false") + "," + + "\"allowDefault\":" + (allowDefault ? "true" : "false") + "," + + "\"allowDNS\":" + (allowDNS ? "true" : "false") + "}"; + streamWriter.Write(json); + streamWriter.Flush(); + streamWriter.Close(); + } + } + catch (System.Net.WebException) + { + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); + })); + return; + } + + try + { + var httpResponse = (HttpWebResponse)request.GetResponse(); + + if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else if (httpResponse.StatusCode != HttpStatusCode.OK) + { + Console.WriteLine("Error sending join network message"); + } + } + catch (System.Net.Sockets.SocketException) + { + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); + })); + } + catch (System.Net.WebException e) + { + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); + })); + } + }); + } + + public void LeaveNetwork(Dispatcher d, string nwid) + { + Task.Factory.StartNew(() => + { + var request = WebRequest.Create(url + "/network/" + nwid + "?auth=" + authtoken) as HttpWebRequest; + if (request == null) + { + return; + } + + request.Method = "DELETE"; + request.Timeout = 30000; + + try + { + var httpResponse = (HttpWebResponse)request.GetResponse(); + + if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else if (httpResponse.StatusCode != HttpStatusCode.OK) + { + Console.WriteLine("Error sending leave network message"); + } + } + catch (System.Net.Sockets.SocketException) + { + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Leaving Network: Cannot connect to ZeroTier service."); + })); + } + catch (System.Net.WebException e) + { + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Leaving Network: Cannot connect to ZeroTier service."); + })); + } + catch + { + Console.WriteLine("Error leaving network: Unknown error"); + } + }); + } + + public delegate void PeersCallback(List peers); + + public void GetPeers(PeersCallback cb) + { + var request = WebRequest.Create(url + "/peer" + "?auth=" + authtoken) as HttpWebRequest; + if (request == null) + { + cb(null); + } + + request.Method = "GET"; + request.ContentType = "application/json"; + + try + { + var httpResponse = (HttpWebResponse)request.GetResponse(); + if (httpResponse.StatusCode == HttpStatusCode.OK) + { + using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) + { + var responseText = streamReader.ReadToEnd(); + //Console.WriteLine(responseText); + List peerList = null; + try + { + peerList = JsonConvert.DeserializeObject>(responseText); + } + catch (JsonReaderException e) + { + Console.WriteLine(e.ToString()); + } + cb(peerList); + } + } + else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + } + catch (System.Net.Sockets.SocketException) + { + cb(null); + } + catch (System.Net.WebException e) + { + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else + { + cb(null); + } + } + } + + public string NodeAddress() + { + return ZeroTierAddress; + } + } +} diff --git a/attic/WinUI/AboutView.xaml b/attic/WinUI/AboutView.xaml new file mode 100644 index 0000000..295d27b --- /dev/null +++ b/attic/WinUI/AboutView.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/attic/WinUI/AboutView.xaml.cs b/attic/WinUI/AboutView.xaml.cs new file mode 100644 index 0000000..9c48493 --- /dev/null +++ b/attic/WinUI/AboutView.xaml.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace WinUI +{ + /// + /// Interaction logic for AboutView.xaml + /// + public partial class AboutView : Window + { + public AboutView() + { + InitializeComponent(); + } + + private void Hyperlink_MouseLeftButtonDown(object sender, RequestNavigateEventArgs e) + { + var hyperlink = (Hyperlink)sender; + Process.Start(hyperlink.NavigateUri.ToString()); + } + } +} diff --git a/attic/WinUI/App.config b/attic/WinUI/App.config new file mode 100644 index 0000000..8e15646 --- /dev/null +++ b/attic/WinUI/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/attic/WinUI/App.xaml b/attic/WinUI/App.xaml new file mode 100644 index 0000000..12ed85f --- /dev/null +++ b/attic/WinUI/App.xaml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/attic/WinUI/App.xaml.cs b/attic/WinUI/App.xaml.cs new file mode 100644 index 0000000..53ef2f6 --- /dev/null +++ b/attic/WinUI/App.xaml.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using Hardcodet.Wpf.TaskbarNotification; + +namespace WinUI +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + private TaskbarIcon tb; + + private void InitApplication() + { + tb = (TaskbarIcon)FindResource("NotifyIcon"); + tb.Visibility = Visibility.Visible; + } + } +} diff --git a/attic/WinUI/CentralAPI.cs b/attic/WinUI/CentralAPI.cs new file mode 100644 index 0000000..22bdc69 --- /dev/null +++ b/attic/WinUI/CentralAPI.cs @@ -0,0 +1,256 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace WinUI +{ + class CentralAPI + { + private static volatile CentralAPI instance; + private static object syncRoot = new Object(); + + private CookieContainer cookieContainer; + private HttpClientHandler clientHandler; + private HttpClient client; + + private CentralServer server; + public CentralServer Central + { + get + { + return this.server; + } + set + { + this.server = value; + WriteCentralConfig(); + UpdateRequestHeaders(); + } + } + + public static CentralAPI Instance + { + get + { + if (instance == null) + { + lock (syncRoot) + { + if (instance == null) + { + instance = new CentralAPI(); + } + } + } + + return instance; + } + } + + + + private CentralAPI() + { +#if DEBUG + ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; +#endif + cookieContainer = new CookieContainer(); + clientHandler = new HttpClientHandler + { + AllowAutoRedirect = true, + UseCookies = true, + CookieContainer = cookieContainer + }; + + client = new HttpClient(clientHandler); + + string centralConfigPath = CentralConfigFile(); + if (File.Exists(centralConfigPath)) + { + byte[] tmp = File.ReadAllBytes(centralConfigPath); + string json = Encoding.UTF8.GetString(tmp).Trim(); + CentralServer ctmp = JsonConvert.DeserializeObject(json); + if (ctmp != null) + { + Central = ctmp; + } + else + { + Central = new CentralServer(); + } + } + else + { + Central = new CentralServer(); + } + } + + public bool HasAccessToken() + { + if (Central == null) + return false; + + return !string.IsNullOrEmpty(Central.APIKey); + } + + private string ZeroTierDir() + { + return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One"; + } + + private string CentralConfigFile() + { + return ZeroTierDir() + "\\central.conf"; + } + + public void WriteCentralConfig() + { + string json = JsonConvert.SerializeObject(Central); + byte[] tmp = Encoding.UTF8.GetBytes(json); + if (tmp != null) + { + File.WriteAllBytes(CentralConfigFile(), tmp); + } + } + + private void UpdateRequestHeaders() + { + if (client.DefaultRequestHeaders.Contains("Authorization")) + { + client.DefaultRequestHeaders.Remove("Authorization"); + } + + if (!string.IsNullOrEmpty(Central.APIKey)) + { + client.DefaultRequestHeaders.Add("Authorization", "bearer " + Central.APIKey); + } + } + + public async Task Login(string email, string password, bool isNewUser) + { + string postURL = Central.ServerURL + "/api/_auth/local"; + CentralLogin login = new CentralLogin(email, password, isNewUser); + var content = new StringContent(JsonConvert.SerializeObject(login), Encoding.UTF8, "application/json"); + HttpResponseMessage response = await client.PostAsync(postURL, content); + + if (!response.IsSuccessStatusCode) + { + return false; + } + + string resContent = await response.Content.ReadAsStringAsync(); + + CentralUser user = JsonConvert.DeserializeObject(resContent); + + if (user.Tokens.Count == 0) + { + // create token + user = await CreateAuthToken(user); + } + + Central.APIKey = user.Tokens[0]; + + UpdateRequestHeaders(); + WriteCentralConfig(); + + return true; + } + + public async Task CreateAuthToken(CentralUser user) + { + string randomTokenURL = Central.ServerURL + "/api/randomToken"; + HttpResponseMessage response = await client.GetAsync(randomTokenURL); + + if (!response.IsSuccessStatusCode) + { + // TODO: throw an error + return null; + } + + string resContent = await response.Content.ReadAsStringAsync(); + + CentralToken t = JsonConvert.DeserializeObject(resContent); + + user.Tokens.Add(t.Token); + + string tokenObj = "{ \"tokens\": " + JsonConvert.SerializeObject(user.Tokens) + " } "; + + string postURL = Central.ServerURL + "/api/user/" + user.Id; + var postContent = new StringContent(tokenObj, Encoding.UTF8, "application/json"); + response = await client.PostAsync(postURL, postContent); + + if (!response.IsSuccessStatusCode) + { + // TODO: thrown an error + return null; + } + + resContent = await response.Content.ReadAsStringAsync(); + user = JsonConvert.DeserializeObject(resContent); + + return user; + } + + public async Task> GetNetworkList() + { + string networkURL = Central.ServerURL + "/api/network"; + + HttpResponseMessage response = await client.GetAsync(networkURL); + + if (!response.IsSuccessStatusCode) + { + // TODO: Throw Error + return new List(); + } + + string resContent = await response.Content.ReadAsStringAsync(); + + List networkList = JsonConvert.DeserializeObject>(resContent); + + return networkList; + } + + public async Task CreateNewNetwork() + { + string networkURL = Central.ServerURL + "/api/network?easy=1"; + CentralNetwork network = new CentralNetwork(); + network.Config = new CentralNetwork.CentralNetworkConfig(); + network.Config.Name = NetworkNameGenerator.GenerateName(); + string jsonNetwork = JsonConvert.SerializeObject(network); + var postContent = new StringContent(jsonNetwork, Encoding.UTF8, "application/json"); + HttpResponseMessage response = await client.PostAsync(networkURL, postContent); + + if (!response.IsSuccessStatusCode) + { + return null; + } + + string resContent = await response.Content.ReadAsStringAsync(); + + CentralNetwork newNetwork = JsonConvert.DeserializeObject(resContent); + + return newNetwork; + } + + public async Task AuthorizeNode(string nodeAddress, string networkId) + { + string json = "{ \"config\": { \"authorized\": true } }"; + string postURL = Central.ServerURL + "/api/network/" + networkId + "/member/" + nodeAddress; + var postContent = new StringContent(json, Encoding.UTF8, "application/json"); + HttpResponseMessage response = await client.PostAsync(postURL, postContent); + + if (response.IsSuccessStatusCode) + { + return true; + } + + return false; + } + } +} diff --git a/attic/WinUI/CentralLogin.cs b/attic/WinUI/CentralLogin.cs new file mode 100644 index 0000000..97265dc --- /dev/null +++ b/attic/WinUI/CentralLogin.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace WinUI +{ + class CentralLogin + { + + + public CentralLogin(string email, string password, bool isNew) + { + Login = email; + Password = password; + IsNew = isNew; + } + + [JsonProperty("login")] + public string Login { get; set; } + + [JsonProperty("password")] + public string Password { get; set; } + + [JsonProperty("register")] + public bool IsNew { get; set; } + } +} diff --git a/attic/WinUI/CentralNetwork.cs b/attic/WinUI/CentralNetwork.cs new file mode 100644 index 0000000..26ad523 --- /dev/null +++ b/attic/WinUI/CentralNetwork.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace WinUI +{ + class CentralNetwork + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + + [JsonProperty("clock")] + public UInt64 Clock { get; set; } + + [JsonProperty("rulesSource")] + public string RulesSource { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("ownerId")] + public string OwnerID { get; set; } + + [JsonProperty("onlineMemberCount")] + public int OnlineMemberCount { get; set; } + + [JsonProperty("config")] + public CentralNetworkConfig Config { get; set; } + + public class CentralNetworkConfig + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("nwid")] + public string NetworkID { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + } + } +} diff --git a/attic/WinUI/CentralServer.cs b/attic/WinUI/CentralServer.cs new file mode 100644 index 0000000..8e26865 --- /dev/null +++ b/attic/WinUI/CentralServer.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace WinUI +{ + class CentralServer + { + public CentralServer() + { + ServerURL = "https://my.zerotier.com"; + } + + [JsonProperty("server_url")] + public string ServerURL { get; set; } + + [JsonProperty("api_key")] + public string APIKey { get; set; } + } +} diff --git a/attic/WinUI/CentralToken.cs b/attic/WinUI/CentralToken.cs new file mode 100644 index 0000000..1db548a --- /dev/null +++ b/attic/WinUI/CentralToken.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace WinUI +{ + class CentralToken + { + [JsonProperty("token")] + public string Token { get; set; } + + [JsonProperty("clock")] + public UInt64 Clock { get; set; } + + [JsonProperty("raw")] + public string Raw { get; set; } + } +} diff --git a/attic/WinUI/CentralUser.cs b/attic/WinUI/CentralUser.cs new file mode 100644 index 0000000..8a8945a --- /dev/null +++ b/attic/WinUI/CentralUser.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace WinUI +{ + class CentralUser + { + public class CentralGlobalPermissions + { + [JsonProperty("a")] + public bool Administrator { get; set; } + + [JsonProperty("d")] + public bool Delete { get; set; } + + [JsonProperty("m")] + public bool Modify { get; set; } + + [JsonProperty("r")] + public bool Read { get; set; } + } + + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + + [JsonProperty("clock")] + public UInt64 Clock { get; set; } + + [JsonProperty("globalPermissions")] + public CentralGlobalPermissions GlobalPermissions { get; set; } + + [JsonProperty("displayName")] + public string DisplayName { get; set; } + + [JsonProperty("email")] + public string Email { get; set; } + + [JsonProperty("smsNumber")] + public string SmsNumber { get; set; } + + [JsonProperty("tokens")] + public List Tokens { get; set; } + } +} diff --git a/attic/WinUI/Fonts/segoeui.ttf b/attic/WinUI/Fonts/segoeui.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fc18ebd0ad42f4c1dc52fe87952224adc13695c9 GIT binary patch literal 910308 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�eXKeWDgeYbjh{l69Be|10u`F}U!w>Suk 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�H7Dvvo-M&Xze#Hf(<~7&Ot}_&zzX zWyOlS|H%Byr-f*I@rQ)ric`1kxbN|4hYC@^djJUn%~=g=rQ@x1S%V=9P}sxwfiHs= z^~fc`!6ChY5(G(?I-g#-R;H6lb%D}nz*i4(kw?VxBK+MI;1^Kj>l;W3VMPPj6~*Nj zR%;U*o5Xeka13iMz*>9quQ1zyb(es>HHckh+$BWH2bG+JLW40YjcE0?ALJ(Z-8|-fM++J*WyYHi`pC@r`{2#mkF9K?IHUkpU0xn_qsVWeB4_rZ; z1(3pBlVRg)X?I^?oXfI z-KFiFfBOSaAKn*w{NW2&XT(u2T-l=nt#PU=PACb0uz^$}(aEXc9w?a*%jAKSN+j}E2O|g}@l>iH zAr(LqQl$)n3Rq}(YDByU1FGP~@|LsMv0W~AV!6S^86ZOo+H4>JND%>2;))j8iP3_V z4UpR~7oGZ=+5gS(2~@ScS?hz=rjnnI)V194;J{8M6rHSOjv;+2dhhkP#o^HYkbvAz zZyit&RFuTZq)HKgGn6LbsuC#BrDz`tyx{UcrI7Md`1$%mqaOt=fVLw*R3K`=wVxpn$h5VX%4o&);`S-=4_3J$qFlFdIcS~a( zgIiGI#;~E4^$2Gm;{1|AW90w z4l;j}SuBzBc|sxI7yLG$M-oB7w4cI<6v<@xs2j8XDICEe4rF}r{q#FfDz8> zz_evVG^{;Pmr`mXp<}#PveU8?e}bl$T@WUFm6^+I8@`L8kojteoFq62553Md4yKZM z?%h4;pG;A$pQjf^=s#wWG~Zw(ISj>__cwcwcb#@NK|XO2Dzk6${2B zyDJ2|w>gLeu?Aa1!pEqf;LVeqWrmQ^w%bNbKJnbKBMDDW zKlA-#+|IBw@NgY#6mO=>Ar1>wDtvtvifDnq#c0-s!0v?l8N)Rcq-8*FerSH<14&HU zULT%XO)5iVre3@|T>U3Vx$&gM23zCo&$3(sdjukb+a_>a;UXVwiQt%(3R+BfTv{sZ zyK>M{DHaE^6X?|DOO7Xd$>aOu%BG=!m%b}pQ+NCD@TVK@g*?VT8`n%F{yCV6UTLBm$QUVs>EMgvqz}PKG@}5dc6EVab z8``wVW1B};%-MzN3H{y724qj~ODEE>g?_^D!hLsRxboq==EE5j#cOcIi@U)>R|a>R zDYKuSnIfb0I(=kd6oi@N;5djf2S+I=G4vAc4VC-)`EwDhOW3;Q7~2Es^B|1j6>u3# zeuBKL7qQ{R&Wav6Il-t6#A52_*#{OnA6ai(h(g|eqjlYHZ$DnWI}1I|e7B~P`To1A zPwcKwnhzaleUOPD7Iu^kb)LR#f2wY2d)e$V-Tr~5$;0iBzZ7SDF{P-hvt-q@y8$~K z0kr~eSa@wNhZ#{}o8&5LlgOe`NJT1>%H=@AgD z{*NL5M-_BHK(LCEz|W7!kyQK`61n_rDwm2-sdxd>$B^HdK%pF7JquAJKJgghgN*$k z0d#t()&!y21XhLpRVZi00v4*Zeg|rb99J3|Jk^HaeFj-%q`?go+`0+P-aKQ*X6C@A zR-%kKKwB5WpGEEuQ8{ylFtoL`fvm|Swv#_lud#hKZM@ZwCGkr20# z!-*bmUcsssG$O>m!D6$&NT4szl>|&6JU06ao7SK?daV?1ix)^Fl8yRl?O3=9(9y+K z$~f1#82TCr?`)V{v@&geBxPP)wC>OQi;4vo3`0 z*Fd^uKLiAnQsfJUB@R;nQWz69zK3@Q2g>AjZu}cIR-h$4GzrI5y>`~u4G^=O! zzM-$??*wCN!5`)gYPvpQPE$Ph+2O%ww?J#xyO`I{_7O$bA;hz+`Avj5wHl7=XrLuu zUZhI_{u@4g34N(v@LrNKACDggo)5&qEh?5OtUCuZS3@=N&anF`!FT@wyLE^)`_XrB zGFHJoFTy?jV3WWzE%oVv^Ch60^y`&M`M%J>gwGxz++8t-Y!r|+mF@V}q#omGmlE~g zF<;*J6x}}j0`t)M2cc31(Z9d+Av{P+Kpl7A5n>Wx@Dx-=EPb;u{R%ET(~)mcR~3ANS)(S1vxX2H37k%MaHL&3j|b<9DQAd zzEY?tin`|mrpPYl2ZjYOS+7G+qs){YQ`#b^@@p_S$GW49eCBEg`Q_5&^r@Qbp#T~9 zn^8MJ#(B7USPvJMt>X1?;XD=WeZejld@87UJYN}ng7pac3n`vhsR-9;gMz}v6y>MU zL|VXz45EybZ>T~@>fmCQT0Dt^Y=$H&GeL{P_N*O<#(;2bHH*){SczN#Y_PEFe-Tr~3j=aE6dZ^RgWH%5^us;lBx2TKvDJ zU^>glwS4xIzA!>c7Xz2F*OuJ));E~D>s5T^cR=hH;FBNom*Tr~PvMEqlY}}31>h&Z z2Qf4^zUALL3JsA$1-mbdTrW6-Z1@ovnq6?^XEdH{`*#xy3kjAiz@0)haBvrTuiP+l z<@X%a6R#}tUKz(eeUN7+lE>hO?+H-AT97H;D>0mpjKb+%HUBT5x)4a^5t6XtOIb+Q zz_nNCBXHLg&s~4QkixZvo@;YQu7%y87mwW6vrd35c%N`(GQsCT1AX`%d*{Hb0KbD3 z!o5#tvhQ2Gzw@E%C%kWCe+T-7*x|cyHSUHh;7uaoyoAre>jGlrbqn`8exE+XzJClL z1z#}SXEOUc)*rxE0KXS_f2Snu`+y7F53c7!WgNT@m;irGhx>m3e1m(-7{O**o4Jta6`cmb%YZ4Zgo)_RNb&a*}w$oqv+~?&3_ExHd59 zj(2tv7Wcb5-??KFH5XunwZ&@(l2*^va7lZ@!+8`G#>H5LK|Q>vKB2WwC4?`YAH?p0 zJXPSHvy4r-WD^TN(LsB4~rvquw&?|-mo`mBeF&18sK8bdEpnkJ{=G_a^ zQWxGev+*qs{!J^lhv&7V*F%2=FXV@9Gx}%FJUlP?Fo(hQ$9LRO+@7I!e*ixI(RDUM zEkO})3U8h(CBH{M#g@?%oM{eD>Y1buo-`>~Pr~9yN7u-^>8h+g=-4$SvrnC_Hp3S$ zP6E4;5j?sZ?74znj9@gd$2Yq%9!(Z{uwXYMTM0FBrx2WZFi6O5ci;(s4j8v(w<8XH zybdEvLP8B8%mKw2#Urco^F3w0@A7PB1Hx^lzy=`DHT+gGAi z&)QAgdTz@PC(k=Pb7ubx+jTp)j-%^}!ig|-MtkucJ4RL(cN_eY!u?!=c@Q_{cgy7= z0m1%ppy&jMaabcbSk()OuAmcu;|~670-qhL7Qkr?$sVdesYCz`x4Hf^Nm7XgYcaEr zUP18}9((OI<~i)4`{Cf7d-i_y?qPa*^$X8KpO)iqyb0d9`(Tnhq7NTz0TzU6sdcOu zQO`?uX+ziP0(1dkif-E9<^hD#hoaEX;9f0Q_F1oDIK05Xo`L=aWJyEqGEU(c@z>#% zXQwqf;b@1G|L$w2>gPR&0`9>uZGCNLQQ_8SR?mC9^5BA?Mb9B>-!Y`Vv;+W~aqPV{ zt1l1M#U;3pqD^Y3BcN}*LQkb%w)<@~j40HB7BO!#I`lD$WcE^kH8qYilVAqdOjl6cx>RY8ITgNG z4$aO=VtF(ZXJc7`Q?uX)m%@?Mr*a9=EqJy`;(qH2{)d$g_=6Q4j}C>4W`2!-xhXoB zkilqXS=))J7w3VDVd%p0T4o>fwt!(~l0@YF89xrZ-HjZA>4- z;8Prn&#YZ?t|zC#!{7^2+c%XAKUlhUZ^eQe%GAo!RDUyCB>Nu>88wC-C%n~^0RMqik~QXMSV34j zPdXG1;DS`(XWiidx(7(e#}cAC9WuF#|nw)9o5g zZ>+6t94}c8aN9MyeGNH1=a#HJv)D0(6FCjtrP{m&6?@l~J~&*msXg_k+ltDIYMQI? z84A;5`R{^e1G*SEbg*voJyi-?5Z`AP{02IZk<~&#D)3MNWkKiR3=^FN?|Bu$!{z|? zVuSmdvRr!?-Yr;!ePSmWKfyGpD2nCbSs1KvR^lvQqlm=o%;n3#AQm>ft|i&CN(v=L zDyN;~AN98sX9mt#q^F|SA3oc%?c;OXY%ZHjIOr?Y#c3M*F5j{KnRQw2`QLV*9A5P~ zDQ33kwq$CLr@G=C!8E0ej&vTV%UEQ$&P+;gGb%&Gv|r?uB6RxdHPix4_wNGuZamKT z5vKq?9oA+Q1WLI-+sbRx*47+D$5QlM5}DRe_? z?0ua@`H;P7!{CEWw|(%)R$CS<2yvWyHqks0SEjUnZB+~u8z^Hut8wk*cB!S=& z=dla|HUb8~gS+SHcg7alf)0ho=T4p)!y=4|x#!&}jw(t)Pcj*$3ns;@{V=xf#h%+k zI==e`l}(+27=weCf-4OXpTZl>$$mB%${x~`(-8~Qz~_?KwP032lnMW%;UDGy4)ei- z#j)*&7tQ!hd*@Sa2j1S66`aw&|I*fkvdXsN()IDqE#*a>O;egWik-_JrO~drvC_f94F(T4|8d0bHSX#pte2D@${}|mL>d$ zsJwaM!uMWGd}Y2ZJ;j>iS<8;ivM*S%KL0<#>iXyB$YU&4K;_4%wSZLwP@IjI2wi`; zSS+UPiHk1~(a;IZVfUhd2|R7hN3UJ1PidLGc4~Q#-MP8EV(r`+b5@t@txNhI{=?t5 z5gRUC_zefF2or&G+M*OX#9@U-SFp$$YeKXZz2uiOt#wKgbM_o{&nQ%QtvTw*{$;4Z zULCUy|2c&Eig=`OOfONic9&?0qLVNEW&M8ytxu%Jnr4z5k1S|%SQ|=hqj2+rAs_Nz z5JA_&N+$Etfky07RVK(TR=>n~P+&n@z_AKpAeucoKdxq*) zonDj_Q?+>8VAZ3{zh3Oi)W`JJ`N)Mt)x3K;oe6cT3X3-{ZL7*uHh#6ATVH50ra`%@ zo02APJJ->)z9tTMoA1j%4(^G-SapY=Wpe)Xja8sf1<_km#!XCZb0 z%p=fZn}8z+0{{#H0B|914mK6R!dr>q?fUJDudmI=)PZ7s6haOk%Lv$;mSM0Pz8T=a zChItOt78Kx0uh)wRA1pGBPIsCY@aXcffb*yukKee$KMjz_z*L!hUNHwbmX{-f z8aVU6z+mO6MNTN9k1TWsPG73yn-^|BT>UG!a9c12m-5Z0XQWmqsgI}U+8k>77ZIAU z6PS8fd?G<2VvN|G7>~~w`uUaZn25|GKxP~vP283V)I`>epppu;Dr#`{jnL9fHfKC8 zd^p{Y2}=3tyd+);%-XKv)q3Y`;}eYrhosYqhuLMqXm)(Wf!2zTmXX7aPK*U^;miSG z7O%*+0F$ss033SySXIj8&Vk=%_WP zdTNBXr`l9Bt&FiG-HA1a?=^+R`AK?n`XsYHGp{%*sEo`6erh}S-q-u;CaF`K<)Tb2agU=BrR zbVzXa1Qb&)TsSg{QJtZr3NYGK6RV^!yCL+}7;Lg~N^XV?MF2K&yj)%(uM|8lQ+|dG zPKO*h482_U-yz0rUPy3qS8iZ*OLLt$_0h?XM~OzFEztDz*ZYW#;gOTW^@@-u6GgIES^OO zQU{Qu6pZ!32?XyLB?Db%F09R1qNaHVub+p`Y^y*|;4~ocr{PI_9(RhDkG)nBr@CXE zD3fx;(q3)`*7xcUn3JgoDjIXvOiy7KV?|O(M2M*5z?FON{`1x}v1q^0-`alP>RETR zrx~DeKuCB@LWl-Y)0VY1Y$+dq8j!H>)u(r?3E{wLVE7A%Z0O2I z9(g2r!<&b%6y0n_}`&NsK!m5?%_S39<9w^_h?tvrqZI- z&gRXP;qeO|*+ArVZh~R$%=;kXK%4rWxDOz})~*+V5p$0-b;mrKxDOsZ#_nSc!3j_O zXw>$@)*ul);c2JfX%IW`J`J{NL~$EuVNZN4YiG|`s-Z%1i;BZovy-*6$3LElzKOLx z76x|B>i`CbtlSI+mbAu_(M=W~gCZ}U7D`Dct$TFsuWSQj%bnrU9gi?K_s?O;)56PheWfbVv0zPjPE)EXBfmH=E!N<$D7E%{OKE4MAulhtdPFxOE==j}%}kqL zWs|GqZ4Kt8wi!{gp2{y;)sW)5_@0HiMxpyd|4^IJG_5>w=mACQ5#!STj>%RGHsepM^awCp)xDcq&X#yeWC*gbTB0tQ>HS|7wc0BJj$wZi5AVQWO?B|GBKz86*`7&ZGK?2qT+^5sTRPolwnxXh8uM$`HKfVz2{6WIM@6Q@MW;?qjh{PvdSMjpPf{jp-HZlW zovH~-iBj=@DuHdp_AYabD55jLC#QxC2ItNFa-O3NXUyFUyPrGk_#B{ZH^Jd1PCO<6 zV4+t|1knTCDS%El;z#%;pXn{Y^UAGXaHa;_1kevT9B$!YMbA$J_ooHyit;wPpW&aT zW`lI~X!@8ZVkz)Fd-#F1OK)-zfQT9~Ug=+>B>w5Z+*##mF(#SH8lbi$fo3wPhzbre=mkr>ZkDQlr&m`_GnRI$jR& zaSpP)v~tw%#_3nT%1a~LhL4;7m~ReqyT+WkaN)ma6XpqknPNux0=$JBUxfWKUjT%+ z!|LzmV%J|4fT+3&w5lIf%C$1C6Jim=2z3tdC)r5VlrS0vK5j zy89@<;i^P1x*=%+WVY9;B;wT(p)ge^eZFl+R;97Fx!sn(aB@^^`K*-k!BPP&*F^?C zS+Fw7xwg<8uMvukPGWlY?mas)Gdtt0T_saz9|I-U4tO|i-0N=q@1WIM#r)9t;)KAg67_!v^`!fz7~=Kf*eQ)0zc!Trg%jCcQeB`PE(7Mg>xwiu?$Dyg(2OfPc?B$34_ zhD{{Op0zGh66QD2`x&xvjDLvrlWpZ>%zd=LuGc4e9b%@*Yijj@TDtq;#fb6}gI61Me%)Jcw6`vGBW|UWM0-1y+Q@W7G1^AQQ$4pSstRpo%IY@$4$ zVA$k5xXLu{s?jY*?{m8?(~H>cR>v3=BipSamEnm-?_LMWNj`-X{=UJno@)Zav`R>S z4o?j8UZa#lGe-|WkRcCql!2go9#F6QSz--K8ULSm(f#aA_v==>hxGxh~H|G8?c!X$v6%Uuxec5QBNx^tL{AeoN{D;Um<5h zu~BVHN3Z>-SMqD5VN#k5of05ML~forJyMAUYfimdDDinK(&Q@-m1#0Gl9aFh!|Paz zbk8SF!%p661>J9st{}VK=p~=`!8UP>Xm<|oXz?1WW7Rv5TX^-bhde30(VCcT5-DR; z;W>7#IyNiZoUhSnv{`NW@r_AnE|O|YN^z)4B-2=w@(2M6l4;{J^ge!pQ5g|og()U$ zY|Ns<%=wjZl3_E0D3?E8iMZ=>Y1$s1D)9RR)fOCZ6A+kLK}?sj!@Y#? z3$Ebvd{Oq{ABO)m3-31N8THH?+Bg6?Ed^( z8TH8Ls0-(j0;IGH*MOkEd22H$Y)tS8G31frDyW^*0eCu8dYWLen`b&EM7r4eBkBNS zYeU8Ek8}bGI%$c5*qN9#vvnyF5?f3GZYY^>PY(=XhhoCrBsad|e+qYt;PDKjm0AeO zi9tid2MaraHAyBnU_+jJ2LIDb%z25FqNV=KsaMfQ%+TsiNsOZEg~_Rj8JS7W#rbGC zGKtheN*9dcpJg%#Q%JNhJjnfL;xZBMCKlhDbXj>sQ&K`KAc7g6;Dq383;L%U%4{$^ z-_tJG0Rxod5Kz<1mRdnmcG5_UfFn0RQM$^GXcv^sS6zHr5lj(5%1ck7rhnNY+uMfY zEn!jbWg*>*La5#nEOXw66I9tz*P5zbx7%BeyX3C?XW-G?t5a-9Lhr zkm5>oysyxwBTxmsiJ_(o4hUSvk_1&OP+o>^|Dt<|@b7>adifI5mUD8pck-0`6MAq_ z$2qjao#Kum)+g9T#!o>{L+C2@HPrAz#Ri8PR-W0(rrc;9h$KKS6ZWV9cJah_=&xB6 zKarPr_1DALC@4f+^;O-TxjDiwt}CtO^IWCNtE`ceI&%w`O^Nj&y0qbrSz@`-(gZwhL&t+|5d|dF^m;U5uu-Y|+i^?POR-fn~|KR=uR4!g6D%?I_ z?Ku=x)|pGR3QdJ+Oa=NdFwqtXv$}Iz))Y4O&rLbN823Z!a4X@nWlctF9#n!sbt}|# z;)&c5knxJWTL!Grusun@WCrsAK;zn@K?K5}#D^njIUX%j0G0h=5T@X#x?`vZ51#7V z_I}&lD~kMfwpDI<`cy{ss%|@k!%#=&!FpVZGmLIqmD*lz_dEIAYcHd>PhIF5Y)$Vv zKJPB(N0h!WOtPmlud^(&HPw~7?)(zRp2N|T7v{vH+`}LqxQ;^Hgj)~C0I6W^1NO5x zRZeL3Ah3`lvuW9m6^L3lchy6ena}$c?D(9UPm8$_Ca@ygt~nboF)tiid?#}Q-yKV! zAA$ZA@C$TEg?r)23s_{pGn^JDv3cd&S2|`)?pwbb@ZBU#hXB`dLfs$2jLgLi@!bqR<8PpEtTtlD7RlUu@adOxRzK8PFwAsK;BDf$ zk~{u7+*rEz_1jJ}XC9mX!7FnvY@h6&P7@P2+kIE_sqcEb-#RpngM|J&;DvLxF(e)m zXJsLtn&6Q%PzpN=261KC4siL$rp(P zw>503ZrV31nNgF=t}*w&*~BsT(n-5sS~Ktb7MzF-azHobdx?;LvB13)R_Xw=gIW%-OHn>VVwS3p<=k}er_ug~+QQdxK z2U>=zKCWeqKzHq}%)Zy)4xn2TcR^2X>?XlYH=yALp5VtRF>Kc%rPN8R`0m~Z;ZH){ z^8C_hTgIvHh;RGc$Iy>+@0TR-pA@4HHd&b-mALi^39DFBhV`7ny*&028^;~>PsqF) z7fG>I7an>gzqtQoLS?ExIH?BY#e$@gZO^ReJh!R%jaUAfG_$w<*hQuuSq0x|j7c-%jqCW=m+= zSdlintrZ}|Cy_twBMr5USTX~#&_FV@zdLA{a9yt(hMl_#Jpu+{U9=!C%#feq-7A)% zU}@k?!T(6}wxNgcd@uNqI&-a@`v()L&z^;aoez9#70#vE6wdJwkFy#Tt}Y!a>x8fHM|ON!VkkUuAm^Q(>=W<%?%*9r{>_DynXaSHf4ghJ6Whw1t+$oWH~@+?0ePlh zKqVmV;28-3AkJmwp+sE4jWr3x*~qM`-%JfK`RR)mFV9YE&JE95u&dM-$4tJ6>S&pW zMl;<5u_X>osw2peo)ex6MeC}q56y`(=S_DOEi5(j$v!vX7i%ILu6?aEJM?Mk!O4wz zz>vg^r=WA(AAzfaIXFPfdL5Y1y#-DU_5|SoVc~F^!^l4}kv*R#RHf;27w#!lnB>f= z^U!~vPx$#jMv_nLq$F*zEXo=o4ijl%=nM?D4@s&_Dq2`#CJ6G2>))39o7H6CwL6q1 zhrUi`N;Xx3c?9$Y{km{(vmnR{=ON5Nfq^n56zhT%hO-vf%Pz%U)=@P?fZ8pK*7i8I zd~{F4tcSkdn6q|%y#%R^o)b!)ESZ@RGWR#kHz)6B{(i9| zEUnD?6f9Ebf`P_}@_~1E-u~WTm8J0jTipaz$$S@_`0>0{fCC@*kfnozMeKLHQRCxU za6FA1_%Lwk!Gr0m=2a=@l0h-~wupkX1Z9b~thOU__m9fUD>#8GRzC&ZOs&M;@Ju7~@XEHwZYj<$RKBn1~H~vcO28jVD zhZBHwLUavgBw9dnK+O%C0)pFdLFWioqg!dMoKqMU9v)UWr_vgp8B<%0vzl!b8m2aW+ti@Ken;3c-ylpmz?d+DcbzhoN|yzWd(d)a#>7tNs>;G={j*V zC{in36l~Q=vx7=+e|GtX-|s3dzWs%@tA4w?oIK{7GcbM0$@rj z`s{1&7o@t#phZ$`WKg^d)&^`s;u*@0Z5t;ji;#22{wqdrF!NA9Q%p3tx9>nzJCJL~ zwM&>A-G4zPgdF;VftF3fKnU1ltPeo%4GULB!FJ?EuB8i<(W+Ga+~rxCs3?urYW??~ z{X)Mk(>Wq|d4yJDu|W3*cz!4`Nc@?;7iw66xAE*Il~YdqnR$B^^OsGp`T4y|-+TSv zq_6wYxLBeD@8v3{kNf~=AK=DXJ*IcqNq_;99jhK$yap_LtZ?2RAWD2T;8-hros&Fi zY)DRMo|2=?-f7HGgf-8Z8*}J@WlGP~(v2<7+MSOy;l4k~owZ4k6-!FXZl9e|w&_%} z9HOex_GEQ*t(Cc;kSnb&>!uRFAkm9jn?bg?(>XamKgLoveMLp<-sV_n38YG_N^@4^ zWSY#?9o>`LcQ?gS(g>9%S|e5{0T%u<{}3a_kCD0|J1#}>v0#ZhnI+2@OH ze2ps5YtZS5r}9uCJ`-RK@KSuJiqOhJ!p*`CVW3>X54Xu6dMwjMs`RrKv}xqQ>Dk#@ zzYMb~QY*vv;{6EsdKaHk&IuIF-bkj6P^ltyGPuc)_$Hp8;X8aBK5x14Cd>(Z2K!0C z5|pF#yOu3O&oBz~EtY2s0n$O*2ks8AI!9DEPP~$GJNY5L4|iYodoFzZCH#9(ghnc5 zpRJV<)i4_htKE>*_8IyUeJ4JBO-7P-(4?KTqZ5-NpjmBf#Gwe=XT*8!fC3FN9kB4R zyw8YtxT_IdN1Bu-uvcSka3P9iu0~8EZ{RBx16nsrfpB;Bdh9(g$>jKTH}k5$`as z!$+9c5kF#51mY9(6if#igpU#D-6e3$6VQV;p0ve0}$%%~NNt9u7#DQT<^?3iJL6+@#wDai%za|g8V9;;pKr=YNzv!d2~SG`)ed}m=&JC0Vhy_=KxD%2 z|0xoFkFIX;yeDQx-xD+65n{&ko{29bx_t`(1K_^V1CRwCCLAga9Cs1jjazDNZ%s;_ zwWoIJ^m()A?GhoFZp4qusdJ=sCi3$VQfK$owH#WQVOpEKY0aFJrW~Wr0B|+%^~C4C zsd(o=bH&|Yq{vQuzLHrE4FHBhe);i2+_(TZ~Td`L-D?GfCU~-#FNA2&M`6w zMAJww{pXf1j}D2jglH`0Z#0n+p`noxd>xTl86FyHGKGei%xdmC{MllYaprcU-Ofxw z55S)L!(%@8P2q`HtsV{;Y#?!QRg(2cBpSc|0M%?>wat{@nz43qQN;oH#6xqL3riO` zr)7nqdCZNx%yocc17An_!<|T;1WtauJ}`C(jLHdjBmGyba8F*jY4z9}lIrW9lWOL| zvQF!xg9vt;#c74whp-98yfBdVsgI2Ro2-Cmj0+|)dGbxGxItCz0cURAj%o%s%+XynVt zYe1XWV&e`5tV_cJWnu+sB8igMrf;s;JR_C=+NxETeO(>5m8Z>)>+G1nD*#Oyp;QM@ zs(t#V3g&)Tykk{cn(T7fSb~KWYzM|(1#_WXk{L-O!4g-3@l( zq<0rErW0xRR_iAI+0B6eVBN@OxEl@phg~EFvf2IneZRV@d^eS3e$e6~F}e!TB@*&vH8jbw5RK#u+|m znRwrC1#>_;o56-D;5A?1iBRqtK|sQ$G*~#X59u>FRJbT%yB-_k}V);kJp7uShX?nlt z8HX1w8=h|$ho?98%uOw^N~F3RSoed`V4(WJnAlHLYNSDG5xq9Kg%wD z)j!G>FTYk9l)vP_vHK@IhUAYmwm!#v^mN_nqg&gP>41V=Z|vIo%GSJ`EiY}^^Y)%1 z_d8?n0!eEi_aHNn!gCJr{HsQnW4RJd3!4+RJ&X)fM$#zMHvm%NVN|9cAyjKbnmA%1 zv5vS%P;nXrZ2~p4Ma-vzpdsWXwgF5N?x=nVw>!GTHc);w0h)|TKDgA>1WTsGUThHM zoWBUX`W`PQK0ZAbE^0spq9S1t>#9sHckc{@C!q$uspcHU!(4PZ77U+%am}P=7#wNL3>n9du2?#-C zNV9gKc8~T!Eu~#4-6kcZ4GNU1C{Yj!p2;M)@I!s&fDJdz*bZPPG@-brOOg+o0KYi< zr34;EL`%saI}RcPlm+k+(d;iWmKezCHTUjaIW>OBlHW9cS?W;AlKImMB8C#`R`0!g z3e2eTO_|w$iTUZi$1e8%<*HYP2dO+&M$J> z&EE{v)C@Gd@x~j|FS`S3YKSoQTTKmp`rF!pfm-+HucM+`_;dZy%a<=tXMefYTj6*y zq2jrsh%!`4bTd~mmk5s?wHI_k}DYxZA@{-z&3PS2~Uxe7m^ zqSwjFni{u1-0L4T-|mOk`oCdcMmt}>wvD@xeV;kMb0@T^e)TnifH1=~CMN?;@l^uoQ9PS@K6un?r*RII+sKgXdpv1qz_4k%49M))1mt*^qIyz zT!9v(xbZi(o261b4*_>q#DPGt&9KgbaHJ065&SOZ!K{>o%rk7?MJBL{QF;0$WzQ4tKb=1MF?cp9S}6Ds!lVmO zA2fJe>^>~E8FV%&(FW1a7G{9$RAUaX5CSp4m1!V@PUg%h7hFnVab;$6B1B15! zU}^xEqJRU_d66!q&e3a?_abEVv-YH_sO7FjqePfyIYOF|RILPWdF)uP$jkFh89*6c-hmoX>l_2ARBL5*s-OCb{*NMNp*0XnH)r*!ozC6Jl`9Zj>Y;0d>w9OzM} zChkDtiH)(L91Bdkm10jW>l+})g%|k(vP_absoK(gYQD`nbyM9?!O@0}`&Z_=Rz1-9 z$}DOqE-yN8*MY1RmixV-#;}S_Gs?H5{96{LmgKFvf99lTUj9uvh{BJIkwsgc=vsGq zU)8C7#G&lozU?W)r!~REByZrcU{gni)dcp@Anfoy*fAwf?~*8Br+j&$)34v2y&F(jk-S*@3{Yf^vp-hX_mVGOv;FD2N=nI_v0Q)CV+TGqYxUN z{XE_8<3sdo@TdWWuYZw7Lx%PTiv#j>!`46uz zh^bytlGl+Jmb>cY?6gJgwPC~Vr_0u~l^YDzZCzP~a|(>74?p)L6!Y#ZotD*gq&a^@ zeX0*7OP)M8uX;zDQ(=tPbY6Ym;;M=!{t;7}q%pdtIeOObxc&Cbj^YTw2ltZPPX)u7 z;K64gF%jv+8f$-$gwXfXfe1JKX8Y~l0w1m(lXaZ_93NcYik)tO zF~2^)b5f)%)F>;tzF4A-)e;dQF$P(%H9f3y(gsy@PSn(?-2TuC*dHx)SqgQD{37}+ z7M`wGN!j|~^z+aJ78zdcc639$ZgbB03Y{H1L2{2?LCjtAo2`Z3{m5JY*wTIfINjX( z$hEx{U8U?U#MiAZS@z7}WV>c?qMC0R!+Eae)tSpqF!zIaOX_@+w5^ z4nVZujvCt+CeI#dTKL%J;^M8(tZX~nnTEIHX?DTaZ?E217aLx&ak{fMT^E!zEt^lM zJnNnd%HQG_`l?4ZB#&G1w7Gq?RehaVcpDjZx_^g{ zVUAmq5(qpj)yAwn$iVUJ(0%)GeBGK7mg;j^UKk!n{9%wCvx8ZlQk$aj&^ac5DidJi zsGaA5Eo4Bg=2@Zn6^6|-q!Gq;uXdrQb_#1nfhzVm1fMv}Q!;Rq z2iYT#I_wS-O60-Hg2j`q#;iIAOiUW)Mkx_4cMu+(B#X?onTRk1e+-!osqs_N3@|Y1 zBX_Q6oDx$)NMLr7CMq-l=mY|5kmEH7zO`UifJjD3{Gb<*3|eV&s*x%s3oAxgF$0Le z8eugy;%g$xo2TXe@-i_CBJzt&0mO6AlKY;(5ceM9A$*QS!kXZCuz)8%5ACW5Z>v{~ zF7^jX4U|80f;v2mjvSzgs|@~30JutyIjQT@!n>-Wvepk~bSFI#nQ zTUJ-gBsEoY>f~J~BzkjnXrRo!G;0>5<`7e&`uaPDQ{4~Kk-1HD0F0;nebKtp9UEq! zTAODsnVX0BOx}iR%L+6!@l(RIRYmulxc=p_`wCapLDZMTa~mQ50#9F0hHCCySGdvC zua^V`_J^eOM@022eEcIcijWA%{_+oz*!%qhGvVZ7r9DSe(ElF(NC zlo`UKoab6%GQo5yHUbE_)gI*loY=I$+ocbzOSW1i$;q$7?Q7S+l1cS`U$&|y2CYN< zw;w#X@1;K%r9Zaj{cU}x4n9Z`Z(QH{`yJau?8Px@v&y1}{p{uKsjF^7=#3@k*X8ys z5PSwXRe2~nNP?nP54Aj8+t51Lb>UQnzfV;Q!zh_%3Uxy`tTmiN$oe@Azd&x zK@Yldm`kkFDhyiqLZ$$HFg~I$+2c6t83+ipb{ZF3NpYV9lO2ZNC3slyB?CGQB_&sz7Vw-xaGFM_hh|!4Mx4r;TAA>_bB7aR?~N0@T{lhWRcOWQ@_P z{J&=2Qu~S}%-?KzF-n2l5FEq2PWTQA1%H>QjSjFm37#Bi(FnVxhy6-&X{Ev&e8eXe zBvNC@hWlf##9RKGz&_4|&2Q{vGmN1?+^0|{%;n}R)%J?t|Q-KL%&$zxk~vMZGm z-5$B!V#;et3lmLRakOROT^%-@!q>e3vy`8DtUL`@BQoqckqQ)E*LPY3Nz> zeBq|Ymu!5!zv9^L>s5c)6xotOMW)ZIv?b3!)DCKIlA~#T>GjJ|W?h&?V~oNQ6d$RN zf)xhC{9HiCF z>!t(Tpi~!j97_wZ(oc&uq7akHcdDhXaN%rGkpGZaFHMMyi87Z>nLAsp9U^snA4#Z1 z)eu~zYMa!&h$7u(#0^@I9-EjTsuZ=>G%xZYHpA{30aiTL)6AO;2C;?r4%DVChVufx zyVF3{{{RSGh4*2kI8?Sqy5xGLGKkQ@fD=D(vH2k(Hz<^4Drg0a2Oq$HSfc?;1NR96 z8NtPU1r~)0Gy^EtvOo?dOcS+a$EsT@hALXraoOfiT^b|O>eXsJ5$YF}S`yu`T1D^} z6u7!3sw6$e|MO<;zvNkFW4in=@-*P0V<4r^0u`o0$28#kBz1o>Ie<{wfLyLmmc)kl z$4g?wQA)is*TYZja7%?A zy#_W4YdO^|EfK}DvYd@M;ZY?W>9xVmshN((Jj>8mj)ojOMzQm9VpD0d2+w%`COpXq z=5>-Cy|b{bU|x~Ql0V&p4_@(%E(@abd*kDAq`(yRK7B>2BAfOn`-q7#QI<3g6E_U}SzIBLX{>FY|BUuqGDQ%Hv zosr{z?)-ci&QF+w!V5TS)0!k8(J!%z6qGVTvIUzF!iFXtnfT~5TTJvw-V~cuLK1q? znB>w2Dj^Fj=c!!k>9Z0!6tmGpHFGScDkp|7GKU34M%ZfQ0WcDPbSJ>3&S9Rr*;A>*G>8vr3jmfsRvs<1G0yqj zhdHlCd_;mgf-fwPu)G}$tiT90I9`BNPOeue)NViq2`QE1K4qd1bLOrSIZRhN<+?Bb)y+5!N+zAUwfcZAQAymHG;{jV(|X;k>j{@G4$pM2 z3xf3r`%9n$UI+u^KQ#G^h^fZJJt z0rn&YY{_h12`}3f9@`%oos|d!En{LLB{}^Pxj8&ISgr#JkPnmS{r#Pz+r;|OWGu3< zS1Qn>IYQ(FHMdzt4tEC>3~_3-9-P+fSUVcKQSeTBX%kO<1!)bsDF0t`ipom1Keu9T zjeTWRSq!zD`B&TETqp5IBCd9I*@JtxzlQ=AQyY=CY)f)3bN^kZ(o@i(s%4Oo8y6nN zbfsL6BDO5cm{no-ppnXH z(+fXMnX|vSd|kYIof1XwIUHNL0NQlnHTn|PCt~eqErmA6fh3L)9oC z9>JHy)UOVV?UzXS{X)(i<0WISg@Fk|K4BR=9vVH=zpy02y8S?Z#MOUrsdqhEevbH( z$1r6)w}Sc8eDCT|zbRf(=McEtgeUuV9#;_ke#tdm*N%8sf`}YJd(!r2mfm)b;xF>-AsB=l}{gDzC;ArUQ2a*~65Gr6jfY^J+ zdKoNSt{vxn!dg%mdoZ)MI8Zp0bimn+se?Pcyo65=?)qa^&RcuD>5KtE{=v}Ao2Bu3 zpz#wW+n-r6HpkJ%zIq~PaYx5uZ&D*d+YwG@tnck`Ub@)x(vITsX^!0M&%VZT^jW~l z1(Ae8=-+B{g^>AW2^4L&XY|KOH2r}RUkjLuG+o4Dh$RwMh2d=D{O}$@G*J(}8M+{x z>>l~$Ik8!S=fo8~$jYf|b5`)LVUH!(Do(huS)N&`=wR7mPLc)5rFC1?IT63K79i8S z;*QJuoO9F;;_mvVUO9(&-C$6E3Yp7L8Rha9k^>@NGlvGK&n1AiuHiTM-(2RMIu{YdYhfYSKHyLX*Q#}Q1K@UNHjBv;ujRNaL1D;n) zs?8P=ml_qAs)_L7WxaQW3k6`y!b2TwXofQyaH1pDt{tqphf{SBo-x4&bqP)F?K2Y1 z1+D4nHO^q)5L<*)FOr7I2R2z;m63ag2bxQztRIwNAE<BN+S1WhDTS-%#W(jJ4%fBL2Qa~Lb1A#lEGxm24{GDg6E+) zy;!e-k}nuW3SPq_@MNreM!1y3x8V}M0fE3WpbZTPk%WrlU?MwqguuqaVFj8er>e1P zCL8(~r)*0>vBvPIMpEcOrzVd?SIjLan4o)(q(Hmx^{UZiy`io3RKj>&nuy@Cq1`jb zX`TQ#^(Mfb0Fu_`Qp1wPN)!W9seK^AVlt^M;xv%6-t`*?{?8W@2=!-XgBKGpTgT!; zb&XwRqw(fQ;YD{xdeItP{)D}?5jVvSHp4x241NfA!Y36#S4zwa^nln8zK}xfFJ|K@ z*usWEq##YfCSwVo&C~ZBi*`~m6tk$HWPx?TCQEy^sU$1bcZh6P>vW-Sq6Nv}614$h zh6FGD##b~So`Joqk*+|)K&bD4JRlUTjsTJuB$kLR1FYy~XB^|fr{Mj<@*8xNn>>`Q z2U38S7$4W1rb0ecw7eS1+$VriJP&1_+1E6=yrF(lsmfBisDzk24mf5>ICJX6Lqyev zO{-R|?q0tR{M$GB7%edyV$6Jc8yMs4)JO6YfF4FwLi8EWb|n1A#G8O%@#h^+X^#4)zCV+8O=iT?cBaI|$ z9gTKrM#~*7wyedLWXqD}70df7SvJOo7m&e(&43HU8*72E#|9cg(l3y>Nx*o4+A^5L zWU=BnG{rVe(>AnyRpN$>L|?wN4aBx)-rw_=#FCJ&`I_?6@wsQtJ@I??)tOX<6rvH9$)&Nr(?&5|La`GRSPG$zlc>?8D>3fyMkA)JT##y_MOJnw^0ro z4X>t#*U+0pJDHhPPgUhdO0u6S%`eU?U`%B;*Ng)#l<7O3n2kwetGaBU(9J*o zkR|g>CJlG2mpN)jzqzMq>e^W?8#)=~PF+8@3fpnxsVSE(X=Rif+wc2%eoZJlJ5-aO zZ~LReO7O<8x_+(-W^c4pGr+ZT>}_EN)J_c`~FO;Z%q-~udMQ((U~xqdVL zANEx_JrASY@lE+WOn^rTL`sS>GYgBd3iHM)xAo}lO*-qRs^Mcpczd6yr+|I`)DV8` zjW9OXpR`(!G-drK9*KebWqKsHYk0!gBT+~msm8bT;|F51HV^da@%qv~cp%rwq@K)A zoXkot>x3Ckv6a^?&no$-22w$^YW-0a)I%hVo)O9Ws6HmnAE}S2p((YcwMDf{7hZEw z`A2oroj7fEYbYc0$zaQ6_blf#^;S=P%Wb_UJyyZ}`AVPrmQ7CS-`_#LLCX1f<3P<= zl^RtwKWw#;%2`Zd+_bhQXMR*Xj}G3AY7f7 zS8Y{cU*xVC-kdPaeelW5XHxT;R&~VsI4yi}tgyJmj+fLfY$^TGCx6AS zt<8@k+W9fx*FV#_UUcK#8ePrQHqlSoLOPmiu8Y9WQ9{X!2!T+taVob0lO^X^1XIB@Do`3hHjvjlz z@Z~?0c)TpOHet7{Ve#zDqzpGFF(EH2D=V#pMMtwe>gj%bHXi|xJwXB`{`fq8Y}$8y z7k^yFPo2UaPD}XON2TCw9QXW4rnR#RTMNtFs>GT`|17`H@6W2qs>lkLm|PL6dYqSz z*5yAc*H4t{f0FBjSyLPG|7=vQzgOu0Nw9enW={CK5y5`yk^WGyZtTagiiB;*HNyKn z;2Ww4Wd>9DymW3}fET?~RB2jSCTA08Q?^{EaCTZ&T5fJaMpnvG z38B$`peFZSCRIngLD+Y0wZSZhKK`*gemSSMrGDp(uGmduhZDc-d+@?ru^(hS5q$Co z39*rLi0;>DJ5>oQeT)6a=;Ky6xks||b3L9K6N`m>#vr>0)s`E2?|U+sb`+FP$&-01foo3`PiD%+p%mF|VZ zyBBtUg_9wbRdX+$#xrhozvEl(Kdw6m%gTz1Q~i7#^6j7U=Fy~{y0v;hrtj^*^ytJf zNBf(b@_ft7+Sg2-SUIser>Z3ThHyhg@UFXj?b{Cdo}IaNYEj^Su>GS1Bl2gKwl$1y~Ay^Z1#`gGrY7If1sgG6= zK63%VmbTrFV0LB6tkSttRxSx-+?AS}R#8$>TG}>i+0t>@zp zd!}!Ou3IQ^#)5STvHx~ElU6QTn|Pb}H?a>AyNKSJ*k$$9@jdFhEAav+F^guWrrQg+ zsx&Fdb(rfkJwi%o-7@aaz>tF3>lgiDdOuog%5L`Eb*C@9V#ZscN!f*&=?(c4=GGVb zb03e3wl$H;kojof#F>31*uC|k*+urT{>h*2fba!3d^6O?T zzOAcn!qV&KExfh6KH>T&FF1$(X5pW|w&l)KPjw9+d3@&P?n%@6=B#=0n0ncr^b6P= zpZH2*r!OhvF71_kGvO!h7ZUGulCxH_k>*WOycv7f{X+aNM`B{{5z~Jh*6qNv8nF+@&Ct3 z%DQx7tCiTELHTx#{^m{g{Ea*VG5XEJv0nFY;(Peb`iUF)O*+qXOHv)>UF*zG_=&~D z3VgRXTSsDI1&k^FF5!nbG5MA+IrA#k$i6|0ebZr;|0$;?^(v<{_6;W~*Jn~3iBEc# z_^bag-v2e?H+?dmZ;Si}zgmxS_Ui<_v!rn>Y*PYG4vfT(!yDB|EOn?W_SN)0cCc=9 z9&)aE>6V1=CZ2b0=cB86&b5i>`>wlgUD;)=Ew2#V-m|W`xvpc*I1;QQ!5#cv$=~}E z&mV4_@6MlJ^-5y=uj?{1>#PmfI`gI0iMFX`I@Amk>=Uk|6_N$Xk)=ucAI%O2Sqp3} za^@d=Kal+k_OUpdZXL0_W6NtciD#9$hP~%hVB9+T<#!n0vX(VdS0f8=T~~awZN>F- z!_zO{KKoVIUtf0FZ4WI;8aMfpyT117CO(6=bIqqegJ&O^%bCh<*~PacgdHwUlA#73r<_RVCIau6Z|DpYd`gAJw8@f+g_dhS)V{yvT(w(8#~i0 zYbUo%E2+9@ikJ98O6{DUO}Edjn_iifp6dEP@qq*znKs1>l7EEv$bg(NlkGp_-}(q^ww7=<s zj@4sM(IOMhrhk;QrFshf%p^3%)l5EeBEkQsByz_Fw0bW8*gfnkB#LQeO+DwMkZVU) z_|N`UF;SJk3_~*i`Twh^rl~N}nwi~J5S|t&Xe+p;aY|a=Xx zr~0Ct$eB6re^{dQ>V{Nut!ea1f;p8H6Dl5l^44ozUq?dur1s)1H&oVE&h03x^(u?U z!=DaW~pCNJay9e3^%JjKQlQyoOh(5B(H96 zU1ohSyDGPUA!6l}#^ufR%NH-Kd1T~4V)>Tty0pTajEln6=>@^`*%h^!#W`sg>T)6l z-rW4k`uy_R%s=u3iQ(Fd%4;TPyprtF`oeHt>F|eh=O*SY>&Pw&r5DtXuSh%hYoA+~TR$#6bDUe} zR+ko1ue`9&cg<%;C+x_`4`rq2XQ$zOy!70b+@f*WdFk~f1>s=oe@-Y#FHCQm>mU7_ zz@Eq0f7*Y(sm9^^PM`j_rAzN!vc!#ieZu6Dalx$I4BA~*VMbmcCo_yZ}`PuHm-0bY!NVPv9y=Z*6VzQT?H1Tvzby2yS{GZh| zJ9a3|y}p9_6V^zEm2}dez12*T~#8Q?Ojw??ONb#33ID!ip$&^VqdJ9 z6i&|xe)e;;ooma^EFRxnoE0dm4;QsImR3}F8(QkSXH{nf*W6H25lqU@Oi9bkN}ZHd za8XmZIJ5Ag$>Cx*v+%m4n}$1{Dyb}=P?#EOoLS-XrRMs|z0%U`>_B!(Mrv|eN_A~8 zIH^1#E9G;4{L;DaW!2Y~W)+lXg)98!S-I)q!t84j{RytGxgf`v_-AS3-CvCcF8qC! zySXZ1R@JJi^A|5&%DRD{H^b4S6G@))yz{Da!g<4a6Ym1pqvX*Mj~q~#5i}z;7RSVZ z-mI-QUoc|cK4s>qAoQ_0S3adVKd7yx+Fmu2?Fcg3{Me=@^)AO0V?wZuW{Sz~qkqdb z7bNr6=XMxre-&3V&C!GXjuDw&CKQdHwaifB59-?j<5H(zddJf1`u9H6(EP;y?_ECg zrZr8u^=?C>va-XKIjc+S(^8WX zd~HR|MMZhz+ad+!g%esrE%PSiBvi$Qnx^LMb(en4e_bqkDB=DKw=bPMal@pPvYNWQ z#O>z~mrpA$C{O&>`E}TUKx#@?PIh`~c1m_dAduOW87RFdtvKzHtjx-s^x{C%>ip)G z$yEjalv$EhSRcuELzRU!lidHEkXAI&E1i&(k()XE)!FyWc9^Gcid~s9Iq3l3iht9s zcQ19XaPOyI@fYr2xrf|i?ho7_xj%8=cmK;*>?`%v`lkBk`j-2;d~1AsB?9+)SNpET z$Kn&dS3aw+G4e7TeJAn{D#Xab`)7AGe(yc4uEFT5)2c1+N~_9@`#yTlj%97VlBun9 z9!5U@s9&;Mrdf6S<6h=ypN4&?pBT0kB#h;&SNB+!e`0A>@kbtPWE?2}E&snd7gh8L z{-l0@wGLaIr`1>oVr0+8NLNC;P^@pv`<~iuQyaYR?Fagi{iR1>O*YfM#jED8nFzWf zBfDB?i`F?|EA^j}%#{xvWQE+VV>9Mk{g1{|f&wcAeGTx&Ar^Tzov zzN&G~_+Wz1moV4wpFBO%RF;{XG&jW;3I}*mCuS6vPYBV-)7+F`c}b|Sv1NKBKN5-L z7d95;HkWuE9kU`UGAGyOH?+>JokrKg`b7oS+bYhfR&OgW>*L;5TG424t1vHYg`J%n zSyI%{JiWT8Xj)xiLqTp+sJ5**qo}m9U^wz8bZFf2xpQN8er9LGoy`cKv?jfD+RT(d zQS8qPLc!FeJbE1Y>2(QNpX_>^KR?>%NPcO_lHWN?mb_SBpZH>Fn9fu~;mq>9gyPz1 z6_JL?WmD^l19LO8{E6k&ZeY%wfBm16#8%qTcKa_oj|Gmryx2dK)zy_%)YVn+j{uRe zRZEuKyL729aQbxYA5NUO{KN_O{?n(=Z#Z${*6)7TKkqXit?n~p6W{+-zbH5RPwE%- zF0HNpWUu3E_l@;BE}Ty;&&(_<4%Fo4gmQC3Daq@4`7p(Vtdh*k{Pc>(>{*iomD48{ z%&44`otu`OGp?i|lIzvirP4JUmsMOzn__J1Q6M_(g0_T~+yn)S~>X;W^et zp|=t$%1&JKiC)XKqkWaw;ia*I%M!kR^ZA0@D)+0gD<(9Rj0-f(tjP{`2Bu7#ynbR? zT}gh>JvIER;ZvmeR&0&+PXi5eYIB0~0yEkst*Qx=e>u=5tSQQB5 z4xg{Duo_ZPe+yCh`9z)n34Nl(E2U(5se(zIaHs2Gw9KY!|GteAVOdtLM~Yt@Q1S?d6&8@bz7I)Sj8|M&$Zu`l>TGk6d@|9l7q@ zGTbwIop1N?`{|!`U0-uwXZdHc1^*B8ca9JL(w!T>o;z-FoDZ&{L|wxt6BZ{NCC5B| zk({;KIXV2dBk_qoi_gR}^C#lJGJJB}2MHad$6J-fC(XC?@uR~hlb2Y0%HNN~Cwz4* zJ|)rOGdWsk=||!n@<~0Ycus|UoR70N9!+|c{T9`DK_Wi4FzJ8CIXhxAp$V5-e9C(x z@d}a^=+*@X3h&=$`0GCXR1^4Q8j8*tNUoS z+{Qk(hd(K)_0yl(iht_UT3@Zb_>MpLs@5mIHQe+5?%|*L#$^Xj{N9JOMoOfwXce*_ zCh}5l_MB7-lS7@RdQ!C7PZVv$Bz&rH_HBm$seJX#Dc^nde=6dF@7(gOSn+3-k=no) z$$UTb{{*ezAG{-xNOSds+Qft#l0pqL zy_st}sxui-#5xn(g_WNA-aY~pQf7dtBJldOw zFaG_V*j@hDIL}z^9=7_C`rU-}ivMQpp~PLRLRNF+(BhBz=JD5!KaKB)-;h4Xc18tu zrKKe$<2C?yUEG=Wrv_Vb(61Qz{b0#ByCTV#%>Sn*MTh^sG$rxdu}$Cq%K721Y+ksv z`Kk=xH{37FGr7JFaN)YxlPOatP1@8x;+x#}SS-~XLeujs`g3>kOAI=vo7m*B+&&yI zyg%{Uow0xW*0*B+v6&|d#vV?YhwQ?(6Ml9{@>9NWQ9@pxzoa0m?5W(WKuYOTnW^b{ zuI-cj>?g8j^oi$j#vX=+W;Z+HOGugb@3D@=J+Uu8{qS(oBkNsGP~^Is_9VLde;%v4 z@Qrs${?>dq;urg9%yDmxJ?wMbt$fi0smCU|KZ^xpTYb^kl`(uC*n>4HcoRG8igy0f27(lleWuKB+gQ!K_IfpVqDrc1 zYRz^N?>=Dyc4v35`F5{w{I`eqPnsC}w}i;qgD?FucJ)@kk5eOvLI>rY)^ z=hK56NF|-^muJs7|NbKB{C4i&{{rXLbMOLH!3ue!_tKAi;sBkJdv7V4SaqOt` zdrc@pkNMG&^-AWlM%@Y0jaK&F=_}AFl zah;o=^gWR>`?}qi48P_+zwU_}I}`pXcE$Q#*UtXLado*}I1u|)|FvIn&s}%$o>jgF zZ+!Wl73r}A_d-VZpC5=_h^1t#yz78HgRKUS`0Fj;q>#t1AfBNp@2N`9qhI?}Y8FS1 zZKJf-;68qak%gKuyGwPS>en;)^a%Jv>AK~Wd**+_gYUn_V*e+$Gj=YidiDnQROLU# zn2-P5eT7RO`u?q-blmIyI`++~h*iDR?Kq~LY*|GIl|MT5w`1JIj)m2c zHP^N0R?S&AW#*cxh3@7>cV5<7+@ zY2oekRsZg!nMv)OIY~e2_^elgta;&a{6EkC%iq0{^mYI4Z>RDe)3<4^Ot*s~iQ@AF64E|C)Z*)s6p6|gK%M`Ok z;ae5{S$wnO_f3p{2hJoWRr#bUpH$_O>R3Lh$|qI%q$;0O*YZhqEuU1^@<~-bsmdqK zS?2uONpm;C45u=F39OG_4d=(7feXZi;$pE&TrEByznC;1Dm*O4jjkgmSZ=OgOi@gl z*r^!h=_)r@xw&g}wb$i!WrzltaR4u>bm&P2w$S`2Fg?EJc=AD zDb>~RaC{c*Q}~F&N8{fo<~8MWR{2B~9@K9?P(ByLn9(g1%dI?ag~Fb~5rr#7J%u~o za&v3N1&UuKc8fh?uRWuCqrx|dw<)*V75==qP23^gA>L)r?%u8NJyu%xUMsEppkf}; z)khV6OyS2B{-VOW6yB|0J;AT4knJAWL4B@54#wm0mtnscwHUYD(zu>@n|P1ncf)Gl zaXwfbKM89^(^|FDqVPs>lXyEl!fI!?!Y{<%Bz!>OgW@s8oKpC-ct-p{ydcJm(n7Vn zK;czlx7Z_Yu)DaIiINbF(QFP>2RN%5@Z<0e>`mTNRg)<}{y?s#3T6+3m+WLraP zwUiIQ@zl*!SWoL1j|ESJ?L3jytrU2ruJ($zv)5$2vrpmu;tBDjkz)-;zgTYhxSrUl zm<{$@Bxbx^?6o_(w<*nCc1QO|Q*n@p7@(%IW@@(%+_(_bKHA;ukD8-wdwu-C;CU>$EAnK|CrB z8qq9Q(X8<{@m|G00qc>^Gca4Mq}|m^KIm0fuT)I0_&LQ~D_$pFFWw+pO|C~)Ps3*w zeo=Yu({J~S$B|(@605>Ji#Qz%(tu^Q^p^%~ak1DXt`^tEPjhu0t*im-{RZ4X zTWG*%jeVQaNVRWW8c8=UQ;+0O=Nr?^|W9S{$S zFDd@0?s%M<-{AC%r*!qSct$*{{0Eit1I2u(-(FC7SmBt$aSQYAHl~PaVun~~Y1|@( zE9}|bh&bNzcWcE3N+XH6OOXrh-bj70JTFl`8)%7*)CbFR zlk&MnIoSKXk#~yae?UAa9*S=v=CJbbQ}~GTKdO9Q)2~d|jnZ|ab4tHDEuInIQvQD@ z{!FwULZcH^K7-2V1C{537&BsNNrR;|7Fs@72A)^Fg+}ayg{`;H=vG>uZnbC@y%D_| zJH-XcZI#$9_K3YEPc&#b-z46qJgv{r=zd$v9#P6imGUu#A6NK`3hz>Qw{m!b9Gb9fdtkO`{huZ*+i#)0Pw|3)^}r7+y}l;B zRhzK*MtSL^e07opEeJStj~z4GTeV4V)h4}F zn_PRVHevJaYOm#qO|~@m=(qPN{sD0}G0n^Y9fjFqW&BFQwfw4?XSox$(~g>XmLI}- zNT3;;b_gyI7mAC;E^#$>teGdZe0s&t=~vf^*NNAQH;6ZioAuk9#GA!i#4X}hahteZ z+#&81cg23qy`EJ*FX}1w>Aw5Lmz3tX;`?L!NqIu?C&dr+q#r8HuoyRDyNn5zhPMV! zjkGPCq;QI^rimG1k=Us;^OZ)D!FE|b%f*%AD!U`26^rjy7|$hydlX)yaIZ-o8)fm5 zhI^N3fp?RY;eO@+fWlu;_#vfyL}?xqzX)4YKU>t(YhgromKdvitd7L`gqMF&Fn%Sb7+2UBuY@ue7Mm4iVHM2!Evqd$t zMK!ZUHM2!Evqg2Xg*s`!vO3v9ug|!fm?^wxyP(;JDbz+|J%0J7U`vN!i`a@Cp2Ac7 zBb=}B0&!vd1Tl-nu6RG;)r#Lp{!_4@mcwS`HifVH7;hGD5x0n2^{Z{-c5#QeQ{1f_ z4u}WEmlXe+@;{}R)8ZL1suF&nr}$8%x}fl|N)=N$ZeePjF-1(Xlx~KV2U|*+d1LY{ zNY&DK;sX1vyHMe!O1WHIDX!AhF6Gm$@M?v76kelnuSpe)YWZ(g{x>Onv%vsX#k7d6w1QTi za3VB2)=JGk2RrDuw_?pKW`4XLE)W-ri{j4`vsmGk@#Tb9iCv26R(Q3-JqoW;NiJ5{ z-rB85!%DJVW!|9hrFx1hmD1)VT6vpWIX8))Q%SBBuM@8qZ(y9>>fEUC=6DI=n{?ls z#aqNJ;-5(-x5@X>?apRWeqQC-s;k???cxq`r+A0b+$r8A-Yq^#>uaT_oep=agwLuB zFX-v^qVZO&glS}-o@KvyKq(K3FDd`SlKBzwsN`@=IlQhMj>ikgp|N?W${_9kj&&C|m6 zK5C_1TX?tfe8R%a9A1r2(#rVH;V$~C(|F5#6ZRX?7x8Gy*eTv8J^AM)2;Ao zg?kjXdDk}QVui2N-FwB2@d4sD>As)SU9J_c6R#I<5N{MWE6y#GT?DN^_@(Coz6?w`eW84GGVKyH&Plb@#8wZzaa&quOZECdqwz ziv8jNr93FUr2K83stp}&f&Gd(p_C`ZQ%ZSSJR`m%ncM7ioAZIR@S%QXa~ExzXKr&Y zD1KP+F@@t6rp+1?EN9v*`l2RSI7#6YT}=~hHnq*ovnQp^8Vl|2v{{QUQA}90xsf)_ zX1BT4a@*8$+i1D=s~WLWcbTudEU@zMhP8Z_ip#~7;woKL4WYGKO4SfrtA*Dn%?8sQ zt<`wB*lRVD)@paWQRP$}U_@hORvnT+^`bpvJMS;!X8r0W@n-QBaf@hgu6FAAMz~cm+r;hS4soZr zi#JF+y?x8`>sX$4)!uezugY(;lsPxKeo^@xQ23x|vj@|eJ+PclDdx0zM*Kj$ zAjXWeM`O9&1<4o}C}x$|E%t~TEKi=@c)8eXrKP1<4mXLnDTfCMcTkg8!fe)AI;hE4 z!s_^2uvWC0*bbi5Vp>Fd3v{TqcTn5g2+yY{gO4+Dp}0tC7Aw3GTi3z6z}TgjZiQDX z+@tUs=1V(x7g!n_`F3dJ+krfPN_dm*`#Ig~TJbvZdg@_^a|3U{4%WV7}r~rA?DdLV*ibWmJjyd(v&DBESmlA z!2WYz+5Zl;(+=#v{i;T^QG5q&*6z4K`KVUVaxJ&z;!1IquBujG|Lu;d71)0ZuTdJa z{~fab9kTx&%*jwEvHy0*8G^2PUn02)%T6m1mdX!Mw?ylCMeldD%bQYt>MncQ**|Lmq1W)N%lxI2exfNzBZ1Pzy z`7Fn-{+zI_eJp3~!@`TjF41P}mota(KD62R<&14D&CTL1;udkMxJ}$H?htp1FY1mj zDg2>0EXIx45OUTU#Bywf#bk&@VujtE8406GNE^2_%f*$VN=v)8_%-5YQRQSF!+!e^ zF{@O6R;m7U5#CI>Qbnuz=$zT$F4g=l)%-5i{4Uk}F4g=l)%-5i{4Uk}F4pc}=2wT~ zJ7FJoql+B{7XBVBsLT1jQ7xiNEuu>;qDw8JOD&>X?XFvQ@7CSBb@y)Fy<2zh*4?{x z_io+2TX*l~?r%8V-2Fk=Cms>)?%le3x9;ApyLapE-MV|X?!KDZa<#LX+H$qiLuEMcoHJz6R2p?230w)L_eXJz~XTqWANPY-i?#x<;3_R!*{ z!*$B-5^=p^tS`~yT&jGmj`dK-jJD#_jgi~KFk&EhTM7ICY%P24W-5O<1Z71ttv`>k2Owd@qKut{>QB)L|S zTq{YgMUq@alExy@WVIGqS3tL0PJm00+c~&^clssB&A3=GUE*rR zY*zRtg>M#b5x0n2b#(Q@;<3{Osy>z->ZDGCI!g{rZ^}OjU zjkSgKY76VJ8x~fn)E3sOEv(04SiH4`^=bG_>*ziPR7Aw9>G|g_H)h5Bs3Y&g6@a#s@?*^XTxK-RHZWnimJH;1u-YXP2(Gok5T1EJ{Ddhs{F{u zVs6)OA0m7iZ@o91%XsU(!7e4+%XcL`(i@dw4$-mF( zRsOx?Z(-Xt*X!DTxn5S{HZu2Md)qcLnl?6xwzq8~qdBAPOxx(#&a{n;xs0|mZKG>D z(>5|DGTP3xjf`}RH;E6zt0?&l=PJrG!`b9iVxKqh6nmhpn{U#(%DAM?`5m{EnC%B z*`}1+lyaL=Zd1x_O1Vubw<+azrQEKR+m&*=Qf^nu?Mk^_DR(I44yD|olslAihf?lP z${k9%Qz>^U{ZMWpMTXNeix$TzRc1v!% zCAZy@+iuBix8$~4a@#Gr?UvkjOK#7pJkO~-@msXWiAJkO~-?Lr=~sQe4RS~ z9T>GRHJ>o`%EG(h9gU}b z^Co)UwGr?0?oX*{&%0-I^(}V8KJWgW!ao=P5x#)5yP)lVdx4ok3(pWYU~^t@tY`m% zGiYHXOd2F?9B=XLX))U9_yr_v@pmbFuhKuF@MGc^#U~VRBbpa@uAjoU#R0{laOu9ac0%J3o@ob0?P4Zes5Eo}Rr_sK@>qf|E# zHXF51Hfo=2)IQm$eUyr;l*(u}a35u}u-T}6vQhhFqxQ*0?URk#CmXe2`R`Z$`<4HG z<-cF~?^pi&mH&R_zhC+9SN{8z|9<7aU-|D>{`-~xe&v5at?U5#?{N;Ol^swkJD^r} zK&|Y6TG;{aLK^O3H0yLgt?YnW*#Yio@n)S4sFfXL&sf+wNcrbM+v9qW9(js$keyV- zyY{v{$lMF@%)J;p6=OS84>I3kG50Cv0eFc1)zdIrtc+I?u4g=Qh@2To@^-!x+G-cG z9pYkUkPbO(7-JrCcEuimFY33yRLqCEdR}2$ojFAB0`ev`CRqMFwb9mM4)InsmRWkr z%pEDSu~TVuN8X{_k$0$Zjc9v>4l&1Nzq(E7?^F5*#8(vawm86O`jGpM!oP|~2oEae zH{$Oso^zMRbSsH3Pb?Hm#2T?yoX9)$5VK(~GnTWS%whFQ52Nd=37fazJk6kKBwYib)g8EWPA*SaLgz z+$_yP{Z@BGZkEFu@m8fbi5;d!SxQ@zJ%&OqPR6%Zi~1bf)7VE{+6+xHeX2`+l1!iKQXi7B^tKk(ryA8K$@F0dRuf}2 zst?K7RjW~b^c*Ztt5<#WA1rLOt4~tuQ|;r<`kL$=)4XSJ@+XSJ@+XSJ@6^D+ma)w(09bw^a|jv(ht zh_TjsL=ry2`}b+W^Rb^tBfsTr?rOreU+V~x zx2sksk05yq4=c~OQPMtww7EOdHYVAxB=aN4oL?bxekGY7k<5=Eb4$5UIjAJ6nMYJJ zk05RP)vfxK)z2eH+tS+^oFnuZEPs>v5u|M?t*#zH+IDqNF~1Q_!bc?ABfjMLUl6w1 zdqlPOh-&W3MWl5oFk67H9T`z7IiY83aCg!_>&_eH|?+eZ{{67HvtSsIgYKQ+z5 zCgFbSo254i_wyb(2u;HMl5juu-@+#0e%>H<^+VAl+|L`tVlLP@A4&KG61xnah}K&^ zq2BBX^=40~H+w?8*%QcttH{A!j{=QujKkd!5w1PU>DKb+41U*Gb*$r0#W6_d2P2oz%Tf>Ru;xub=2% zKheG3Q1}gnPhmOFI;Xhr9%$qJQ|eKlQjhu+R*|b%MWgkoPjPpn^{7v&M|}zlX;-aB zeG2PmVH@wCR?h4jCH}N>KCPTjE9cY7`LuFAt(;FQ=hMphv~oVJoKGv~)5`g@az3M+ z&nV|J%K40PKBJt^DCaZE`HXTtqnytu=QGOrjB-AsoX;rdGs<~Dr$`2Liex~iNCwp7 z8lVLoa|V#xMrfx<2H3-3v{NJlw4-;Rji(0C+MCc$kqn^M>Cn!E4$zvOfp&^yfOXzO z&`yyIIChF;z_C*#13D!-pi?9RIz=+z*eQ|$Msr)Bogx{a7iVERMKZwZu;pW?NCvQl z^Prs=8qg_{0mn{}3^;a*WWcdgBm<6}A{lV(6v+T@94lK?`PeCv0a~|}$9jVU>IV+! z6v+T%A5zll$p?AzygEfPfK)9Uv8U51k^!9}8Q`5|>FpHBfKHJN@b)B6EQ8TbkqlrN zjCP7-0Lx%G+bNO(G-7$$DUt!~1Led%80{3v0QSLXW8?vyA{n60BL|%#8PF+`0i7Zl zz+zZ#_C6ZGCfmJi96f-=u&|A$2e23x-mM($6v;bi>KI(d)pyX;S!nyH-_a`kJM`jS zCT#nt-_btmceIcC9qprjhcfe9O2x0VkNO?%Yhl|*{SNms+CFMKIoAbkm)BYHe*@Zz z|5>d#pVht2YQ_JoR{YP>-yYag_gi+9<1Vlj5M^j)1ec$a5?n6T~C zdY7GA7H?-u-&Koymlj8u7H2do@vd6jyJ~Uos>Quai?gd{CElgQS=i2&Mk(h?XuF1@ zl#_W_THIUEb`3@8haZEsYbdH+Ls9kRqLN;eo_QPbwreO#-_mINL!!);orSh*DC*d* zp{QfKhNAQ~Eyi{YMd@=|*mey?9osb&b!^vARJ(?v+BFo_uAwL`^ey6T*HDy|Bctsa ziaOULtEhGjMIGBU6lE6O^0Zw;QO9=2T6lE6OXuF1@+BFo_uAwNa2^Md=hN7${ z7;V>3)UjPdQOEX^MEMG>(RK|*(a|huyN05U?HYe{ZMsB621qU;(qO3SneEA#y-vyC01jLu9-wreQLiVr2x zI3mh;YCGcun~xgQ>d&A?uY>$2F)i*PvE^ z=oKl(R(}Smx5isUTm2c->dzo`)xx&=Ge})E+Un0Bwa)Hqt3QKSt#oLsKZ9ER8Pu3= zP-D75jp+t8rW@3lZct;oLA1|r(Y4W5e+ISsGpMoNpjLkdwfZxt)t^C){suMr8`S7; z5c%70RdTKV3?i}LIzu{7H>C4)L$WPHSQU%6^K?TRg$-d3e@NKQ(+wfFL(tCC4Iww9 zou?Z@Vn#bpHzfNoB>OOgO|W0tdAcENg3->?4Pg_EcAjns+1hXIJlznoHQIT)A#8%t zb`cLDTchnI9zwQ8+fh8kOyIAfou?ae>^$9&TKAAz_Yg9-GBbWRSwZA$yu#(h*oJ~J5M)+UW|60ZV0^?txXNlrYwylgI+A& z&eIK{7vn0sBigaBou?Z@M;5m8bVF#$!gii+2z^;t($GkDNcDe+`fvGL{U4(KTiDLi z4QYfsq!I3rM!4^3P2@f7{BNE2SQGgbv^{L^p$nt!VS5i<7;O*Rd+5SwXVu?h^~8Q< zd)VGX0>tp_M%zL0p7zYVr}dN%cw@fld_ceMEVQ%sAMkcI4jOsWag{fn(MIJT@cy-U zJ8Snx4Vhpz3^I;VccIrS@8k>=_-^()TlU4KsfigW5$oKwHzoca~#)UPjp<2adeWGlG^Qtw z=}BXH(wLq!rYDW*Nn?7_n4UDICynVzV|voKo;0o}jq6F{deXR_G_EI&>q+B!(zu>9 zZcj@8oAVTqJ>(GYG_X2;7S@W4PYI)I$S4&~Q<#wmVZ75oR<|J|5y(gc;++Ok4}z4h<6%@cN&Oy8px;tvQ`f9P6IzsJ{QE8(If^L7el<$Kt{)qkpg7A z3H1~N=lAoT|_zJ`nu;OE6{BKyRMxkF_1O_<&|WYr$x zod#0(AmedJ{~R(ZhxF1RtL>1!I%Lfq;+=-^k7>a#E%>DczqH_&7X0YDczqH_& z7W~v(D}!mlFD>|`1;4c5mlpief?rzjOACH!!7nZNr3JsV;HREjKBfh~wBVN({L+G7 zTJTE?erdt)nil-7X~8co_!+73?9zf?TJTE?erdrkE%>DczqH_&7W~qJUs~`>3w~)K z*+w*OvW;jUBO1uu0%Sx38PPySG>{PuWJCiQ(LhEtkP!{!3^im#0~ygkMl_HS4de{9 zn`|Q*=ocB$5N6&3GVcM|=Kwo(l@Sf$`xItGo5ADs#HZoUSsbtIX*tbGpi$t}>^q%;_p~y2_lcGN-G|=_+%&%ABq;XQ<2>Ds!gI z)wr29R|E0*0a+b`%+)~VY9MnpkhvPjTn%Kd23p(9w7D9{Tn#h}$(~ATZzgTi@?@?C zGFJnctAWhbK;~+o*-Z9*C>%+)~VY9MnpkhvPjTn%Kd1~OLznX7@P^eg6S z2s2j$nX7@!)j;NIpjq8a+Pme$Tn%Kd1~OLzS+jF9kvwUTypg#Y$XpFH3!F*qwXj*> zOq;8Loal#UfiuqcGFJnctAWhbK;~+o+2Kr^tAWhbK;~*7 zb2X5;8i>aac#oAI3qbj8t_I@q12R_wnX7@!)j;NIAaga4xf;k^4P>qcGFRgUr2T-j zACUF~(tbeN4@mm~X+I$C2c-Rgv>%Z61JZs#+7C$k0ck%V?FXd&fV3Zw_5;#>K-v#T z`vGY`K)>QB%Z61JZs#+7C$k0cqcH9Lq=A4@mm~X+I$C2c-Rgv>%Z61JZs#+7C$k0ck%V z?FXd&fV3Zw_5;#>K-v#T`vGY`AngaF{eZL|koE)8en8p}Nc#b4KOpS~r2T-jACUF~ z(tbeN4@mm~X+I$C2c-R=v>%lAgVKIb+7C+mL22Kv>%lAgVKIb+7C+mL1{lI?FXg(ptK*9_Jh)XP}&bl`$1_x zDD4NO{h+iTl=g$teo)#EO8Y@+KPc@7rTw6^AC&fk(tc3d53214rTw6^AC&fk(tc3d z4@&z%X+J3K2c`X>v>%lAgVKIb+7C+mL1{lI?FXg(ptK*9_Jh)XP}&bl`$1_xDD4NO z{h+iTl=g$teo)#EO8Y@+KPc@7rTw6^AC&fk(tc3d&(m8VPj7(&g$ooeq=&G_Eu@EF zw0>qGBmLh(>n9Y_PxuAI3lOy4LLt2cOVcaj1&HuIh4+irPbj3HuoU722%b>By#=H777Eo{C{%Bu(6!z|A-x5=iWeYgeTG70V!vg@1hQfR@dD%)@kE;; zCsyD*;)@vP{sJ=2g^Y6{<6Ou%7c$O;jB}y&lZzb2xsVepkP|DA6DyDtE0A56kP|Cz zk&S;L<6p@57v3*&hRZFs^B~aP6vebGBfeiCzF#1|Um(6;AiiH9zF#1|Um(6;AiiH9 zzF#1|U*JaNjPDo1_DO?-z*g7l`i{i0>DO?-z*g z7l`i{i0>DO?-z*g7l`i{i0>DO?-z*g7l`i{i0>DO?-#e284@GDUm(6;V1|{4mPI}; zzF#1|UmzzhAiiH9zF#1|Um(6;AiiH9zF#1|Um(6;AiiH9zF#1|Um*L1A--QAzF#1| zUm(6;AiiH9zF#1|Um(6;AiiJR66*Ywkh46HvpkTqJkWGkf=13l8(Wp25hG`L;9`Y2 z%R`v6Jdm?0kh3a~vpkTqJaC=z;Vchf&ho$w3Uii+FlTw7jmt{Vpz#)wvpj_HfCp_{ zP=W@HHaaLlgGSEsz?T%}EDvGM@<7h=K+f_&&ho&1k+VF6Im-i?#e^T~x18l6%n208 zSsu3p4H{EK&hik>5IM_3n6o_4PCl2|Ssut)9yn2yl+dH4TrP5!hp^;>?kvn%9>`f9 zC<&k`i{UH}xjc_3$bAZK~p5+7%I+>rDYQdEZ7rm>7E)UasjY?7)EZ7rm> z7E)UasjY?7)p+Fl!9P^@_2!7PfP9&}v#(Z7r;} z7FJseqd|+ewiZ@f3#+Y#)z-plYhksuu-cmKPTfOFYinV(wXoV+SZyt=wib4*t%cRr zY@NZ%U~MgI=jNcbwXoV+SZyt=w#Jy!;?>r|=+45{*1~FQVYRie+FDp`EsP#5jkUF~ z+FBSrT3GT?TMMhLh1J%=YHMM&wXoV+SZyt=wiZ@f3!^W~!P;6_Z7r;}7FJsetF4vN z(>vyt($jkr+B{e(J-yQqe_4=qUdTEx#9x+MN zWkLL9LHuPw{AEGB7(x7HLHuPw{AEG>WkI|cLHuPwycj|JWkLL9LHuPw8}pVU4J!%$ zvLODl;HA7-%IPUtO8jL({AEG>WkLL9LHuPw{AEG>WkLL9LHuPw{AEG>WkEb3LHuPw z{AEG>WkI}-K>TGv{AEG>WkLL9LHuPw{AEG>WkLL9LA)eE{AEG>WkJ(>IWs>t`+&bJ zh`%g|zbuHqEQr4>h`%g|zbuHqEQr4>h`%g|zbtq}#9tO+R!$-QvLODlApWu-{<0wc zvLODlApWu-{<0wcvf#fe_4=y4iJA?5Pw+^e_2p9!Pb%p<1Y*1FAL%?3$iO4 z;x7xbHyh$F3*s*e;x7xbixT253*s*e;x7y0FAL%?3*s*e;xEfBXC3xx>>4LloHT@-G=!Wq zgnKDZ1+~<|uPe+6T*79PD`b-^WRojolPjnjT%~RpIe`n!>Q#V=E#V=E#V=E#V=E#V=E@ z*y|A{2eWCOY??@WYav^G*33olTGtv(>&QUPd3eyP4i^aJlQl)HqDbw z^JLRJ*)&f!&67>@WYav^G*33o&QUPd3eyP4i^aJlQl)HqDbw^JLRJ z*)&f!&67>@WYav^G*33olTGtv(>&QUPd3eyP4i^aJlQl)HqDbw^JLRJ*)&f!&67>@ zWYav^G*33olTGtv(>&QUPd3eyP4i^aJlQl)HqDbw^JLRJ*)&f!&67>@WYav^G*33o zlTGtv(>&QUPc|(gn--Bxi^!%$WYZ$DX%X49h-_L!HZ3BX7LiSh$fiYP(;~8I5!tke zY+6J%Eh3v1kxh%prbT4aBC=@_*|Z3?=zaQ&X44|FX%X49h-_L!HZ3BX7LiSh$fiYP z(;~8I5!tkeY+6J%Eh3v1kxh%prbT4aDzRNZcPnXM4?}z&LVO;&mDEq-shLK69zuK` zLVO;&Rm{>HgZLtFtCd5wa;R1g)ykn-IaDi$YUNO^9IBN=jdG|_4)$$@F6QH`*Eb#; z^#){5AT(<~Uj5SXwkMD_JmpUhrb&WdS z6g#2ye(Ut6sMDLGPS&i>d7d@gIxN`JaBuvl(0XNc*r*Bchx|9lGr4+h_8!pil@b&iT?m6QRg>9o7f^RD36wlkNe45dVrTho+pJ0nh+oIC8sI)CAZHr3VqSCgg zv@MjD^py68Zi`CW&i+s^)r zufxC@Z^ zNyuI)XwqIlAJxL_m4fV*g6x%o?3IG-m4fV*g6x%o?3IG-m4fV*g6x%o?3IG-m4fV* zau-N?3y_9|*((LvD+Spr1=%YF*((LvD+Nt53nZBZdb)+wiuvwB>ccaTy;6|9Qtm=D zLJYbvvR4YSR|>LM3fc~$C0f~ELJso?w>pW?R`!=Twi{uIR`!=@Wq%3J8zjbdBP`L% z{t~V1FVV{W60Phn(aQc3-V5Zzd%ornaaFeWnQi_ zuTYs+sLU%=<`pXQ3YB?<%Dh5lUZFCtP?=Y#%qvvp6)N)zm3f8Ayh3GOp)#*fnOCUH zD^%tcD)S1Jd4+pT=Ml~1?w=~h17*pstvxAN&$KHbWvTlsX; z63@Ekm#on>zhsSWkMikJK0V5(NBQ(9pC0AYqkMXl51z8fp-1_wQ9f&wPcLt}XOIit zjUeASf}A5TNs+#nai7KTog-+gX}wxa>(y#nFJnE6vDLI*#(GA+a|CTot(RVk<;i!B zAm2HH$FZxuyh$yd?;JtCbL95Y_cPl1S}#373nwYeca8|#x(ps*tW@*~E#`j3@SP*V zUm(0uZ;*}rjks6wzNmqG^9b_IBgmOP$TyE5XD1=wJc4}l2=dJ%Xm`0vz4xo=y<6DU zeXgSSZnU+Gt9XN)hJ5n~{$KXq2fnK6%=_K@B!uh}JcoZGAf*(M0#yX$b*xoKEk#Nx zQc9_{jzt6#H9|<}K`BKBL68X{IatR_8DFK8DpH9+F(8eOT8iZV|Kyw`1O(BDRD2al zq;S8_@0>``PH$)Kow=WT-+@nl`#Ec`z1G^#^IOkad+oK?V$UOxJ&!>4JObJC2(OnVbFn`a6`zHkJkLp-_3 z(j@-eWP3L>n|f;Lu)`NPL&%;-$b4rCN}qUmlci7EJ}U!z9)aw61hVH5XrtM)Y1b^A zJ&!>4JObJC$ejZ#rh=^c2(s!UXz%{!=zYW-tY3$0t?(SIZ!)Vsf~=zmTAAly{SQDZ z&m8P);jE?zvg#wqs*fP6K7y?J2(s!U$f}PZt3HCPkpi;nBgm?cAgexttorEAkrn31 z3Ujc6g|O-)$f}PZt3HCP`Ut9oXxqYB^$}#%M^L3j!zQ!pBgm?cpvsBf>{?cRbW^2` zRB0ns+DMf)Ql*VlX(LtINR>8HrHxc+BURc+l{QkPjZ|qPRoY0EHd3XHRB0ns+DMf) zQl*VlX(LtINR>8HrHxc+BURc+l{QkPjZ|qPRoY0EHd3XHRB0ns+DMf)Ql*VlX(LtI zNR>8HrHxc+BURc+l{QkPjWo@WNz)9OG|iAn!*3M2Y4{C8n;n;i-`E4%?6@?1?^@7i z$ED$c{|U6&acT579tN$qnTCFjg7&5$4PRmD*zCA8e1*w2J1)(!*>P#=f2PrQvJjge zl}3FxwApcK^hhmzn;n-%kJQq)*>P!_A(JLQkS0Hnh99u2Y<^T4e!$RX$E9h8OqyoM zq^Sp+MvutSvDtBH_y;SG&5ldMCxDtElcpImX?OtAp*7)t)tgPDO)=SevuTOq(5-M*r4in;n-%|JG!i9hXLb z&r-12ap`IS)71i|s|8F~3z)7JFkLNRx>~?=wSehr0n^n2rmF=^R|}Y~7BF2cV7gks zbhUu#Y5~*L0;a14Ojiq-t`;y|EnvD@z;v~M>1qMf)dHq75)yUO)dHrg1x!~9n64Hu zov{%+Yc1ddY5^Zm3pkfM+T_mVjtuRIV=i}e3beUBa~VmFf;P8juIBd4k(B?{IY5qo*=5J(SM~h=UMH?lN;BTMr)vee_v()^7q&ELq<{EaNl-^lXWT&V^0LkdBgzp;RR$WhSd zZ!Dk}Vc|A^V*y^s(B^L}pp_?__TA9tZ!FL_(gIprJG;hGpglFr6WaWZ5NvrEv=MCf z{$Z9vNF&%GyyYBZo4*mFrW@M)jSw~6WShSc(inS4?>a+z*BR2g&XC@9hVWEhC63MC z2*Ec)d#fJOyUq}NGuh^Egy5T@z3U9=U1tc^nQZenLXOSf2 z8zFdWX!AEhde<4^8E_u5&EE*YXFF^2H$w2)(B^N1;IpC4-w5elXGrflLweU4(%XR$ z{SEsj#O7~=@XuBTo4*m#yUq}G!S2rHZ-i)l3~l~K2+w9{^EX0z*BR2g&Je6HJ=nX> zkluBMV8|uNHh&{TJ7p=@{EZNv&{DAZ8zDTQq0Qe2>0M_??>a*;%2KoW8zJhHWq zp(a|m&EE*=U1vz|IzxIp6Vlt6kZbcdLVDL3(!0)(-gSm(Ni8p%zY)UsT54h%b=K0f z`5PhXtf9@{2vKuQw)q<&>aWQ*e1E*1OJyv;}MNLDn`cl>c8S z|G$v>_yHj{e`6uF&(P*YEY!PBSdN!iNR6-%n;o%`8ewSjH`qf$X!AD~!hA!Uzp)VJ z8`>Mag|O6Qo4>IT7MW}#7z^c-7s@9uluup=H#iG73~m0#LV4YVSkPpfzp)St8mgRF z&19Ruu@GArs)T6i1NT9ER~=~YIv=DKYzFOJ=Y#N*aF}Um?>Zku=Z5yK^C5a!g`mCb zT%;5hDTPH!VUbc;q!bn@g+)qXky2Qs6n>@@ex?)_D}}{MVX;zJtP~b2g~du?u~Jy9 z6c#ImpDTr*D}^OWVTn>$q7;@Wg(XU1iBedi6qYE3B}(C8rSPy)Sc-4|C)j4+5-ugR zU7)>tU5aPk39{=J$gW%91mQ#>`$G}J{!k#hZh`E&1+wcFc%SfoA-ir7!me8&yKaH( z8wF+v**yxGUAI7X-2!d?+fw}JEbt+PEE2No79s4q1^!&fu3O0Lx&>~8|4Z?WcGh^c z6yIof#I9T53qp3?LbkUROU1XPXw2f+myb*FeioBmw?KB?0{<*z*DZG`JTzq2Es$Ne zKz7{%*>wv{)>(GlLT1-3u%FQ08ZVV!T8b4cKIgKn3IK5gwiU!weaaecHKf| z*Da7;w?JtRCR-fyAxp8WrOd8dAiHjX?79W6CeA-%-_4+n0RJP_KvvNKSuX`-6&;XObU;?o0oi*CWc^8yy|+MC(E(XS2V@l; zkX3X*R?z|3dkbV09gx*jKvvNKSxp6G6&;XObU;?o0oi*CWbZAIRdhgB(E(XS2V@l; zkX3X*)>i>pMF(UR9gtOYKvvNKSw#nA6&=v((K4)QI%E|ckX3X*R?z`jMF)IQDO+D+ z8MaOaSw#nA6&;XObii`OWECA`R?z|9k|x=E3z=1PKvvNK+ZE0#I>@Y|1G0(^$SOJ@ ztLV7P;EW;bb%2ScE9#)htfB+5iVnysIv}g)fUKeevWgDKDmoym=zy%E1G0(^IMDL7 zRdhhBt;gUsGrAS-@=kge`7qyJ#xtfB+5 ziVi3%;}fjRkE+b9B7)2+Iv}g)fUKh9F7w@BsnPoXjOPtj(E-^*0kn5Uk5GgD5o8q| zkTpv|^Ba%IZ#-hF=peIlDaa~1pm~o+9QIHES%n5PAM%KN$RqM0kI08S0#_}ZRdm3g z30Xx4nN@T^R?z`jMF(UR9gtOYK=x1oSs4{%WmJ%rQQb%6Ngk0Wc|@M%5qXkFu(h3K z6&;X06hQNMkI1V$BCqm@yvifk%feNDY-F;^kLFEg4+W4_bll|*J8*&aG_;)l(t6O^ z&E)D{J8{>BQ; z-&mpf8!I$_V}<5#tl){}UpZ^@H&!@Dm5$BdSi!T2U2F3Q#&h30Rp(1`a6jd-u%dBM(pPxyVI&EHtT2n_c~oi*7;GgdI_VyW3! z_X^G5SixAg$@cDVh30RpaBcp^3O#qPV0?zs(zmCy)J=-Ss_zK3i zO}3}<6^!B7RW^TPrQWu$MBC$#ZC1ldy=`a2oLLPk^|pPb-nOrVQTDB=&1zVwx9uzS zwtc1Ewy)IN_LX|uzEW@7SKf&*!V|8ACx$kwVI}uYj(8!9W3w7oqGM7fZ9`jQ zVWr--uhiT2RrEQZbXU>meA0c48ng+t5$wlkqmP0%g8djgu@D=m9G1^dz zV+u8+a|NuZ5jKc*4a$28*lm_}S5(}?S1v>n8!)iAUX?8h|X z`j|#sA9F|0>OF?Hx3e~a{TSA?I5vX)7#`KaZ3O!uQa-uGWa_YT7$u($X2) zyX@5(ab2wu*KG9pPiWkHQ8xPA1zLY5TYdO!ymuM0_2IMChtI}un{2(!Z2Y#N_2IMC zhtF0YK3jeGY)Zb9aO=Zos}G+|&%|Wwg=XX74XrPljfXe1K76+N@Y(9aXR8mNjkmXO z>%(WO51);ceN#F4$GphtHPB%f{|@*Vc#6 zRv$iFefVtk;j`6;&!(jyJ}rfz_2IM8CwHMfd^TD&+4}I=v>=AohtH-3F|=Mmwt5BG z>ceNN51*|*d^W9##j!qoHm!-Fw5mRQw)*hd)SX#`TOU4~x??Eq(Y{!GYsa(IhtF0Y zK3jeGZ1v%@X?M!-zt)FegMHV7)`wrCws?)&;x+2S^Rj>QNYLnhtG@B}@%6v@w>j##q8w*;2MKmN2$X25pQbOg*xgHpUXx7)zKp zHFlMav4l0o61J6!k!_463^yzt8)FIEO2wd!v4mlZh1(cQ7|tNW8ABUm2~!8r6?M>L z8)FH>B|B?lEMd50Xk#p4jj@C^#uA2I7H(rKVU4kbHO3Ow7)w~Sl^x%V2^wPwYmCKq ze6w6^j3vy|7UhATmX3|FgyE;5jj@DX8)FH>Qj=|rB@97;c+vV=Q6U##q9NHpUXx7|S}1v8>Y=%Q|Y%dY+Jvcrv;Hw68Xv;mHWu zy%McH!*@?*pnc!;3|}x=2)plr1w4a4!`C{qK=$1O3nl-7FKC`&uf1bn71wTbp5xv( zy3g{&y3viv`3fm;u6BQ|Z;O7duZn)HFMxinFMxinZ-0L6+LuI|okU@ebMui0V)4z? zZVP`-AzKY8Z523Dc$LL*NAY#cW_R?t4d57sTupg4^M#I`eeT>0FkiS+R~7KJ&St*c zv9qu0s@LJqW_KT>ADj6O%W`?s@^ueLE*9E%SeyB}$F3?@NQLA|U0cOd_GZ4rvUF+` zUMIO;a)acE$$Z6A=058dIrpI>8}oUNF`x0^K%rUcIcF2L({72N*-N`6f@UwWpO>wlr(E6K=UuZkdkA9d=iNPUU@N_v;h=q8xRsbUfTsDa zDY?Cdl1w21lOD1Fs^lZP?dvjPPnSxed!&$g}KNzl|J72MyR& zFFAh??y>YKa}<0Wu3u}aR!Ukak z%$FVWRm<3Mj+&J(tFaH5WV2entd=jU<;!aMvRb~ZmM^R2%WC6GSG~)(9W6QA0Pc{UcaY}g$aY7zW8g;6zQx;#eJ6tUb>2?Z$DR5*Z>MVI zPJNxXQ+D5}y17%|`t4K=-KiS7%T_*jciGD4;B)702U$NHWVLXR)xzCfSZzBvO31E2 z$YX_86L+a5?jq&akzY}`efPJEnq@J|S!raKTcMB|VLjn5!M7XSm(bxcaHQ~RMjl>* zdlsHA+`(PHgjOxi9!Aw(k_KKvOHr6--;EZ~Moa>~B-vI?DbUQ20`BDjWczNkK;MlP z;MFareK%U5??wygIoMhIZnOYR_6F^{(E>`f2^=Z3??wx_cPxrWGTFWxEs(_v(1XeL z-Dm;&p9AI#cj{WJ9R>Pgv;h5_MlNLBuK+FCRrcLzfotE57U;Xt0=Qwaea~1R-&LS* zNDE-Kh1)lz1+INVTHu=RDnP@Qf_+0;fQC)BZ%7N!&%>a7Lt3D3NDEy1hP1%7Z%7MV z`-ZdtcA0G7kQV40(%tBD3T3rk>u&k#-T3N$$mXkeqsbD``eVDLx7}zg3Hc9(Xsik} zAHEy5Oaje^@0JhWEg!xcjg=8%K72PCyAw42>=u7^V`aP6G`3rwe78LLZZxx=5cB7| zrIX$A=eyB~g_u9zjZO?rC%fg(cgvseMkkh+`Sac4%x?Mf-SX$V(TU|{UVS$@v6$x7 zccT+zdG$T=7X%D43=DsW|yo_#<(XFBR&zI#nUq+J; zAlui!DWsJsfXHQ};sp)6Y{ z%NEMAg|cj+EL$kc7Rs`PvT31gS}2~X`yUdC~FqVnuW4vAsV10vSy*IStx53 z%9@3;W}&QEC~FqVnuW4vp{!XbI~K~0g|cIz>{uu}zQWy|a9^SPhV~`$E0o;OzC?b7 zTnz0S!LF!Vu4~J6 zZMm*3*R|!kwp`bi>)LXzJ?56{+Hzf6K{;P{D=4So7~xpqD?;m8RZva1+&qW;j0Qa zHdZN}DwU@S%~KEMwW{=8d=>h%_{PI3m9|PetU|-DyVbh3MkTLN$!k>d8kM|8C9hG* zYgF#BNPRj;e+ zbydBts+V;d6u&|78x+4m@f#GsLGc?Dzd^Y)D3^$?is-6{u8QcYh^~t0s)(+ND1MYZ z2gkcn_ZU6xD0>c?{Jzs0{7~{4T7gElk!Q3_=nKEg%}48ajnT`8G$(@>mQQ!50PV;dsrzP zRtkre!eOOwSScJ<3Wt@#VWn_bDI8V`hn2!xO5rV-d4u~FDclaeC;3C6<^C4ePIlko z+85j-YJ-mGIq?Wz@Qo+Lo)eEyhD{)Q9)j-)-*;vre<+!KPLWRw+2IuV48HLQDZlO> z@g>vd9`U7Ee3)bMMdW_O*Ha-EE5znD96@^vKh7s&obZUUGm-N+Wv!&faW1>AH6)#Jf!WWM~GO_O1{K|8&848jaFFmCD1%% zt2|_@JY*|nDY9garJST7&a}!yw#q}c%0srwL$>Z1tIkY?X&>m4|HgnTKrk znTKpeR~FMeWUJ3SWUJ3SWUD-6t2|_@JY*}3va{wPTYcssTje2J+#kbHI;v_O$R*q4|yXVFGQfFUjJ=sGou6G2Vw!Cikbm`o53#lEHy^u=gngxx+C# zJDRh!z2^>r&7^Yz&Y1kMRyx&RgV!V5jbT)zJ z{Z7jJouvFTk z`M{I%fhXkyPjYvbg89IcSk2IU;7R$wlicY>_hXoE*h9EgXyZ;FQ)`}ZKUS^z*geRd zehl+ZfmVY)c8{XBk752%@I8gUkN!V~{}#vU*T?ivEY2CbR<-OCjYoZ=@u*KU67`8j zqCU|`)F)`^l=}&}JPca;pOF3x@I8gRPi^|dJ)!Uq74os-+lc)q%Ig!fXYv`I)IOnR z?FCctDxaXS?O;#I7fWXMYCJ>-jptKCW~qQSX4R%Kt2TU##j!D~HjP=eY3!v< zV^(b%vueW%z1=qXpEgRe5&01BDcagw`2DxXj*NTCfn8Sx2xT6SG(V?cE24R<`Ku*{dTqc?P$+rYxmpHp2^nk zx1&9aY3+VH+B39vza5PkTD#wl#tg09Z%0>#*6z2XB|~fX+tJS!(AxcWwfpVp$7E~w z+tJShptbw$=*Qw)yWg&Mzg_MAr}6`z$`5>sW;VK?!oZ23`GHU62R@Y__*8!2Q~7~U zRZl-fW3Lm({J^KK`GHTVr)8jdgHPoRK2;68ykjK<>5 zs4Y07QMfbmrDyP^Q{6Mz>oU+h^BFwqOz@(O7 z8J$dZ|16LFXVM>zZ0o}PnKW+zt(W^}(lNBwGP0{d|y;gY@%3`uQL|ZIFJx&qaHLSU(4( zpYKah3JFRfK`A6Cg#@LLpcE36LV{9APzni3Awel5n)Q8&W_=LrgIFKL`o2W7K1eG7 z(h7jI0w7)*q!j?MK8VFZ{6C2Q2l4;DM67rb^D3>nErHgXuqFlNtmoCbsi*o5|ZMrWRUKw6=?huHV2JzB95BUUWaXdm!`23XW zb+E^|7r?ECFq05c*adduDnEYD6 zAR#GOytl6#BMDD}%m=0wr{@E9KbHlvdJo8`9mrTTxYZEO3<<&!Z^-x|tlvfYs)kAspAg|uO9?Gi+dEJ2AlN5Sz z@1%ftGPJyUNQXU?R}baYgS#80F|8E>Sv{D4k1`&Lv8xpX}RD_U$M8 z_9K4O*H4!1hhv z3Eu!&d;ldexv%h2p>cQsWw7uOLbLdn#O*=CuaLq=zOQhtVP9dtb6b%6Qy0F%y;%6b zb1T5FDEzAm86g}^oXeELWlG^PrEnRg-9osfaG6rLOetKZ6fUDY9}#XTTtHFo!IKW^L&>poy(QZO}I+rV*%azXMO2^jtebV<;(s|N1Olb~Nn!}XlFr_(6X%17G!$|XlZy4zu z0|!X9dOeKPj`@a*&%?#%;o|df;=k@2P8oKA=C6j!Ur`q&8>`_mmKrWT4;Pn)i_gQw z=i%b>aQM8-H^Mza-MoU5P6e+5uarfultr$TMXr=Zu9QWtltr$TMXr=Zu9QWtltr$T zMMf%xkxF5tQW&WeMkFEz`LR** zW25B9M#*Q6BHudSDENE>XdY}7xf_}X8%2)CK=YQP$jk6bVvbf_9<91OT6KA}>hfsS z<O}4r`ntV;Rx;)zYKfbH2 zFACDn2V0yg!9$W6Z9rzU0c5lRWIPsRJQifM0c5lRq<0E3+5pn?_g!s0Rgm#mknvcM z@mP@YSdh^MknvcM@mP@229VJPkkJN^(FTyw29VJPkkJN^(FTz5Sdh^MkkJN^(FTz5 zSdj5pkkJN^(FTyw29VJPkkJN^(FTz5Sdj5pknvcM(FTyw29VJPkbXW$KObbY0isvS@bwnRIwTsa*8vJZ}4K_7hN=z_cSp%@L9NDWscoTij^~PR&ly@3J;hZ3@E%i zav<1Waxdhb!Pq_a?iBxG)%_=}0sA#_%F%wsW5|*Ljz}^XIATLoeAUKUP!6jJVb2AGeN(Ar2=6B3 zUZlCsNY30$-sv2t5|-+uaV|^0Shth1WHKL~RX!E-`$(*N2(mK}Gcc#>_fNUnO7;1( zmZHV)I6s|VtV0#gc@QNX$=}tTuCp{dr*f}KayPjx;L5ux#cb&+)4888yE8kJM(AI@ zXI5k+)=!;`&tl)h?+5s8y1bX`vM7Vy@dCoGbFSk5Lj4~}tk3IkBs#ULuOjwC#Gl8# zS*bEe;UPjLjEbanq?p2_)|iylvdi3r&T2XnCz`$&;n7Ui^(n}%ZCH?4p1?qj)s(N5nWc83n^PGa|B_ilW$nre06 z-uS)FB4nZNd>-L3t$y)NW12R8pVz9fz_=a57`tQgPbql@b~4SItyq5E?NKSu6>F~`#hKiNG1%_JEZVu=eVeq{&+CF~ z206n>zjM7Zj*L_u_Y>3DZuYsGFuT`O)x3MD*Y_fQ7e6q~`3Y?AT#n(6mBi|su`*VB zJJ=f2(;(+Ir979bt%jOzCUM0>@iQ}IA5EmQXaFC)yfITR{Q4hXCAGCUlR#Q zla?o_UYZw=`RWeqO`&WtZ^6278S~^P_WYu2Inr>nq)I5Z7 zHP}*QDOLizVkYPB*1dMH#rSLYkfHb&dgcEFdwixPW2BXf)wv1l@R?Tg z?m=r0a5r|>=i557xYbYd1;)=fXZ~&b66^bGFpTfK<2A)W8Lqjs2oI^V*_?jhDPS^6C| zH2DF_WA&3&oy7^$=6Qyg7mC%GEJ|+iW35HZ!_HJ)i*YIIvzX?o&ij)X)2|{I^KIr? zVttTU89M6rg1~i|OS)V#HePSP44pWPO9r`()FM_5X}59qre3^5mVp`Q6xM zo_cKO?Rnnn?6k;PyFS)#oYzrD+jL$}o&Cy%SJ|Bz>(jXpYsW8SX6&A0^`Rry=dBvE zxpBytZl$m?#cEQlEj@pa9bT$KH-EcLMt0K91bRDB&Uer{DSbvi}F!^;G zPbJ@W#t}M>kgpQM&e-{{%3?oMn>2xVKTvxYOJgeWCiDA8#I>}oH$7RuzC--Uq-ECr zmUFxE_!g;Is<)A!rTtw(CvmhqEuLNRO+tRaZ4Q@Cm>XTMDf zv3{uC!xZGH;BDk%`P$E$b=TxmY~Y&-C~ivyqi=693QN z)y>j@>3(V_{e6?)Qz*Hme=Ap+b}Y^$N?>4u+V9Z;O|{gPk!hcJRz{jpb*y?Oc`)R-f1P7wbqYl@5meK;`&i z3E6Fyw9Rs{a+&U8I_S9a^C^$y{>}f}Gm_Q)dq4Yqh+pT=S&QBI`PW+FSr?qAr;<1@ zadhH$5^qhs0sQ)BXDy|0{(+4y=-;`?w8nqwpG%Bn`pmtY zuIJ7%w&)Ux5f=B9dzR<^?>Ua|n~v)n=VM&M_rt`y8UL7>xXnpO%al8CE$>$^_ zB_z#u+@v{4naEj5>ydw%^h@LoNxwyYA*sRfB}I}Vghabu>-f5Uz3UB5Lf0F+PIKI@ zKj``sJK=sKj`n}B=~##FGlX;|1$C*{~+YA z_%A~q;-8589sl={r}=-3e5d~|Jmlo`l(r`(M^GldjV?n#-2JUazlrOZi5MNUg8K;E6Q8+lJkA@VCJ z&BzB+T96N=96~-E=;yeB{(*r`Lg32*^dFcRNJoAk(2D$C;63EyJ#Tm1o#AN? zfmiqXAK3ERrY*mFB5|s7@!gqs&vcf~oSQnvX}#y6%yj3YS+hf9 z+~m~zGRL@sQ!{7Z@AgdnDe@I*vu9?y*W91>0Be5VKX=v`cU=12^9H%Mr{BF`t~>LA z^asYcs~?y*H`RUofrp6m)V$1x#<<%T+@1bY_t^!r)5o~`7Np&MuUo$0-kA&B$btt5 z*-MMl<>sk34{`>7chZm8Df_#(O{KN_{^W6tQT<>lc$ec)v#pl*bOyv_kNW^{gJAApxH81K z+!;!bcNovPBb=|%-?);xbCpJx$1qkqmJ!=)SgYb%Qt)6{0(|O9t?}SrH_GB5e?HVa z<|VNI-*dc(w++TYJ9b=a@)T#Iv)8F*#rjijlH11}>R#iHcc;5r_t|}dueI&_r&{-I z_mnTmH^O(FZ=&xG-+jJCzSX|>dhx>)m!p$%SM2!JafF+0K09;OQ?WBw9pQ{wIhj9d=cvao z{Qa$-7yceUMk&SOlf$j6Ep!o7=Ft(|OA9G&k0ay9o8m|Mc$VJgIq~Cy z_;Gps_;~!dIev`izqvU6n?9MYe_MCWzV1BZ+`)Lkee~NGIm?{YPS{zGFWBO2clJ21 zIR~6dC*mA-TAdG_b|%32-JWiLcd$Fc9mDRbx40ACjuO!$x0HWlmbN3kJROI|k7MJ< zaq;8y_>tbJ;>GRpo2BvJIq_p$qrb_I|1OLlOXJ6u`0+&ics6!?wtM_ID1IChKaP(d z>Hk~4&&K)iEPZ$VUKKxXh#$AdkFUj#)$!vy@#E>(@j3blcKvhIVkDF0b)GxZ={M)M zjnwaMV&=%dz&fR}ZAL7$ZTH2G@zQOJ+j(1DJKK2Pv0S%38$ZTNyDhGzZE?GAtBs#O ztlTfCPx%vK=kntk$&dMg6xy&Mv{Pf*Gh-Z2pVL?~b{0>4$}c~jPkua~{CGb3jq&qw z?c|?|{eCeie(V`P#;x+=sQB;eRj$v~*%#w?_2RC0tbOrgy<&gES?nx#vYp4B4bCR! zp6sLrdxQ7q)lMV(uN-$ia?ZGkZa25LJHQ>{vKzH~y*tjG#BP^&y0h5hYJt0$Rb{i? z$K4I?Cf3{7>F(ug<6^$4Y~%~5GB??)Tdl z{yq@1_-ExWdg8+K#dACTM%yLU$L+}9es|8F-=#NoI?w%;elEST7RSAGf}V?}&;!`g z=|BB}y%?h{8-wt zc$T7FuQXgQnI{zdo0rTQO3%9^lZ(&&;M@+!X#l=VY1K@`i0$u7YPHxps>5Jhp?xm@AVS)7GA9IKEg|c zeTDsm{e_nb2ME6;94P#NoG)A|Tqay4d`!4nm@Ql* z%n`0t8FD3uh3kZm3x6SeLio>$`K0id!l#7K2sa6TBiy3+&kMH-Ul48=z9cLV?iTJ5 zzAW4;{JpSH_=@mV;lB!B6TU8dLpkn~ykGdH@PM#bSR$+xRtf8b^}+^WL>Lt|3Y&z@ z!h=H93s3dJdrKilgsLOnG0E=;-xanBj|)!-Ra3kVRc6%@uU+z4omEZoJ0|;8U;IAF z3Bp8S7olp9-!C~us9NI}d;OOyL>%^iRq`;)#Xmywjl$`|+l6-s#W8=T`&vQj8!`o&EDYK8oh;)t1kanhfs z@O26o5B>k5kf(%C3!f4GO1N408{xCU=Y*7iGW=HZHlcXv-zoWb!d*f!Gev$QFvvmz z*9mVB{=M*K;Wvf13cqdX2ficuyOM8{{5{F4*8$b*z)uuDPpH}&kZuDie?T=Qpb`cu z6h|x#98)^)8V36a`wItJoS@1X94vW=!iPzgt%Fxc9;xtAlE+Av2Mb;!`C5hRPJ`D= z7DIwJ>FhX#j2BK2P83cO%6A3RCC?RR2*skH_!HDU2F0A9I1?0Gg5pVVsp2maE*FX? zK`|sKZUnOxo+Ff}3Wg;=t`a^W`BlU2XAOHeLe-rfsx>{56p}3T3%dzbYkCAtcCJcR z+vO>i7qBqzi>*!P7NfJjkNNVLH~rf^Wz2iU{DC}yKUPy?^)FWEVzn(+&tf&KbFKO( z(?Pt(#Oeya;bV-IF+Rqa_;2wj#+n#MV(f_VB4&T-*u5;d+VqiJBdit58zvu?EDxCc zj^y`*?+Z@||0I;}OFk)Cn*Q%zg7+=chNs%)$(wi+6!LAMYMS@OUcx`<>|MecLiuiQ zmSojN?*Ym3GM?&~r#j}XQn);?r`qMIc6n0&Z?$)e>=Ok=&Jwj2ee8L z$Azj9p6WupAMoEj0P)Zt^JL=TfA;_a|MhME|8DL5+T_2b9gDSHomwrgtLkyAf6!fW z58)U43KuK9kML6A0O6N}1BIRY6N42pR5(ni{+M^8~l<3xcZr1tYzrjCd}5^ zRAJ|qA?Ee}YyABy%KcU0zY1RyzApT~{{+{$|0M1Gg{Pj*PdfikJ>zulhdpZd;$JEJ zTRhoj#r%!%Sz)KAmH0DA=ckV^_UHcklf@UGDgL@g`L}w3Uwk4^KO*>V_0`p1bVkPe z(y?0d#hTHX^X(&JA1w13K=2% zno!TH-e32I|FORGol5_|zDNC^J<7I2_q9{_JK-+jOTq%-Zs8u`%fh|F-wO+c|JlB~ zLAgYPQDLL7N!TnrDAe=jf6D0FpOyYu;W@+q9)tVu9{B%jV{rew^}~J6rOEq~-(=$6 zIghzd%!W&Jx_HSRU+{aEczvB@?_1ut9KZJu-d#?Lx72&Yxybvi_gkljx6OOe>FMq8 z3Y?3X3;sjrQvWLdD(B1oo&MiBgHpPs1f9VtJyQBQLj!9AYn_pSb%AxxRe@gw{@EE7 z^aXv+)xp8R%bc;nVZpCC*92zpp%3#&Qh0;?ANyycbN`WlcHO_{+P@a}FP-~bn0dj^|BshI<2fDY>{dGD&d1Nk z?R?7?uj4v}Ti%`W*Lj~aAoDNa{!xHsJK;@nu_t$-WGgl_)nFrlY7 z&|4hnBM$Tr3<(Tz1_$m6+~r&rSP=NBGbGR$cnfa49eCRrDLz~!K8y-}J@|EJOz<1Q zZ@>^^#aOZ88nNP9vEn+h;@drZJv?TH`JCaD^-aEqI6#RL#A8?tj}zfB^Cl=UYcF^y zlsiG?_Nm-mJu7zt<^COv-{tM%-d^G!y6PUf>K?js53I(Oa#6}fPEtw$PIu*gdJ)n) zr8glL!|$%TH=pj!r+f41-h8?@m=4#IbZ=dCZ$90dPxqFndrQ>4C30{7htnmvKKM(g zYj8vGeFZn(2{p9zZJ zLGWd;HyC+{H-zw^-caOW-Y{^uzFryYF}uUN-n*WV8@(IBo4lLAo4s2|(>##tjrYEd zH=5{8M4rUBY?3$Gn@pS^dp`#6^zOup|KR-t@?H2U*PG$ZK)%Pj2b|^2qMWn6*?6*4 zFBMGp9w6Mlj&bp7OS!LQ-ZF5Nx0;Y_FPpP#yfw%jmvr@y@Q*;g(SM_pOwD1Qga3B_?S$OnzXQC- ze-9y<{!HX7f0mQvU*KPW9P)?2g?@H7^FQc+5cwhhL&%H#i;#cj{~7XP|6=5y`+ttS z#J>djVZVL7vedtnkVkm4ndE=ezmo7(eyryICq^;5`q%i^5VDp&R9AnVKM#4Ge;x8K z{J%i{7yna~^J)Jx;II6@0yq1gBm8;)^Q87$KVM_{xB0h$+x^%DFYprI8TCtHb(p}Q zz#zVVxh`-W@(qC-z`qaty^|ccIdC)h&A>OoTLZTe=i9siN(y`@z*kyyg}pwxNf=hac?L18(;S z_6TZL(oma+Pd}r-Gl>8FKRdd~JQv{~c~ZjnCMDM;*AcBDxq-0e)FwGgIhqvzXRYwrEwLXREi%7+e7n_<93kCUir@3TPl`VvEj%#( z+s;{T&EP@uOdz+Z)Z_0H&qq8;M$Xhi?}uDtYeD%{PB*zRxiNmFFLq^eOL9xR%r4(P zaA&&G7rWBC-J=%s&D=-5#*H z`c844M&8WdR>!U0>-b(EKl|IkcM?1J{^P~%99g+(NB>TLgW_>$K|139rQ?qH`5jkq z?HK;9<&Snn>GSO#$5^=wI9j<2iIROgro`hCZX6%=H6M7Rs(U2;z=5hhk<0_-RRbaq9;mGv99eRpv1-`! z$K!aoYGh>jfp@CLMphp`jB&?$%?a~XhzlJ z(Lm9hs>ctkB4jn4%}D8l%@1ZKygNy|HK`SB)!rwrbh)dy8JEdWSm_n%@36xM*k9 ziRX_O?Wy_*4ZK>_jt2HsJCWkzWuNKXyoN(N5Ma9)g(TUiI(iYFGPLD1qdeE*dX{>p&aePr_>>jJTai_YY;zz4j zN3)Bwt8=5_;=;TQCkVtM(YxR)m z^r8={M<5@m9tEC4KQCN>XG~*7ov`@H>L<8&ajf{M>J8B+i#JtoYdN;jq$d4ZuNuFMa4cVRq+Cqa8dP==+fe))yt!g7VoXz6IqUiUyUXgzgE4E z^1#XHQ?mZ1;{Dadkq6P$PP9~7T^!v~TwT30njdFfrRgDV$4FK81CxxO2bLALR98lK z#p0Z=I|ptzmPYp$)mLwP{&?J`Z&%l2ujAFtc1P7mjGxu59d{SwDkc0N@@(;kW?3}z zLG(4VEIK?@eF_`JY<;@=3?(^R1G#v$jIp1C3n?Ki6)oKLK~|~?yH#|X)ejAxifmaBvdmq`eDi9 z>JiZ=OO{zJC|PBUD#?-jc=ag4*IP{~dAjPl10&@VPM2)1N!!1nXim-C1FOupM9-Rk zXiO~GTCeBcvR!pVb*ku;WZA+zTjOB!A&tXg z%#7*3q@ZR|(EwHL>Ik`2@)^p2uuq{;+YZd7j4WN)FUK8mTWSugQ*H z8)tHIb!OvDCABr-XrO$toh@HxXD^UfDLkjsRSW9V@K@bxo}!jLShFeGzjQwUy6@XYf`?sYH;(}@~u^?n)kzv!3PtGv+9ontSkU%s92 z?iNma;ova_l^0Zn_D>`IVQ=n_)%5bh>YfMtl)q8`Xw+AJfL35RJcrNa<@MQ-)#bJI z;m8JSLk|upZ>(B;aBz7!aaNZfu75I8sqkS|w&);}-#BdY!I7rhgJWYHE`Ns_`b7DO zsuOsIAywlKURVB6)%xaYQ!9p4ef0cNYg3*-UNNHT z_Jg;_>?`>$lMl|q?zbPjFIH2EPuK5??8Jj*qO0cmz0oNZqpCCa&#Abk{xwp#-aM7n znu8fuYv7E@A(Qu=Eg6gs7Z;zce)ixp^URe0mZ~=nt}5}@?>Em@Um6`+F`<5cG{0i9 zt!+6vq#c8UKJF8!K{}S^tj%DpuEj7`-A^ z)8lPfa{cK@YejDT*@LykOKb8Qr43wqco`|5?xf4|SUa_`pma&??Tv+{%WLmye4})A?X1QFrMb2D zHI|n?QJWEc^tltYp~l*H|4==#(r0T|H8z&MP@B_uxO8Xj?x|hhc%t;x+NT>o zlH6XpuXb~jQ(9cRwJE8zvUYn@x6=CBf~KCPN%|zQe%ipQ@lAc{p^a@CSn)(d;=vOY z8yfrvKdRW+(EVV0#j_24TAYd(8V0l^RqSjS+|sRLPs6a5o)xb)jBM#!v9Dol%fO1_ zhU;2}R8%(H)H0%?zF~aJsF=5`Xs*7#<(hckW=6v#Sl!9vRUE15-EuwshZ)g)^RbQh zRkSutZMmi5gNEB%CRiI6Ssv@VR-CGt*fN=z)(-Bh=}#RwQ+1;8Y4fEA60Lrr*OHyV3hK!bO#d~WecJy-& z)HZ}7ODYF7EN+=oyw`fC@!myc!?KS440rTd-=<`0!>V|DeTv=-y|`H0U38=&$9#T+ z^|6nr7dJz_(EVx+`&+-Us8h>G+i`|;w#0fV^{++JD~GD?cj|S-TR>^4@`{G_`(LOW z)A02EA+dJ9;!MNl$cD;m8@9HjSKjzSbxUUDxQ6Y~e6w%MgJ$2BC9xiOtS?>kDs8Lv zK&(F;#_Lk!tOr z%93ecCYJ?jPc%&{>s|X%(;a2~!5LsXIH=BPno~BkE~zQK?26iVc>2&YNZFXWZcUkG z*VgrHda&%qy1q?I%Er|VY+7D6v2I9YgCX*ix)DvQ%cj?jiu%g#th=Tuw`^wJ^-WKd zrPbZiw4rQn-Gru%Wee&iH$7XnsBT)c)UfFV^TS&cW8O7}WlQVu#$}Jz&4~6d%dVT# zw6iQ+m)^9e?8&;!rdP|Js(Y|$U)iR*C7{X0Wm~EWn<|CrW%+f>o9fGU)va!7F56p| z+jIncqUnhBfty;(UaQ-%KfP>!-NvR5%1Y~=Z8}v}UH3xMnX*XT&Ssx^&gSH@mbyL7 zfwH&jUTyAOcD!z1bN{jr>x!de%1+l+HV-O0TUXz7q&%^%xp}DB=#P&ZHeXThuUfW$ zNF2M@9cdm@-o381`C2saLGz8}ed$(hZ@rHc2G=JyPb?o+A84LZKC*6L z^uzM8^}U;?mtR-kzxmGco9YKO@|0IUl(x82YUShWuV|hLj%iK&G=OD!;vcV)N4SyJ~N5ezbg6{gmeH^84ziH;2nJ>hElRvOHv1`C4QIb!vZvUS;LP zhJu#ml~WqfUgh+LH==_o?`$~GvbuC&{Y<>2uySTYc}s3(T0?Ei6P0rt8e2A0E@(L1 zvaxbe!#gd{#-3a%mo}VedBHT?vQxa>Q~7AaN3<#Ud7f=!Pqne<+0M_Zv8Pl$pH^l! zw70x^!BeXITV*)nG)<^{GLqD?ukxu#x0d3{O_820m6coSu4$<+elpUR+NyLa^CJUW znqyY8d|QrKzHgS=b975^`o~xo>-|>ljSM+7s46is=g{=Z z>d2_3-1z8(MhvL?-6Ky}-|x`S%1Gpz=-${^MC_@*vL$l;p)r+jM{YTEZG6l@+KY`U z#QK?)XCpHXO^Ms3wCd?YSHxuE+js@NkwZ6D9*;~ou&naK$mB!giZUb9@It2}cO06i zr_s}ldR@d9)VHz#$xK#qO4LeD0}^c|r>|%wry;E5^e@g;iBGdi(=}S9>6==m=~h@s=S5aK*yFs+8n}OSYFW4J5NkQiciwT{XN9s)_@MOXZi4$YXQlgf_Zv>W z`z=;c-@zB+>zx1PyUF)W=TqMgeRnwLeDiz@+yvjlzDHfp_ejI*R4)Gk$Bdv>C&}JSNH8M-MX+7WS8%BndBSX<^Lq_ec+L7*r&oJP~ zTEn{3wT4bzUe~33sO!s1)z>A~wJx!)OD%DY<#m01UBmiPc)!n?xx--onQV7|@9*=@ z`FziF?m6c^_c_n=oOABIbMC$C6dG}nLaR6`#wm{|-w}U^_n3WGG|v0oysKjCyzzN| z5Y6*G3{r^gLGyy*#Dl8us=g}@seY+CEB-gt`>OZFzgPXU>VJqARCiQ&#NVnuRDCF3 ze#G>MNyI-JtdpI9HiPk2njpN_19$ISgG_MYPMmAVN6&Cdc~P!jgueGou6~3Q2*U_x z-*dRmzt`y+eQ&?(3c~n%2VFPbJM6lJaQ8irYsxj%A-;F4Bj~+>ju3>1_fB?1y?3f3 z1|jafk&Y$rUFcZ$-ldMj_r^L_zITo4Ln0-A4;YibCNIMKySB==!f#%ezs?l$Qh6y; z%FEm}BUuzKXZOebgf7=rR-kLA`i*Sp{@jbkMWlDTS>>isZ;>UvU zZ2vsGaV1y`hF3l;hT;n`kBX17P<-VDUyu=F#aI@G=l-8$;rL3#H`!yb?%%NmWEH$K zN?@aS4~PJLg&}6{5LW13>0a$lb8FmMcdon8UF)o~P26vO&x36g5_I+jh>h?A6 zYuIp_Z`^RgSO!PdC+>~oL)t59bJz15bwmZtw{W0{H^MGo7j$W!Dots-Ahz&0sfQ@qBq72j8UpXDfip!flM zRq=-64VJ5@RqSG$6&8h+ZBf`2cJxjmbeP}S-^7mNJNDz^O7W0vv8+tiBfq7LRCdjC z1x4UrQw`o0bm*b-kmispq0Q_#>W(WT)wRkLYu{vAy;IJ=d19p zhjA(=o#&Jvv(s5DCcT~;`M+SdoYoGsHEGi+{U?cDv%M(gL%YZ7> zuLi9J>Hq`KFr&w}GDd|)&>w>S2rwaS2DN}%L2aORPzPumWSEauA4E$BA^jjE9E3Cn zA4y}}f)eya&^4gBY?%OW67qr9pgkk< zn~>iO9*>}%@4~xA(auq{)9X>2LCJgI8EDVD(EYn;!@Fq1D7T^s)B@N5ve-jhV^7a` zK1oA;me5HvtFoe+GDfpJTfp^cUcN4)oW+dEk9) z-vIuA^oIbxd=tfX2=xg{=ZYk1lVBa#(9iTh0e*^Y?3zlgF{UP#y1hk;cgl#kOEudCV z8>k)B0on$+UdE`K3~ly9n}g715wzJ4%j$h&M>DM3j2_htjXn>}y${WGL33TuS{KfJ zlJWlOWN5FSk0I|M-3#=i>=)!;NS_AgjvddVXEsAqUC`7ZwA2p`^$RkL5ei@d(lO}I zPoTB2pkD=@9ZQ~vmYx@0;`zg13b&f?b}TsYh=c;r)KiOdmYF4<6nJ5ATDA_rb&a(3kWW5Afz~ z==S5rgEvs84A=pb0~J6GPz&q=>VP)^?^vP7SfPjK_n}34j2C)%cON{v4_@5|ukJ%1 z)%(T|Js&@Ukf#P70=@*ih;kZFAg7QHWB?if^1{3O;MslX+x773K6rE=TCbPJ8F+CY z-fH;KarIB9`_Iz*3+NxeNB{Ue`Ulpt%}j7FNS=8QBg_!=KLq^`LH|S0{}A;5-_aj_ z&)z_~4A=pb0~J6GPz&q=>VP+ap98-DuN%OJ*l!ZsQ=oqYod%tm8G??7Fmen*r$f-` z5cPHYm#xs#2GOgo zqDKv(7hOdUx{BU&6+LGNZ+9b~jhlHJ`gs^-L7> znFxI*LZ6B3<(UJ}X(H3$UC!%)Or$q}W`S-5)y`~%bZ$szg>>nV&I;+Qe%~*`akc^9 z2jA_$>p%(i{Q*#l^c$dMzz(1sr~oQ48%XnH4Yq56T|gc1Cg1?S1K9T+w2At}&#>(Q zevYz!9GhkZsgImP{;z@a!0*xCameePA*`_T+pu#YyNCS$jr=KW{}J2MpffXxuy>-b zPbFebralz~`zONwiLien?Eg0GpD278UpvOP*Mxot8dn^`uc4m&JUvCOK-!M5-|fk1+TDT26_sfVZ{ve6uiUgn}Mw23p1nQ zO6Wk%`}ilEC(StvpfiAS)NY1fjli!);8*?dE1Y@ZeW$Buw!@DM@FN5K$N(QQz=u5W zArE}W03V_;(f}XogAWZd9rlyXpNf#)27DhpwgayNCBP4WQs52jR|f0=%7F^N>oW^+ zZk3GwZGg`h;4=pJi~&AlfX|G;XSTyLgU;8s`_9+4!#51@4Fi0`0N)saZy4YkeejJw_yx{_ z*^}^#Cxx$}>`B0TezzU|F#`WEz&{M|4+H$e0RI?)e;D8&Bk&Ic{9^?EVSs-m<6JNq z=Yq)?tNY;}9{9%y{KEkM7=eEn;2(YPjY0UvlLF491e`?)ID-=E0q?ovcKF72_{Io) z!vMPv;!X35U>UFFJg}Sxmh-@J9$1bn=7F{7?9hW5%>&DLU>OfAa$A#y!xs2io>P z+a74!18sZI6Ftzj2io>P+a74zVY;r(4+@i^vuyBWQNu} zTw6xaCZHK;!Lc8OZ+`&a{s40h&b~pP#aT!Z=!d`*FpV$GF97hqU)c5u*zyC|?gQBE z1K8{XjPv=h&j+y02ROnL(D?^==jNiBd~o)Fvj@Fq5S%65r$hJY(0w{|k2nA0OfL;o zGgE<{Qvo}qqvz;h3w+Z8+uE63ut`2_k`Jjo=rv@Ubl4^xwn>L=(qWr)*alyB0m^_K zKsitW(3MCHXf3b{r~}>v9N=>R^d0c+1%8HY5Abv3{R-QsfpggYHEu|v_l=^1=p_}ff(N}M9hM+_r=yotpqK3O z**zb2Plw&pVIi`8I(o$}ynFg-T;))&$i?{tX{#Uf4>SMWFWsDLGko8i`rHpu-iCT2 z&ea!TU&i14EC;V|VEy7UoWsw@IeQVji@qJS0Cy`LxMqEadGP+|Um!e=GxlHM+VV8Q z6YL!O4c_PXdxUsg-@FfA*AW(D7Q2Bt`$L2!>>k3?Yzkp1n@0Es?qB3xoyi8N9JcoSzGOBW1+fxRL$U?$5D8ZnQp z6O6bj&2U6xAB0n$9Tke)Og%DXdE)0F`hGCG+s7dHC{K~G~O}ZYhq2xrr@TqrUgw4n-(=K zZc1p%Z^~)PXv%6@(Ujb@swov7AjlnZ7d(L8QyqA}x(4^tmczE^@c!>{gcZ0SeGQ)W z0YakUhl(Gv=M>EfT=ywD6dmv*A$ank5O4{G<>xVG2?lTn@<(VPC{H_YU^`CsjQO7P zyoEVOElTGVOR#g?66U;NS>U{7S?IiLS>&9uEN&Mq3GG3a740FG5s`e;LYI}?& zqdm@&)xN}%)4t4--=1jM+P>0K(!SbK-kxTuZr4~0?OMz3_FPL#d!fbFUTkr-ms+~o z^_K4TTFasK21{>ylclfS#MAxl4$F!5P7X>Bx9_){Z9izC^!fI~d_US}wB2L5(tgY` z-acTt(SFi$tNoPaZu^L3s{MjhY`@vh^NTwIn? z*HWwAwVY%o{qV9l$V##kB`j&5ur6!AZHj20Y^iG(X+H_n771Keu#2_Um1J#z4WJ)u zQ+qM#g6wH6cEwv0aSS>Z*$XzXnqXVfC)t+lMmi(pfopMfD zCm{1}S0k5w($#F8c3Et4m(!+lxox4Y1GY$457!_3))wtLLS?*6FKzSw1>cu!Ym0Rqb!gD%kas`z*IDWsv@LfH z*^YLsvK{Y8_3MlJ3+zn(=g@XuAnM=F?YzYE3%%u1{{7V9E0-uQm-Kuebrg4wIZ8XP zNxtLIcTPBJJ8#prqhZ#k$nPCZos*KDC7nq=MAQmD4csQ((st`YFQsjV$=mKvqBfsi zB;887cR0Ly`Yg)(FpWRHekM`LmbN6<8Qb-aYRL~Jy|-+~xJzRqjlTiZ-v`m(ct53a znfmJ|P)Uyxm5w7(Dc{lQyye*6Zj$_+{G9tFjq~tL$?y5NPrmBQcO2}Tb{yU-cX;-y z9LM&CItJQ9sDJqVo#qCr51)6O+#5+_f#cNPXudtNHFvGCC4ae}O8!ICG1-37Bw{|Kxr*jRP^o`PeYn+yc@lG&L?!=` z#yFZk`FJi-(lyCL{h!8l^j*ia>nQnvh3k=kgx z*s;}ixueA1-?_RibnhD5)sAv|U+2oU$i3-p(R(x7V)yFW;`ipYE!|txwtVmQwxqpf zZ7F-J+Scr?qj9P&eQ#r1=HBKu-Cm32ACf(&54PpCUu!Gc>ulS;*WFgO_kh$F{66g) zm!*B%syepXM>`8i4{ddjp>c0dTl3x{(td50y+<8sogHEE$J^X{ z2ip$p9g>bCQOS3Sw)N~iBgrmN@}IUNd(TOIm5xm|Z#%m8BI)0r&~ZXKwx6eOT%z+3 zK8}!|-0U#e?sV+7-Ro$vvkn`9^kY|cxa`3lUG}h!Zu^3cL*(oBg&nFunIBQ?kao(QVG0OMP=(u9f>KNzea&$gNpt?C7H|+Txw`gp( zZ|%5iFX@=Fmv@TxYS#e{LuU~0ujsq>-JK!!md*(Baf02}8D)2M#@M?$C;i$O?MdSfW`^3ZQC99g0_3^ zg-+&PT`G)_6g+$)?5+{wJ3;#`3EITyNDITyK8or~QW&IEUsbA>xc;_Xa! z=Q~%qw>neZB{W76e`kif+?nOBCY?BQ+y*+YbmqHvJGZ)9oF#4>`4!p7S?+d`zMaGF z8{|`TF6^v!cR3C2Zaz0+-XnX`{O;WCK1BVI+U;y{_d0FvJ{oJBC*0#sm%HED$A$|qa=9oFu=%Gd7vFRb19K#ZeRJK|zm`yf6~t9Ha>zG`PDU$s-iSMBWLt9C~D zs+~)G)y^1SwR4rP+PT43?fe_9+L3*UR_(~5Xw{A^o>uM1zD}!lWC^rtNA^uxwIf@G ztKEZmL%V+!N(JuJRh+6Askl&asbUP_TE#@g?TX2YX}uf|2ZvU8^pQZcK2{%JF`!?n zU#?H$Aw|DNpRUi;>-2g0BK>xKnZ8P2r*G6Z>n#<>^iI87e?Z@(KT>g0e^h^5Kd2wl zpQ$*;!^w)16&@Z2Dk#v_F%C)tkWP@}$z!^sj5{9EI;|RfZDu)plhxyj_h$&t@oV5D zd~N3Mah3ZUgcopspoXm!e<(Jw6k2746xsC3vl`(c zd^czfzBZJK@G#z+kcMxT(RWrK!K#>bSRb?=_l_d45>1D-4)o>rDEzBYg?l^(glIgy z+JJ9`{T;$WwEY5mTzFV`825VwWwp{U+t$`avSqD{S{Jt_04rLPTUWKFBF<>dYRzfQ zZ{6Bjg01q_>Q+PR?$#9*%GMT?*jin!U9H`%hgy4E`&#>3PqYrB*4ftct)s11knU?8 zZ@q!^?$%qacUz}SqAAD}g4{)|i%b!%D@;+~x&j>h!L$UW-Y|;&C=eGZ+yxf|(=u=` zF(tP4nJy47q%|fjINOk3!9gwPZ%sDE;0P2}@Gy$DWbhWauy34cWvk5;Vp?rVLu*f< zcCM)q?LWlP3qD<@VpA#f(c8M%q&L-qM;|y47caI#IzkEZtC2^5ep>QO4ZO`OAT0q$ zBbb^@CX<8s`j0{!C6Ek&sS`96TnWkG$YI)VI%ql!>Cd)inLMUrrX{8U9NT3&X*$J^ z&t)*}=dB}sOUDL<>?5r$CXreTew30xIkYF$US!sB*+{-Q__%zt&g?Y1{jy7K@KGu= zt!^DPA29crkC>18C8T5dU_Ndhl+qG451G%H&q3b-(o1Rc#nxW)W%E_u3dn7{YP;Tg zw?f$zV_5}x&%;jL=IiF0<~!zldk$C_+0CMCbyT^#*=i}Vl(*isR09UfZcB^BW^ti+T=Bxv#k~Pm zv2H>^W1ur9<^K{53-C~Zdh(v?pmg- zqBRJwE6k^kiLaO|xoDK~}9b*IL-xTcNZTTT9IrtKM2`ZGc24 ztW8#v)nV;y9o}=!y5GFide9VOJ#6(@k68z-C#|Pihpi*l3()o@Yn*k=dd)gvy=|RD z`Ls=LQ`tgok+x_X?&aB*+Lqgr%yO&7mSWb~)&S|YOjD3eXUnq{*|yutY*n^8bDgcx z)@-xba3W(nVCzB25!+GQadT4ZUE82-$acnduGM9`i1=*lsC}`0tG#5;W!q(Ip}pK* z4c*WPmIEI;Z#S4NXmKz6n?~dD)=_wz4P!%}eYd^EZnL}WUH0zQar+^w#@=i1vttCe zpRf{#uHq4~lQ$9on= zC&v=UGVa|rM+i*%zIy-GhhEdb7qD17h|O>-C@W3b{H#J z#DtPA7Euy|5Qng&q_bohLSo7Ol9dRn5z)wr1UL#D2dHci7y`}! z=YWflnc733_Mk0(SxGLE;p0FukvxHr_;+%fyM%)ABj>MdVuA?kpL>m zo`O8GFKERA&@}+48;s81CYl|e~N2pH^l0N)&+Ivjy|8#896SeJ= zsLEF!3hMR&?dSVQ?Utz2eu+wYxWD~Udq0U%{~7{(wyj7&TFSehN_CQ9eS0gO5<3FIS}Arw2*T zmwa}(pGy9F4dv7iKZ|~b9{qa14SvnwC;9z-elGd@{q!Stko^39D*5~;P(2<0Koz^6 z`o{*TkK9i`%ig|mO&Z@mGPX#4Orla>`z-3SAD`EJW0EvBar#Mp^ZxvFw0jVc=>7du zhq5z(M1B2L8sk1fX-pz{sQ;e>(1&^dN1v|90J4xr=^P);N1CwJ>q`|SNSFJ{s*yGT zyHN)FRJ0%;a#q*?7tn?6P|$8rrzL<5ka634HE{VQQx8qf40 z;Dfq+>_r)$Yb1L#V*4`cLNIQ> zXt13Cszsdxv(V=v58!rzZ2CgfO9d@P9<}>E=u1&X(ECse+5j|RKNqM8^okdH2evzb z{on%`rT(Emi1bC|9|mAcj$@!ckPf&`NJj$zwGnM2`N{9~C$U`zD(!O$=@H-p$}>PO z0b{^5)C)!4U8E1Yl=;!owMdp~cIp%QlD z`aA&R}_Mq#G@-;{gAr1Y|zWmw(`&1Hd z;MbLo(oam6w65NP`Eia)fzF^XNYD|MU0uvBvElt`dW> zYA=Pc0xgj1Lm{Yy;()Z2SL(~tgA(vwJAeHKq?-T};PB;lf)bzozHKRA;&%}Fc%x#0 z2RP=#04Ra#N@25ZJz{A0mOI2w@rD33&15G#y|o0#ktlp%Y<0 zk2?zvBGC3>9(xLoVc%l~0|h4$q6$tSj38VV6VV`QZ;yv z{ZaWoJhdK)r`EgKm*fZK2U)cIko++F3V(t|^XX)m7D1_U-?~BMCy7u$_DiPw+m)SiXU=S78T2{%)WJumP?B zbot7=XX{G)1k!w8dHx~n+Y9so{l0xq_~N<6+-!mT&*gs(EB}T3C+sWopWuw~<11i2sRDQEXpL#Q?~Yv|?qEgn zw;w#gR}+7guO@yHYl(k@f3$vw@GM_PoXFP^KgZV*C-HT}&$9`HWWJjC1@>=PO}vt? zCQjk2iNC{F6R+Z{iN7n%6Xs!s?|eap6~4hjFxK|c`r=d}R0ze|-Y_8yYkMPv2(0am z6e6*!q**V@O8)Q__|{aUw6EouRG4<>y9_@b;ntJ-SI}g?pTYrF+9gM;cW~r zG96!ioGrX8yo_fr*9vRdtHLY7D=b%7C#++e`KshRzAAYOUzMCMY!WuH0wG(-W`)A5 z!mI2xVY9FqPbY2>wy^IB1wsMa%2zIL<13f3ZdoX1-xs!{Uu+jjgc9~TU&UO)S26#9 zuVOCctC-*5tC-99D&`%06>~XX#azKxG3)s%=1RVbxr(o1-YM)6_ONQcmbr$nWv=CG znRoHE%yoP%^PB1?)KB1F!9c5u!f!<-MxAHGXYe0nV2PalB?1$c2utzCgSUmB;4KG# ziMPqB;R|?6EB=c#A(ZkMDZwSUur(X#KUp>UKEwZ&p{TzSLB>)L=gg&!g=PmwwfU5T&}E+BI0Tvd z%#)^MYhPQ4Mc%f|65p0)S&D9w;Ec35ol7l8o!c!Jofoaa?FrUZKn7$TZ;L~F0LajX zHl=_LBY(;-Ly;`i(c8XxE{fFt<)3Y@`KpVJCuyr;mV2xD4Bo{mz*6KrQU3CtH$U zVarZOg84A$e)yw@)5W0G<`MYhC5HhvZh?Px!_FsQ<6-!tXg<~!1dyExah6aHN=G40 z@a9J%KQd6aZ7bmytAP<-5Yj7jGq?|8nUk?o#2ed_z-XDfnE+^OgjSmoZ4D zW{jiU$9;ZHeV^;|6Z~G6o16T0g~-VGWPX&mR{qBNG%I8I}@ z1vYb=HC$&jmXq#iJg0Gy#&n5#$H?0lCkZrO@-)|zZ=9sDjgONU(`l^a!UP{Q_wjdL#6S^9t~Rq(pdPJ&_#)mA-~7D&pL~|=IE4Og zncLs}dhbNL4+2`#@JIS(lI0wZd&_xWzm)tQb9M|zk$EMKvl8hzjym&dJHYEvA4x_Z z0qi%?M+tcte+i9{53n6JxqvQ-wr|CFTY~X62|5BkvYlhCZZEf1W2}oHvU#?Y z=@Bm+8909Mya0tj=8~p&)nc(fD&oizGH3zOvrEI zWx=y$4oZgs3(O64j@e#qO>H*-yMY!C1DzMO+fau25;odRcH}6xwqV=V-VeJFa1O>n zb_xXXDYv@7ugj^jG&@5r7CO(RW4j!#PTRC=zn>m-9d;2s<|Q1*%oDBvw1v0^Tqj+p zI7X1Z;JV}*!#07^*IX03(k#tD3Z-4QU6YLmEIkBDyQVwj9jcB{AhIL6Beo+R+e?uq zEXQ_IM+(7tv11LPBfTS&V7uh%0GC0jU|OZY3IeB zbVAQkb14B=dymXtGXELI=07|CS$rd@VtysQf3$P{P8K}hFu$HXq^nDst|S)-(-49kg1+lJuRs5 z9j0#!!L&A82*FqRUKJizZBZ2pkKqeUe=U3&Uo%@E6yQ5XD}~aK4Iu@BIixhCTR-`tr~Ugax)9(#rc{cF&_LOUNq zFL-4oG$P_VW5M{w&0^?9j&Fah#rLUN=C|UjO$upK z3&Nwrqghn=omdyg#$r$l@cM!L#>E0?jia3|nRTq(a*43zrPdZY=p z0M%&#nox!-;J5G%qBn8%>&s(rIgsuI_5-+jed{pb0gj;_uDW@8fK%bkDbSNlFyJcr zty91VZ~?dkV6~J1SIm&XyU#Vy3E(y`=}QwOdAtw|xT1b*nz2SXpaMd@WsQ-(c3}U; zXyg$eO2c-I@c}d*$Bf`$dms-WG=tY3$W`2jGSE_Bzmx=7^sQoQ7LT`Vm4pVxD}--=`So*CUO5`^<2?z_T+lCT<% z)x*o{V}Lkd39!tEL{KV&R_a#+X#r^s(pmsktS-~|k2Zid0VV)mR^JKi z2k1Cd{~!QwtB1GMAM>S&(s3mWAbk>mb?aeOo)3%i{Vw?^@qkt8VMRYh+K6Lw;P_k1 zk%kOL$ne?}DCBqz-fe^ow9WIV9K4LEZ-h)n$U^nn>wreKw)#x<#p=t|S3$2=->kk< zeGe}eP}T(3gw-slSy;2EW-;P~nibVIYm#eLRo|&et;wj#s>!Lzui08tQd3@2U1I=B zYIfJOpzh)tTaBxxtERi=P)#rL`VdNL`fE5gt{=s$$t=m=V^o1*-L!7rw&hg&52W zrR-~}GRzL~m>s^t7GrkU&X!_!c#1t6{&e_K_FQ;E_%il<_=@mn*~;+e!k=d;;V*=* z#N6>6%pfoF8RTU?gQWfcL`s2K*d+B1yf@@g+$r4cLkp-4Z~MUYdmG`sjqoJk(W;i6j-8!5_wPIi90okt-oNwMcSi0He3V!^e<>{c z&H3NNyh1a(IKLhZ_R3l`4%&gKq`Cp?U+~@>_`6e16F5n9Wt; zOTw41;P7vRe}g>~{!I9{SV(wccp`fwJUKj>g@u1RJOwLYX*~MRIg%hV;J!D*lRjJ7 z1tAsh2;NNrsof$LSBq|7SXSlD6H@Wt0ZN2a#KYcz{dnMe@cnohQdHL)SeW|tnTeSR zwVubdJg(>QTRd*zaVw9_Jht-K!Q&1dck*~IkKH^zz~i6s_~$(S1;s4fceEWm??305 zkE_2wGcq%x-p=C^9+zS+idW-ZnaIa`W@kp#6+EuwIaNHa=5YK6K|kJ%{TD` zRfHPvVnhz!xQZBWnnivaPdjZ>zX)g@eCrToZm@N^}Qt9V?^<6S(Kq$8W!cupISojh*m@sByrw|TmU$A8J= zBRux-_$b9p^c|n?fp27T3GjW~8qT4P$9SV3Bs|FDpYZsnJbs5__7!NKWC?7Cw*`2| zAo44C{L$9b@O*EZ>Ug@5$KE#CdHT~^c97Tcw(loA?QP{xdD`37cX&Fm#ey1dEQH*6 z@3gvDjrm%=UHv+>9Br4W%hWrVTwS5oRJ}0ep6k~RO+|XjqD-yZncp;tZq@a zvPaYwwH4lOS36)sr`pLLQ+KHUj4e?ASbcy!u0E(f$evLDM12U~&;F_Ur)-hhqy9Pj zn)<(}{|kFk{nzThhIjU>2l3>CfG7NL?uBud|EHBaz#iUn!Jyr9Y0uc6YkO|*nb8bE#Ri@iOWPYWja`9$g_o{x{TbAg5AY32W|D??fx`u4uI4O?a|GZC1DA ze>FioC6432wqXABAWPOVF#xnJ+y^SBJXruV_2=sobQ#9f`qBCoO{a_*^;fd)HH{dv z>c{Jon=Tl0-aJ;ns_Bw3zy3yj>L#agYyGYIjD|R4N&QrPj?rMOZV1{?+B9L@-4Ig0 zwduC8MJjKIs4r=nG};=X>dTv^jjo26`szJ$W7me_dczM*#%_r=#JzcHkIHzcVM+aN zqs!Rau&lnNzH4`+?n=GQ*lp}{PkjeW-a z22Fk6n`6fF4ca$Ndt!~F4Y~FGd*Y3w8}`?q*t67lrJ*p}v}d{T#z&|mpG1A~Npdz6 z*Ps32gz;8GV!i9FrN(|qKlke+Ww?IWm~R}H_Vc$3@@%RLki#dJB;Wm1;{TcYzgwTx zG-fPs5bN`st{Dw}y-WF0dp<$$_v`t7{XVE(B|A&<`t2;)Nz&UV_>p8Ec)eV`LH#Pc zezSTro3H*G_1`d6Sa#T}{GVv0uSXQ4p9<<`c>d$)m2UR5`p?kgz8SV9tdOPST7|B9 zskh;p3F%~Tm3@>e^)U4o^%fj!n|d4g{Zjo)^spf{u6ER?)u$oJIrVSQ!$#GkIJ%cB z@uKH+iSG-(JbJP>fj>(;n};u=;(1(+uO6q)*by*G<$`J*%lNuA6AkX(Ai)p4BuI)lICMY}npVrfEc6*U;Ed)Szo< zZgAF3P(WJOkk^ohR9RLx@$l`ZYjC2Lg%H61wx$u>Z+p2n6cK06*Uz;fvtiAytcI$F zyn0i^nuhe6+g$QowE6Q`4gcNaX(iGwtsfvet^$V)tVs#XTZ*zIgynN`7hwFOXRa6V zH3YGuw|#lh$cq(e6lYjd z<*gUQWMYW8Sj0c-v$?`;d?{j5Trnr_3X=)rxJ?o}Cl}Z6BA*c?j>0k28x;lw+;s@x zc!0@;lL$S+kvaLzOd%ZR!6G>4lwh92IuO0kGACCDKD9y~pr4bE6&gYz!Ww}zL} z)Ta>A5S9X7fA_TETHyb#Vc z3&cLr>j^%&vC>r`)*>*mOB@W`Ll{HPxP~Lg&B;9jK54=^F-`P(ti6i{80M;sWieF5xdT|PFRj( z^a)A8oK~a%D1yck*o{7JWcbBdRnfHu(_FZqeLFXD}u>c3V0 zSM^t9}>r{YCXfob$h@zJzm&e^mb?Q}Y=hn9l$YF_F#p zond_6e}=J;pJ6P)8AcCFP#;nsWl8EjoNc_Q9#fC8m-#sd-ShdZ*@YyeS?HtV#Gj!h zG+IzheO6HafX6f*3+e)_eY>QHz^b`myyf>XCM47{1`xd;N?)GbM`fU5K)t~I6ao1X zpY>HO`qDQw`qJt(JGFSG#+F`gIGSFbrm2j@(=}asz2P{JnVyrLQ|{C^ycDBvNIkQ& zxN><_uU^07Fv@h5DF}Ibli>`ISFs9D!}RMrcb?LBR&U=~o1RlOT;VcYtZ>yHd^rL2 zmh2cXT-`D7=CSk}FIT^GQ13BZ*Lz+n-04WaLHikQO8Zr0>5o+x>5mz>7s;=z1SI>5iyeaP7kEbJU=ug!v^`{I~#IvepZCQQr+A>2OWNDtuv+9<9#Bf^mHt9~nEt{`6Z$ATD{)tUseS>T<;d9S!BZ1cJC4;a+;Pm%SaG(}jhbWi zi}Yi4hp1-xJ^jR+wfc$b<{cL*m!~%4dA1z=?H!)VBb7ZngY=X23HnJxGihRO8&a3* zr|Vbfrwx{!$10EPjHr~?ud0+A+?A+X)n6G}pH&%ZIKbQRDO+=S&fTgS_v_^#o(P${ z)n6G|pHmrW=;240+uFHy|1{e^upQ<~Hn+806UjR-7@S-aA*7d`m!Ow{%A=oFR^{^h zXFQ(#^84q`+|T2mYn%1^tFHrPI~(vU)mi;v_{8Cg^E*wIMRPrJZq2zZ`c#jc>w}-> zb)VvAeNZf;aRV7R9rsLS8kSy{DH)L*M# ztiM)wsOl`96S}f?O?}4Bu~awpv7J$C@9h{^d(UuW=Se)9cSzr47}7VbP1;$Cr|IVM z?9)38=YYJOdOWRmzEV}6TB(AUmsQZY*L-yWMmVNEfl*t)sQoL9qh~Nu2VtcC2NuFd z>QMD%jMQO#q>kVt^`qERx;yd-*MjPQQvVZ6=cDs0IExZ-=Pe53=_=oh@g3g?`=D1R zbOm`reFBpH1LP7Q(Pi-DXKd^iczMqcR{3(S;3^;l?_Q?aO3FKfGJ2=BcV?Dy`|vN7 z_smzy=?35PIFk3OK_Ra8vIs70C zTA=ex{6C49;VmaJoHMR~tW=-8xhSAS37?4N*Kit80dG;0_VRkie`LF09c7{t_a2m6 zfgUdH8uAfktn!Q!R|QH9VDsmTN|iDcIf>Y>UrBwM!S|_tx8k+}Vl`YB^ z#U;fUa)W?We~C<4rZ}O14=HYfSDDg#)kVDIO080>=usR&*#(qol@YUhDO!}v6p%-8 z93@F~M4tq5WsIUsxj<2cvi-mne~ChgAKpSZtw2vx>;}lky>iPHHxx;VtBMrlqW@s) zkiSf!7(rO57*;GoX*xCmM`Vyxi8Ay7@w|9Fpv;MTh$i6%%EG|aDIOEg`b$Nz zO02@{a|b0=Vkfm#YK3q_%n~pw2$xWnD;lV+zB0L(BG|-4Jjo^CNiR_>q}KY%6!=>0 zB0(=k3$-Z4ISHOrMQilsfc?5*b=rv)+PR28SYq|!Cgf` z&>%n3pDzk3x>G1%{1f_xX@9;9N4-twRRXjpz~<7iaSx*f^XC|HgMbl#iA*TN>^Y2W zjDL8>uFqd0hqPMOgL#)`T@hPuf0>N62+J78KYX`U#Qhe7zeJ8BmkA3PG|TqmNJah< zg`mV)o0d&8(#dX=q328T;pxXDc9o?dht3~v&=YmOG6fq!SO^&xArIpp8xhd&dFkhy znf|}K(?Mred6?h-J$F0;?{(nrhtMpb_u>8qz4??q?*2m1ymoY3%lB4qvlYi|a}~#J z>ndKdt-E;HwnML7-qu^3xUIi{t!OM>x$OksUcGI&aB|z(;7J^hZHwS$19HDe87YAB7Q!6to&EE^%X2CY~r#bO~(n4{fb{^ zN#2ioa8~j@+=Zn7+*d&pEcz;k07{Vg zDBsRI&htdd17BXAca??YRpnXo4&)v6(q|^U^tmWs{_%ivC+fxewte)uT3>ylC{LX7 zZ`WbFXT{09x;%GYPhN^dAHc@H#($n(8>_jEgR##i|0gTpUlI#y1Y=Z#=DvJ|LjWa2 z<^|=gd=P9d&x@mao3G@B01=zV^CI%Zyu{5n@}hv4&A0O6Hs8%#vUw_R8OkwNaLa6f zr8m*Pqv{;|Q%cuG^WjUg{~pu-x+?EKGW_4&VE*s!L;T;}5dQD(!`z!6<-U>(Pgw<& z0Swm+}##aI?cNJq% zC7|QLjR4$2nt(F~UVfLSgL5zE=H*_^&CETMdmT99#b)KJ*K%*>p3A+1?VGt5bML)+ zZ8OU~vssBF{l~S7EVh#2yb@o1WQZAmYo!eT5!B&&Prz0EY%blwp>vm1f8OVljC8mG z`-|#R7`Z;FXA8J~eb6zDIMTQ!q7U?d^AVq9v;u+tRXl(^tieUh_^JdESELSX?VgjD zOy>`)w(39H!l~~oR##IFCb|a_V?O}WZZ}?0i*h-*=%<9NJnjkI|eis zeB6IQ?_zYLdy6W5Z!wtv3lzfdOgzl*Ez;WyzUZEGf8rR9AB=OuFvfH}j6I4w8Ik80 z%RU5P4K1he;YbzIIRMtvQn^%zQ_Ao6?hhKKJFGjFU8U>HuFFozZp?1Zw(#IY{(j0q zDXycwu+(3CPZ}X^%`R*od!k${{nZMuu2o#cp8Rp z3rhmFgOGPhD#dl%GSv5-OGMmZVgMM@!hN7}%F`6662$z&1)+t9@;#e73wt;34|iwZ z%|Dh?TG*FA@N`;X|CZFv`wLIxpWKpKcs74zvvx^p__>_P!qM!0Z+=dv?!cDrg6N!O zIUxnHn4kUmCkrwQj$|(=&=vIPjusRx4b7hpjJ?P89o>6e zZ@m50a|QAx!{4;zU-Pyruq_37n+i|RS;QtKL3JO zGv1s})J%Xj0`>6e8t`h{Ya_3=z1s7(^rKeu>J6U$@$1VTY~>SOd7glm`TR8u*FS(} z^Nr27Hs8e=kEnBO%Fs3Ch2%wm7Uo6e#po{RF5rx)FKFgB#bxXX=J@XW}m-zNovb8`K@uUDe&(xP}7KM|H<_$B{a- zWQutB_B*P(iCWhQ0sPbBFN1r!m%DC|ICH*!uDT<-0~>mE=XA$6UDF-V^<>g)`T1J7 z1f#cq9pb|`S@4E|O{z_ifa<9}q(h(T+Y}AR{ha4x1@?BFss8{gum$xFtiYCG9dk9V zDt@f~F=pd#^`B#`{|ohBUCr8&>?>Qkvd2+}_PepAJNwp_L*SF|2jvrpAA!n< z2gxJJ5qLbROFW2IAo8~?g8T_{-8w^Nd1g*#_4@S8-I*<4 zUxqY3CYRZ@t~#?jvp2IZvp=&s^F-!w=6N2fv9%jvG_#BI$?)!n++oz>A%K5=W(m0G zd%1%*ICH+UT(@Q>XBsjOeLW~M6{)Puv+zjiU%>|*u@YD!_x4C=j4tvC!Czmq;a(Qo za1XKa>uWU5EM-=3mU4Z50RJ!S^H|r|&yN^}m<3yyMsq3tie^kR0Zgu!Ys8HB_0j9) z>tom5&04;G`IDECPFkO`eoaQ~`t^?B=y*2k{jzP@aI9S^bVW3!f{X5;!boX@0p zKh!BhEgk~+tJX(?yUNQQyuq3C^>clsR&#BA{QAr%k7{mfu4$&%)7??;zkd&^(>WuE z`UnfwCat@zU9;{s;&g42HbtAhC`X&F!Che==P$0!BD`sgMyoWu!HlU>zA%C}?#_tb z*pd;AaD3zLxG}`GjN|J{;1~byHD_ORe4KmUpekex&^&Q+)8wY}Fi`PYGlxhqb!z(Si*o{{;?5hiP@f(-wmd0Mz^r@n?2^+#Ftczb4pHZ4ox^_~N zv1yWc=$7;S`m_nEXm6P1uTy1B=puD0i92y7zO!621~yIWqIL0_46j7m1lYrS=kE)S zHuG!olwd8>Xrr_-vFEd#nM@m}U6K*6U8!BIU7}6XYP4Eyt~NKlTU(g9P+OdJU8~Pp zqpj68tn1e{X-#Y86i_b>^|abfZK*bf^Kj69sAEDcZxW zk0a}~r9O#F|K4^6;mQ%vY&@1Rym26-cjL*dtgo%s3~oHNapY^OH(uCyDJwZEBP(M= zO4j*}V;iq+xU=#0#>uP|8>h8$tx6lJji!Kl7f>%*8@q7=e858+N&BHrC~EOA%l~oH z#-@!Uh$ZgeOnhg#;>ZIVFX2cNUWv5SOFyqY$FMqvdL_SuHSaLK#P{IPY)shLtsRK% z)}GX!(vD~^XfJ8Uv?FUHwb#~O&x+5AS0-sE9>1%-y(s#XF-?PZdXs$J-AyWuxUrYQ z+DL@!Yp-vL)J}pAcx(!#{np*ph;$A^VU~aT!nMb>V~Bm+i8Jw?6J)> zyValT&dh`Nf;n@MQqLF={MAb@-F`Xwqk&t+d#CI3-6xuR6#O5f3}L}9?SEP~zNpq&T(+;E^0S42~ zqzC%1=1_R~AZp%2 z&HS}toX?!TyZWV%)rE5bNd@B6cd1 z5G#2+!{eLtaHmNoS8hjsiV}C6WU)MdC*{b)d42}ZnJ+(wI*;*qgZu!}-^RKfaHbsL zUliaYUZi~CJ<5@#@R~AS^D)Jbk$+kFCDge}JZHKT5#T?nh)2yUGTc$dnsL;TU64&7 zUaoK>zAL|n{I?V}h&_~+l~KO@g5vvFTN6TQVVYumbCmMsJZBZf%3g{UxfIKO%lUkr zb2y-IqNY;u=ZOE3O6Tb)mM8L>F|z-ObOc|8lFid{#cgodA^STVWxrBH=|gf{Daw8$ zJB*`e%V8x!L$Rz+PFH~2sJ?Qw40oPo|4cEs?LjP;<36MKw{mb0$7KHtaT(>v{tACW z35p(yWpD7fPacf)a!Sv5Z~_mj(H%bV$_!)^6L`)frLhWuN;7%sGM=8Mv`o%x^818h z3{NlMrN88Ro#Z)5JbsGDtEX4OTkhfi3PJcIzngfE*Z(f(tfM*%|Hh#75T%7*^3q3m zzKNb)lcg~YB>4@ldj;75-jOQ^DO5+6G~I?6qa`@}a2o#w$#N*InBt|~R8y9V=gFXl z=~bwM|24rUpL4@7ihMK0SVe+Z{v@wIZwBx2nc2>dJHYFtPM_eVRDT}j;ElmgQ0z;G z@f;mEJ4LeNS{`2!-$(i;Pb(=F?(p;=&;JLW6UyUXi|>KM|B(FwbwVgd)-8jy;xtdo zdHo_PmC41c$dBPU3#e55CG9KL@tOlXCzr=7gkI#Q^7MS+J4iRs$`J7daRK7h;+GMB zON7iqiirQ5#b*Wd3v}-th-G3Nha@Z+x5;4(!vzQ3mQyq9=RF^|)E{IJY{y*A7K2{nThAK+Nsid&SHp`}{IMS;yhY7OXlol^?&JA3XS13m);5pCmqdX@M0*74r z!>Fm1{SkY0(b_f)Ngl-EzL^4PoNW}LXN~xBnvt`{m(HhBtjnVq$HmNI;PC{-cx%J| zVej4Je5%_2|F!n%{oZ?KuZ@|6B&WtPXL1TLA%{tlnl#jWL`n}-UM|^#>`$UipdT-k^9cC`VT>tby+p=$)J5NtY)7Jo zNVA?Y_Rk= zo?uahdxhstQ!Y!kLHE*g!X#M z8%dU8&7^#%P@fRmXN2Bi>emUaUDOYy%zf>TM0OMUXBhh>xlHIC5;}b;ucpkp#m0#o zW8JJo{S$fKB6{l%p-nnGcKcWE`@E`7Wm{Qm znPvsa^RCZ`Y?UH2h0a^#cJfxC-J3GYve`=3QEGA+n=Xv84P%QbvrTN$-6|Td4^y6^ z%wx9`N6J?6dDi@j5*tsn70l+-`=P_yx@=o( zAoWHVn<8||3hfuje^B$dFm{>Hs!B~qp*@kLjo9~#>>d)+yt-4LoG*0S2<;8zLh6r_Cx!Zi(5get z3Zb1Z^u`I@cH|nNQ;YK3l(z}(1C&$AkH~L@v4NDAkO_H+$o6b%dQr}yT#E7+LTfqY z(?UIr>>~7--svH-wMA%0lxI>tM7||-*HM0eWPR+h)R$pPwi7z^IUZ|bZxD?>C$t(c zmSCqCH;jn`Y~EF#MZV{G$S6_G8<_5tQLgiQ4I`IHw+8n=ze?(-ts z`663s-1jx|PNB1n`ZuXzOWGe&pCz<&DYJd-)69)WZC%au^+>jo{(&-m1s1xnuXU1S z``epD_F4*^r-UwB-eKE1&8cb6SVK8aXn#UYf66_{Q$qI+p~w1L7mKVvXY7~MGv}Bi zvipqCxs7B^+&z@v5ZWh%?rJh|_NOy8(SKOFb(ksNqn>BP?n@1Ok;`-8mKBY~x>?7V zvMDtcnerWSC%KGz9-~Fuu`;RQ(OJydSuYwlE_4FQ?AtE;wzHY(s|oGKlvj|INVbDD zg7P@BGr2(ML| z)@jkiYLK^*tedk?WT%bLP1IpKUL~sZ6;MW4{ntKOwT$ zlKpd!(54@@mWyolkXWlF*@Bu2gw6_~?k9TvD`nQ%<9OuMV#-86i6}qB9Oeq`L)7F5 zZKko#F_!1r-y-_>anZzGp_lM!Ex2!@HQ29WO+@4VNIiS0l_<9~_u{d8Sxj@g(Ah{* z@6$)c*@xqv=wp+GnrW<>tRef4wOjNy+uUg{vd5n3Iozv)&|yAK3T1i&`&Y_EID0xz-PYA6#)T|KN`9g1;&}~Pq5jwRfzfF0Y&^|ypmHdeORu~&d zc?p@2hlp&?rluF=9Ll9Ae<8G%Q$8)!!^kc|kLjHrB3oO8c0_q5EBo!dy(#N9*r4WWHP=&mLc zXKgxT6X%_!TZftQJ?h!Qc3*0E_FcBETUIm{>t-Ee%BIv*WXgBQo#Zm=d5jkOyp>4} zkIrJw&U(?faiJ4XW}kG~C!Niru^S7m6=WrnEntnHJdW&4E)Y8TB_!$c zmMv*B2YbF~tRp0k-C~cmSrg|0?v-dOi!xirIxTXn26-#VS~&|vcG?KtMCscpGo{00 zx4&bWF=V10DpPJG)K3Vl9%M_h1$lu`_alELSqF>f*LsL)<_hhECSg-NBR*|2eq3VX zuFy+(4CZVn>d&(uYa+4kkId&bp~aL|Y3`N9*xQB9Mq!-&D(;CKn=I7STQxXFLL%!!~WpLMD{ded9IyYk?kGS z(1$qXMRv+i!=Zw3jmWRUyWRUy*XCtp8xu7_|G#`aD)+A>+#qqIpv2bfab$ zHM@n@KB4=8(7B8HHnOihR#twT#9f9Q(d)OFvOMKeOu0a49V2&=3#lJQd6^L3n~*dg z6poczQNzA!C%#CqK{PJzrz7Q>!pc&vP;X)#+K67~3$gwPT6>sszpPNfj*zEwQ$oYo z6G~RjGevK`E*f`+!pfVqMD88nOB2wbl-g+dE{sjot)-;bZ!@=UvZ7_}ArF%ig?f{; zv-Ja>?8Ev7+kZVvoLKmXYvgA_Tr)mU}fqLi$+f>d>Z*2DSQrt3ex&@d@F>{5@DK2F%9({HA^%$V3)qVC(~NzDa#SeyCRE{Y#KvXi z(CSRqE~*ZBFqy&D8%O;>YAz$&6k@I3TE_m+l59%WX3DHYKHT?ww)`9(%VAlEv?dC5 zRY{{x2yHy8gC5nEX{t&7>I25^Vm=kAIm2?#mr~TXLYMu@`kDGH@)+xo$ut|JKU;G| zua}X(OKy4z^Q=SpDe@HAiaf!TvzS{M$p>q*(&yI~J_A-HH%LmWE7NZmVr5^>R0cI` z8QYTiY-c{SN_#BR@ZOnTC3n-T`+3yeqz~XtZ^@yP5MOu{dAm@}FT4dZk5qpuEs3wW zL2q}Gy%hVQZpOVjlX>i8sZwW`_Uq=020pndco}2qubf2x&lHVjO*Flbl`9&xfn3f! z=ZF{5?41jFS5ZZIN*WALzD7T!@O8AyI)6^8|JYoC*Sy>osAavdp zdUJ*D898d?54tNvW9<_^W3?2*zoA^*y?|bAWt%jh6;u>Dcd-tfn>id=+*y*+p2FUH z5&P0I?zKl_tg$Wn7WOw?RZ{A@EHRhdBYE13X|$%Lz#SFsRAD{W z%bh7}zSj<{NFF1%kbQ)9Wy*Vm+9yAzW*(U(v>zlbYI4YyWCl4yXz!++OJ(x}Qm#n3rO5iA$m$GvLTFD(q$m3@&D-Q!vaZ|_)2A5wGc_NRzmo^4UlyBzviihu z)OKZ&ZHt;Ml#j4h%OuunkR;M*Uu1nD=_mJ+G+US^lZ<=4q;$`LK2Ek2ja7%t5RLkl z$MP+n%95j&lzkX`4cUj949YDjU*h4c*_{(dK}~CKAxin3X)fclD1ALS*At}X_E{cd zrqmF3!FbJ8X_<5FTd z_j_pSy10Le^9YT-m!+KM5lv-(v)Fov7DaVr<)E`en$&vm-zC=FA*d~-KO3PdQ*q)WB`JVlAFVl2z4k5M!b58YY$+=@} zJF*;GV2M!uCbUlT>`Y;veUg;c80l<8?3c{*Uhefib9kTf+s=B_a4t(PM;>Qv7nYkX zR2wLdAnP)>q0D~}*@}CeqI{V99%s%^Q_iEEPLzGEmaN0gUOwc8l;`m*bYMzH`oAuu zd{F4F;Sr5-Cn5bBX@AER*%?cHTejOVGS0JhMriM5kNsJCEaVy3_h)*EGCX$`scDd~ zVzLi&SWh{VY05|%eK3}T94gZ;_HeH(_MDbXKZABRk7Z?1&Y->lnUS!&SQ(UFM{>3w zl$7=q)~Y{qJDniQ&1DVyu-rV6^>)@IGqwlvTDDjYW9!B$BF~D9twYWbJ?=Egk)CEg zxlH-7R~`HIlJxo>)(}q;L%u`W)~YYzP+Am8x+b^>P=6iXFJw|3Q{|w40-V~&Nlxg~L-%pwI zRqS1*<+%&pnXOSxsK1budWXpB1ZAJBDrM;@?jDrV(!CeuD%P_fbB>D!wSwog-exK9 zI!{0zC|~$0+QH{=9+XkoJ|c8>knd8nSBS5K32O?iIN3+&tP|REgkHYTokXS!ol;~s zVQiVuo+I-Xd$-t#y;x+YoAfSx-wLwMmk|NEAy!Wnz1NQEk1%Bgvc1qcOuZ$l zx;64|QawMT5a#JZK3W{wc^nS)5r^Jv{7x#8F) z&3vIVkSUw6K1)Tm8hGUpJA|?8l9W=Ok=|(kD!$!m!S>w27C0;WqE#j59!x*XU5+#r zm`}F!H0M$|I%|)_qJ2gqJ?A#gO!mW#F0R32%h;+Xcq|K~$2v-$Uh^vO7~hZ*-3czd zoHImna~8`py3T`q!fk_l6mphZ1}u;??jmnC|>N_QF4XRMZw(e)LuiIHdX{W5=a6yny+ak=&dE z2(8$m+v48tmvwr`?-n6!`Eo2|M?G*%(^TF%&V)HIj=W*=pqA5mV- z+%6T_sX$BI<=&0f_+B(t9@)lSioGnMJ|=WNlr!ZmFUA&MOUY z*Kw@bETf6Tv)~_*{QZiOKHiw+-YsqAj-zM(hcKQ=e>GZUuZ9qQ4|#eINLgMFmbFmy zK1UP3qO?i8G23u0bDJ$^#F@=w=_Z8#Nq7mAYtw@4$~-R>MDMm``WCeJJ7t{Ji-hR6 zn;?H9*8<*V>8svmDFs)xsEISxs|)sY-UpY8Z10q_i6{J##@WbT_Ya<_$K{NBv)SA8 zr8V%}zSQJyq0X1|R=(Q+d({`4b-U9No3QUK5sfuWp5B3VBPE{m2kpu-!a6rQS%_W6 zb;ye3v7&!LvqfaPGUYuYYoD?6$SlS_Nb>1-+hWQbYAmidW>AyC^jj#;VC-&ca>-0G z&e&YCC0S9Zn=!VftUstTBHL4_>BBTxTuWKYlrzXvjQv@tKPG?Y+Qkv-8&Gp0d5SsI zA+I4X5!#(8w^CDx)lNP2Zf_O<3wpC!cm0?=bU93>(a#9ormGKqyoawx|%Texoq z8J9Gg>z39bmfn|~z?4@~zKSeEo)Ox$8QX=LZ02x~nyDh&)2Z(%8eJ$BU7Ihk@lp?;cjoMrW6%JZrJg?x#8kZGDwuE;c%D1R@q-pkkylv7!^b|l+bFQMF) zdz}_y1y4AVdwogX%YBD1&mkh?ObNf@zHgJq$+dF6u!e?M&6dXszsPx9VV)tfHI#V{ zB3qG%x$o0LD^-pZU#Wqt^T~vb+{}~>$$3JR!<-9+?ixwy@=gt8^uRItNpG&~<=!T-&S;jknrYgJ22Y#F*{mjnRYGI!WXcC*FS`dd`^Y}h zlA5+0+b6M_{lPlUJQLQ}nMd@V5O+W%&$>eUWy!&QnJJeQ$<^7hqKCnjWQJ(q4;O&j zh3Z@8|EbWrO7?R3Hk0m5O*PghSI(Di#w+*=% zvB!NmgTEv+esj^p`-9)b5sQ?VNvflXedAbNL=LCHi{jEIsS=Ac2ax7>c{)q|Ak?Lq zTgCWZXnvOTsDqp%n`wUcD~KFxK#hzzcI+_O5^SHW?G)^FT2iV{;%6CK2J%RzqR@Y|&E8y9&%Zn^r%~?4v+py?nsaw%Vse@1*#W&tXeigh(e(eqNH1bBFf*!L4lmhk_o_iZy zB-DAL2cd_z#EeVVrG9)-0Qr-ms^Ivd8k8%8ms5_4T2q!ZmluVSXCZn!^2ZUuI@*Kn z$n0~l2t7`SG@>7u)PE(Ka~*M9`Eu+a>I3cqGbD|b!B)zUeXWdh?~{y`z4SWPZCzoW z$joyc%UX91IpZjhC-^4$95|Gkq0|gL2aT6jR7WWH@4PgY(ueim&ZEobk@9@$Y-tS~ z9ooVBT=t5!mAx=0MEjtgh_&Xi#qua0qyAVCu4=7&SneqvQ7hItkEP_X&f8h%?UYZQ z!}YB7s-(AVNofyf`cewHBhCQ7iP8k7chy_%TrI^fcwu zBIA2>I2US2VG;DFsIN=S8L5xjMR`|JjzjZyq2#=TN3o;`8hyHGwCLHw4GQy7`Y;~L zuyem6c4kp?#4ak#fj*~5+SZmU6g5rW=YpIKc}G&7NDWd#eZo@SWn6nAWjRgV5)~S(BnR}`rW%0{6VNobFYd*^)qw+U2?{Bklw%*tF+yk zVEbf!h9l)^*5niJ^%YkvZEqk`!Y|?84Jm8U@OT#prJj(*XP${I2X}dBd9^FHM(EC? z{1o+)epd`7TCMC)gl=c#JYIg(O^dT9WM`=ZSB}+VV&+TiO{% zB=5TBxv*bQ&PZOYE%>JOfsiR5X3962@=d0ElPTYnl-7OHl6t$-3e0xyrrZLoOS!Hq z9;~jjnX$b{q(rMq%4|ncW=o!ENu-4SD2bHF8FjGklPh0cS7hWv*=a_(5SDvH#wM(C zNSoj9oCJSy28b-}tbcK(f8Nj5_{Ez*jf~*;dojv$DE}z3yk(E0*a)6-&}VSRLHY)M z=|N=nz*BPGt;e0(q?DEC-o=!{JV!>N?H+odZs<$~f48TD4>_H{!Ool5tCiGNf8vPE z`eZBb8)#O=U_1H~SI*-n?nH?dLVk=g2pMM$dO3HWxUetCVr8E=Ux+M38!m&UF7vD# zJ13gNU8>kGBFB#-_H(BznC;vyWV_|XrEg@%9s%>>|3J#qw5ijgSEog9E^O=zKoA&(;ip|^|j8`x_VdvcMiY3NnXB5=A3 zJJr*j@4(l&Dl*-Z8on;;je3}9Q+BXnK_ zcRJ^h_XzQ>zvL{MwM@B_HQ9;Z7?G6wnMRIur+gg(>_AN-pY0+$S5ZHldIwx<3v=b| zX8hh{eIbt`*M5SsSW2$_K4V`;I}hg?QCT^5Yhr9Q>?M_SxFXk%?8CM9y_Dn59;Cd6 z>?7laK2CX$5Nk~mYm?{8N*BBn(%?H4Eg_fVy`gqO_+e0wAnQ`IpIk1){SJxkLd|@> zGkZq9pOE}M>sEQz4zm{!W1`4YNk?e4q|a%`tDCv!=0VfPZ3J%NSezlUeSm9&Ejdaa z^rR&Z7WPD%Wn#a2gq%C;@L3s;K4!lfA-0J*3HpGw%sm6<%4n{e$$b_zTHe^z<6P;V z?Ia)Fg>2{iir681+9!@@1|`i9@RWm582+|0V)t{lFpm5l&xgu&wA5ripRQRVwC zj^uMt_6m{hCXCG>UlbNTLoTMKx=>$80+9K<8QKUkuBL>1-l^zQk+GI18js|YNQHb3 z4cB0z|5d0K39U?FAxkf;O?epEMtJTpWj>pVBaxIxsOMhiDpH<7=8$}r>>Qu?I>)EN z&Xu8lk5IKH8cDW4{{P-9WvDb(AAc-lWbKyDJ%L>G{kazFUDb`bu&H$z#Fwzvzw7x{mTU<_vRW6P)$(6E)PM4NA-ei!%R6T%it*EcbT=gFJNE0UD_ z8&l3EpA*__PwNylrNLs;3oXys7sv<6dl~yC<=8q&LXP0s%lCkPXk@4H$!mr5%!lIdEGinBsndBT{(G<$Lk+YMs^!e_T#|iPfzmoowBqf$MrFo?KR;Ij_mckOPR-(bLZ-Ey5 zn9W{fv+rTOZYlEIB(W+YKOp1e!@{Cxgqr25Bh<6!s2eE{BNvm~ghd;KdWO)Zz1WXX z=9$9pKtXR=)VwRysbo)bjL@NV*#8vS`jGrWXrCZY3-vXWza)8#_+F2sXK!(?7TIac z*gYiAowbT-nhG_K%bGzL*t@+Fd9sOT%oZOLQ8B0lq6bT8$%$e$T|l>C7j9%Iq(lnbe6nzNr!^EfqZXMAs8 z@}#}186ux!AJc0@)=kLz!lG}4svAkWC}a;)Gw53&_^wK%p*8c@DXo%q15J zF(SymC&*FcJRz)4SV;)GlQcQxe)4&8JvoG2BZLh~%B|!{p;duLv7cmnT09D?jA$%F zvcKu`L{8LSA4{sN)yNM0cTllXcR^hGaF&lbS^UUFMb^1RzOitM(d=4qkBGwxhZ4f~9Jm&jHfp?;NQE9sDO zq6Nl_tY|OlJ<6<=dW&gZCs&Xog*NxHJZdJ9^Mux6#s-wzlby-#)KjBr9rmTv)ALwt zZJVuavu-y1q&16=mYJQls~4PJ>R;8^5@j=B|oI*9`Y;lTk4s{x|8xu zlI>=Xpj<=fu*IB;l+PF9>tk~49jO5ze?-ow<~p*s(4ytq^e_&4o#QYi>ws^cA&ura z!qo+2T;mD3my_rrJ(&JQlD*DO7ukA^8umb)I2QJBJCm^qe@kDAFR4lT#bg_D6v-p9 zs!?7pRKE*#Te2(3{$M>unO+xfgh`s8g!V|XoX|Q;Zl;DkNB52#YoX0pry=D; zny*F18i8;RS(j`{vKKjPDYO5$Y{?kQ!c`*natAP$ecrxVWc=!+umWk5%Y>RoZQVxA zQu0xu^%TkTZeK}#1~tcp4*QsWn3{(eYlN6-z)$MO$faZ_QoJ%&ZYh^1A0{s&XOkC` z-N`(19GO9O5Ml-*`CmYeAnE^g8_E}wgUMUTr%Bu1gwoG&tsu{9haBELw-85>e=Zky z96AW~NLNqd?kHBP@ha`cc!dRy+GF_rbFxq~K*)`v&sj%sAJ95rV2 zaI52}$)m#krL0O)AIJR9 zsJf~ZzF&5gYOJaz^}Z^H`P(J9LT-;yrirSCdf*>QmS5ERQ;t-5Rb4ez9aJZL30J9} zsxN+7D+j;9bCVja#{WB=Ruld$N2-FlST$3bseheDHpbXe>gs=Q%kRYfSGvi?{c_~#&fnN$6t6(Wibs?^<%c$mfd#Q`M9&eFes|H}S9*X(tD0Q=%TC9ZIi^@zJ>-EQxi=2CkC4a6Q{)+;qezcTCCiZI$Vz0!up39?Cw$08 zWOK3&nMrmTHg3>hrw7@W972x1arBK7oJr&~at=9<%p(`wIDSm7vlP`C) zIdA+eW5;`W~6=3VdB@K&~_`jq4?t2WLRrdQ+!f(-1^Pj@=;Yqr{FL#5t&4LH* z0ngMEKCKtLMsN7HKJXxY;olFQ#yJgbHBt#Vzky#D`R{09jFDN*e-3M4?3DQb6sGb=S>!i@LZ* z8(`Fx8Rh>())+tKNG@Rd@(3@K@g4gnWQ^*F#pw0l(8B0k4>A8K)ToE-SCTgB*a#!N zoUOl;G-eF4|Nl?u4`!(@Orlu7F;2l16l#yCMgXTalcHBPY>ZuBND8 z@ga}0Izuk+nlG@HS!=DW*1OgL ze1E#oHg+Yu9)8(9%g(k(+tcg?_A+~|y%oPDf51Lw7di&NQ(w<%<7DAE^U=;UJSV@* zS?g?d-gOQ*$DBfZ3B8hA&u!yox!LY$cbdBZZ*Hu0x4K7T>9Okgl2>M|S8PaZLTpZK zVJttkA+{s7H+DF_FaCY}jK9nO)ISpR4~_+eDJG>-O1+deDOvcv?9nOHQWm5vOIe$; zHRauu11ZN+3R6vLrPO+4NtH6A#P*UB+lxzVOT3RZ4&Xbr^6)!1 z&m_b3#Ztl#lxqFg?b5wVY!Bmhv7AaLb1J>5SV~xX=_7yLF8k?Uw<~PJwx2vE)Tq+B zziwZYUMxLoc2QP|?Yl~(&;RRo zx2j!YyJoR%)W20miS2g9wq^f;#kO($t+I=4OZ=1)+Y3r;uPCv-vBdW7659t#Y@ht= zc5AQ1c7y=L?Go+RPWouE z_P@MkiEZhl#p82IY)>q)J+H*}vJ%^3oyGIpSz>!%iS1*5-EMD{*e+XQyF~wK-=;)- zaeF}fwjWj^zC{0MFa6_BKZW*eFa4wV_8M+Gm}`{97%9(Uq1Uxvn+#Xs)M)_aROiJ$HS$%lrE<$ zC-Uh~H5oQYhV7DJk7SsW3`Zx!smTye21tE6EJ=oIlHrzQ_;xZpkPN?1hNlx@rg&@Y zpII&$CXY9>S#lfC3NXHJG8~Z%CndwXlHuZHm@GdtS$^i8r2Y`vsaP+$V#{A!{ff;c zwxt&pJ1bX+)fC(ASlsiX{+%}bHNI1c^qtQ9HNJPjU$?Ilt0uV*p`i{~wNv;(Ra+lJ>DknkKS7`dzC`l1PDlbN_aleL~9{6%=wZ9wu24@kD~fbSD| z4>+9&v%O@Po(!ud!{o7NCyzb5TT@0_KQt#Cu@ z#2z{UM7`qd(_J zu#BO(#aamym!UV6h?hB5vGl_#l-L%3UMzliJOK zE3sYNvmkzS_Fv;i?}S&erMIz@8Wk=?fmY3mTK=`?_aMn{eFHwb%j5`AE-L| zgZ&Yzi=XS~sviD0f1JA7pXyIlJ^dN}e07b#z+a#S`gwky8stCVKcI5_h5kY{*k9x? zQbYX3{v&Fr|ERxI4fmJ%kEOuc2|0}i7|JwgrJ>-Amf1?)p|MLH(9`?WUzf+6-AN(KG zBmR&6k7|j3+&``!^?&kzQcL}x{h!ri{xANoYMFo9KdqMgXZ%0Z6aKj%u2u#?VAOL# z^`N@i5M%@y>V=?YP)ltL8U?M?rl3vGR&5V158A68L9gI?wKEtOj8kt16M_lqonT@x zQN0^X3MQ%df+@iiwI`SwOjYj((}HR0gJ4E5Q+*iB4(6zjg1N!n>XYD}V7~f1xG%_4 zUjz>Z3)Ppw!@&qq3m#Kn2g`%y>Ts|!SgF1V3W5UlZLm66t^O6P3D&41 z!85@#>bqcVuvUE^tPB33eh4-M8`Y1&KZDKcL`rH(1$EL?HdSyVzq+ZeZIfX#v}0OO&`lg|dnZ~BE4op+iRHv9r&80fkv@k7nXj+@r+L*ScosLWglc`IaPNuU? zGhIzLeV)0>^w8&za zNmnyd%oJVSOf^&W#b%nBrZdb8Geg%fv&<}A)66k*bS*R2%+)Gnzd%FzTEu7{6n`l&zt9U2lIk?L1&s5&5Qa9 z^H1|n-O;>cUecY+%jRX>*}P(2(N~&R&8xbLdCk10yPDU{>$;nH!@Qxpn>WonI?KFg z_ULQOhvq|lt@+4&qT!5OdO;)I-fFb4m|0 zznWk5aC6$6)+5Xrb4K52&YH9OrbtD$9vQh&pvOe1QL4TrGLg{}qf${ReQQ)EDx)Vw z=~23#9F>jE*HfYj(FJ;HR4KYhPm8KX7wZ{O&FB(6Cu$Hi)bpYyQByrXY93v#7etxS z6?$>hIl59WiMmDI_0lLO8mX5>i=%wKIx2{s*DpjbL|gQ0^lmkAXAZvt2~X7kV`ewZ z*2ZGA+<@8H9(7VX@Kc^jH95-i8<`uyX$cLyq-cgwqv2IYLYkh88_KxhjN|@+q-$hk zpJ^!7G5Bp=q>f=7vMgo^Re5)#-&cnIB5=8zIi|>mrTv$D^FMKMnQtQTkx4 z!^-NmjAw~sl6)Hm(kAtw)!0{K#v$=ORxK*1%D6_7-$QPWnQ&(5B^WtAE&V9?S?Q(V zzS56@pO;<+?l1i~_(kdE;DORlfM1qg0Unfm0~t$X)vYclbn?j(Lv8d?zuc z;2dF}Pq3H5Xml-F0eh!Qy8m5UM_GCU-ZMNIe>1+zRFCiWt@s-zBmOHqLT!vl@5euc zKWG5I5t@eZ2~FV(TA0=tnf?VU?`5v_uZNvqAOG28$A63e0t=tzcStd?yO;g0es|dS zeJPQ7&mRX%`P?7ok1(svSbwHJ+rPuVQ+$Ab53GMGtbPXUe6Ih9ztn%+U*WIvSDQR@ zzj?qsXcn4>%p&t}N~x66DP>a9Qqoh-ODSs>!wW2h^)ELo{MTXg1?EZflv!h*hUGsG zTYnKY{t~SERao=uu;Mq(Zu6FT+q`4;z=A*W|1kT_7v_NZ(i}8jnM3C506&*wz70|X z14}*@)C$@L*W!m_uZJz4gbn`++dX5>1~Y>>uvr~hksZtr@`8o1T`!77@yL$?Sg?WR zmI?lma(+s=C_SZusbbohOw-wPGd-g7qYI*oqH58_QLU&>bV<}OY8thOT1A&dZKKPh zE21l-?rAE`O-o6O($dn-PrD%PqO@vh7pK)otCb#04=|l5lb)U~zf(RR^MRjmer4R( z9QP}5#IMc~|6+{z?NtUx{2CnbYhlFiqH6nD81d_Htgp+l{t}G!Lsdh6xIbJq;fUXq zV|_D>^)oPwnB~t>&HXw49Ly!=`g1XtxXYi1xx{?T1ln*W(3UfScAN=Z&Y3`a&ICGO zCa@UuibwrNF|SzWFT=dz3I7Sz2{VCw)fqE^C)Jgl33TC1pf6_v{Wufo&zZmg%mj9* zY|aD*awd?&nZRJq1cq=XFqAWa5u6F!$eF-RoC%ENOdyvtfl-_ZjOI*W3}*skITN^< zGl6lO35@4VU;<|Xw{Rvfku!lwm#MEre2U66WAPhn^m$QO9IV-pe zvx1uHZp;VTsCk$P^iuc84==0vL7$+Hx|g$p1)LS!$5}xhX9f3jR`3941rKsoun@C? z8R{X-3TCTCoE1EbS;0N(QOpYNQ%f-`cu+mYS-~>S3LfXI0CNJ&3ZCGsU*C3 z=d55AX9WeE6+DSq!8)~?vx28m%BPf9&tN`KSv`v}y{%e{F};I&4r6*JwGLx?SM?8! z=~t=s7=6mB=P~+JP#ZA%R8lWs^r@;gM%AP0>P3t}HPxo5c2ryaGpZZaRhuy$HBc{M zJZhr0U_5HBUXEHuE!Ebjb<|qD619oisBKZZsGWKh<5Z^Fj&Z89dJW@LH?cBaMC;_8jG)U;H!E3H&oDfMPrdRn^LomMWboO&y*Vp>J@c3S1M%Icl8>S@*0 zyJ;C|8S1^XnrSuFo^&VOQSYbw>Aw0P9d1K?h=DXxdyzq!`Y8Rp^z*RlVCm}WKJ%%$ z*wiq!OdV6#Tw>~(My82rW}2H;rcM0o__y)z;zvzyzpd$G`kDb|pc&-1GPBLSX1&>J z4x7n-jz8LrGq;-C%Me^O$+uJYn+vH~h=|xBPeg z_x-)*S+mY;FdNM#v)ODh+st;e!|XJ>f*XQ?!Jr_=ylXx%d(Fq@GxLo(V!k&&n&Uwo zvpMKzelkCsU(9djck_oiX9`VG4U%10MQRiYYE{itztY1AR=6m^ZRO4Dhvv>?r-l}Rg`Rw1oYTGezfJxnhR ze={lRZ&LkK_#5LJjCQ4bj7WZYc%V2uP)$|JuZ`=E^XZ4m(+^dkAG*Nrh%1kZ^g|cY z4^^TEy2u}htBuO^I#uX(s`~TbU8>Q$RHt{jnBFCW-lYb;OHF#0TJ$cp>0Rp3yVRw3 zxrE-O9=%I_|DU+dXh84Mklv*cy-Qd^d)11jkvzZ>5Z{~*3M{!#qn_*bT-xh#Gt{!RQy{D=6D@niAh@e`(>xgmbajPWn`GyP8f zm3}wBzdy(yWo|YT{d@iU{QLa}{fGRA{U!cm{&Ih%U*JFGZ}zwNTm5bRcC*so>9_WG z`|tRB{144D<~iI&+~@E25BLZDL;hj^TmOjvy?@j{=AZCS`lrnM{%`*8{@K7c|1#eN zrGkrt8bNLUK+rcBAKVh$8cYsu3vLgl2eX1Zf_cHc!TrHQ!Q$Z2U|H})kRLo5JQX}0 zJR3Y0tPfr^Rn6t*3Uj6DZmy2XMHQpUQASiRY7{k#+D9FuE>TvRo#v(aX<=IFwDZ!+ zr(Kv{~+3b4()$1?SBaEe<pOj`Cnv&*RF< z!ulLn?{H0nX9{s$Gh4a1wz)%j{+<4vDu$VUEfvRXzYeYjWhJl-{>u|lQl_ju>S%uS zFy#NUoHVY{Wi_%o=&3UP%_z04-^d>y{~5CFx5a9q#H0sgf=&33rEBbY0et4iSiSrz{uRpI>~BUcTl_7k z&sKjcT49^NO~w4}{&p3I54%|T@MASp0G~Bar35bqFJe`pk!hqt%($8;gIQNI6=CMp zT$RGC=@C^LGp9#Y8O)v@Q)!q%J+9I*i+Vzxhq=&?s;oI~j;r${CvsG|=)CAWRUY20 zimCv=)=5=_Z|jN`4O}5(<@6WS@;9uXYOa}DxIXQQ8sFpJgJbmq4`()x^*%2!SnrGB z%I`YV_=VsF<;&Ht3R0q!^HJB%rZdX!X1by59;OG%wjv8`S6cP}nOP+JAfZ&|xM)&ZXpZ9-IuhbwF^^)4fSv#M#3sAfBRSK>%tElr?yK<~udDgB1 zYj*)_SCO^5khQDC+FkT#?JTT*^NeCGL){kN9e)dL^=|xK^pR8XQ)s2YPr-RT-!F$V zTFXa|_UmD_!}lBd4OM^<@p6@dQSl0uicztfGJdw7ts;z$IhYmR>feeUIvwjLX}FTS z1MAdx`FE?b7%}ftRVX#e#d`T)yLTSKCWgD`Uh2GjHut@n)Zl)L^Y-5HuF#Ur*KXC zoBtcGY0n0ZYJqFHK(!Al1Qk?=ph{3hWd_xPYU&F1)Q;?_or2my9o0GL5%f@9a7A~W z>KgP5`l;?g4*Wn?FeVtIuELl+UiHAZe2cmoWAm+;$4w3kMw>;Y0{j|3SaAmSZJ%}rl z9cm%2PIjt?a9#4QT7)Z;z3O3HJAI}WV>RWlT7s3(@6}3L=4x8zQ@Bp~Nv*-P%FpU) zT(A6stIglcZ@Ak0-TaQL%|FZ^xY{g&1+BxiN{DMq{KK_nxu`s@Eh|PB;;OPLENe67 zEA??D*(hp^Ysh9%D_lLck22i|3}kh0m_H1@egy7yXsp0orYx+&w1q`*mCZSWw-)9m zts-$JC_T0Sx^e&3S?V3k9p8ne?1}GzU;QBd0q)$0H}v2QzsBOsH}P+Ax8_LvJ7qAB zJfTX_n#y9%`G-26_irlrRs1UG?Q+lNLcf)NnYxIhPgUAfHP}?9s*c%aCv`DqoL6E^ zN9?NxW}f|3P1;v2f0REOYdZJ(_reOqrs~nA>SH$gAg+EM@*jdlh3`_& z#rn>t{-;>k+2`-W%Fcd&KkgwN@DHf2w8w6kjYrSI<(DVY7E&-ABf%+c3vopr&G; z{eYT=x%MJ8gSI@2wmb*(?#Hnn^hB^i-9@{ehdKC@Sp5;}zL(a$0Q2!@)qR+gKd16I zf4HCH--En2vyhg)2=~eOdqu#s~G*%^H|9kpk6RHz;A3cW6T)! zPh884Q=831bF127CY#A>D^@gaQ?JmIY@;W66{{OF)pq)m*RalUhuQ(JvOv8~@9_@3 z$Gh|%@6mhg;b{H7S!wds2e|HeR_!&Il|l zzEMYU_4K_uMvruo9_eR#q*L@r@JH}SztSVgO3Lr*G(FPqSWzibXE>`khgFmmRY>nt zB;EjdkUuj4DmG)%*q2sv1s-Xk%S~^v{mNxKOm+DgDwR9Po zo#=F#o#?VrR&CC*N0ck{U43}GT!?f?*sayRF3x{{gL5# zUy9>>X^!`0INqnzHpt&XFuPT*KRk)!ynw7to+y(zT1+c=6((N`r#Xs0!%=)KNAYzW#n*Eb-@s9PBS-Nq9L2YC6n}-I__n_tp)EZ3 zAoEYf`KM-&!+k`|Fm2A|9M0uj&gDGL++v)k#W|<)IY$aOPe|oFA>=&4aGp?_^Mo>- zC!}F6AoF6m;=%n<$hgY~oxEeBbdJWIHg}XeiZh1NR;HDS%eanKCp_Pg{lu8m!%8pis^`l}|fUxjbXm`D#KOYc7_Gs zYe>Dy+kveDq<)>@N^d8_eD4j0tGrzd3%oaxx}Zdh{C7{A{-+k%jeJ(%?=6Nay|)?W zd+#t@<-NSh~Y}_V}|+OCk$74pE4}K zm+7QM_F+p}Fc|{Bh@aWtByhV1Xx7A*Japkc39$$z#qb(i8@HPTUS%Fs$ zBwQK8^#a2Dn8R>Y%w<>*^Q1*$F>I|w7-zULhBY8;=f?tut70h(3u39#BC!x#Xpxv< zxH1+o%#W2~xGGkfVL_}6Qs>9gu!Z)Cr88U^JC9+0tSrL<{7wUo6mP7vU1H@Ju8fsu zm>;Xaa8>LAhJR-@#rw#AwaC$bx5$OaL0Y5|!YThb!c z8Lo_7%rHNe!EjZq2Ezh;p;KC<7Ph2CYBO9JtHUrqR+r(b*d+`LV)fV}^|2)_(tzR0 zSVM;Su|^D6#Tqj#h&4fK`QBopWtuTu8M~BWeylmeRq*s0$5kLBfPMfzK2?pz5D>>` zAa5@>fZxr;bIpC?Im&T{IOD92ajdRU>J%SBX*_g8lTs&qG1_s4G2QT_)G0oKlBBya zDRn|Q6|g2(56^kXb2z=#Ks>oR0Z&ce6~75-5+#jHN}b}llq82yNvTtOG^9jHW0F!Q ze1%$clJ4fD)Cu2xcAOE;5a@18N}b|(s~Wmt(BYkGN`F@)yn&vq5#BLR9y{JJha@H8 z9db&Y;&_8RStGnZPN`EIZ;K~ugm=X$b&BKN?PQJc<~F5H@fnn)Mp$7@)(F<8>tn{M z^qcsSkJcaP4{*LLv|JEh6)%WC8DAZLD!wNEbo`n4v+=cZF7bY+th-uR4@`|e5?>r& z6n{9rB>rf8Y5cMHviRfihxDb0mG?j;T{rv%c!%_AJnv&+rM7-JFT5w5AKn`-2=l@R z!Uw~J;X~n~@ZoTA_(-@Ud^B7dJ{B$u9}ky@PlPMNm0^CkDl7<}3|EIwg=@m6!)L;0 z!?oda;kxi2;rj6Ta6|Y)xG{V&+!Wpy-Y+HV&n-*|tj73iSzYS|Ya`w(OqBfpw}k&x z^M99Y#VoujX*IE$pyU^=O)R;ysuJdgBg3)b?cvODRyaGH6W$Td4etzZ3~vfYg`>kU z;mzT=aC|r+yd|6%-WpB{Cx=tQ+rp{gv~YSjBfKlT8%N-%r|_qAU5)3X^b`6?<>;sI zl|pIPE~+YW%SCRo-+z^J6UvqR$CfBT@-LQqvObff6!eECDCHHsU3q$k-iNPCTxwma zs^CsvT+Ix(rv8w6H1)^SW2whePo(~odNTFr)KjUyr2d-vTk7f5-&4<|{*ih%^;~LU zDn1Dw>d*@9&CAVU;izUL6j_Ln0T4e%Lr{9rg%og|)*PVa>2^cuCkWY!tQ&+lL*(%&=qF zCF~k@53|CaVXyG|ux~gx91>m@W`wVVO~ZO&{jfo}EvyqZ37dtNhRwqkVau>p*d}Zn zULIZ%b_zR(SBBlftHNu;-r;p&pRixpKO7hi3x|gz!U17+cte;Iz8XqvXWs}9=LuFBLg9aC3mUk9qAPSvTZvo?6n z@JhVfQ%ZHwWpo+URj2E8)eUchmQ~&H#!oqwr7P$P>MC7PS5!T8C0$8ftt;!ws;921 ztEy{sbv(1t3-69*sB3jiT~qbewRLTEoo=C9s6P4%eTBMScfzj`_tjVGD^)+;Rd-eW zb$5JiZGgT?U!}73)%t36gT4me8XKsu)z_*)`Z|4`%F);3i#&sMKiy9a(F61VHB{fA zZ&1VZAU#M8*Ms$7H9`;7_yUCJssS^rmc-vJgy(yiUq zGr&L(Om~B*hzRBYG9X|A*NBP503s@)sDLO*L6VqLSY zY0b+2R?R@8clUm~_ulXB{pn|3s_U&z)u&EXovJz=k9s13Bye#gktA~QB#9((14uGS z<`T#dGK3pQhLK@hA{jwOaD%Y!brhFGQb{T|n2aOixMcDJ`GHFz6UYQ^2$@7CaYM-z z0?QMbMy7GY$qdv*BX}R)hZ`w42~ON7$hRps>JQ}mUrV=(p;L! zb2-SfJtW!@@?H@VT?r*XU}XT(uYL86gd61B#VFzb>+%ihZfBJ4=I{bQ&_nBv{U~lU z>Vyf{>R_eWQmjGQgw2cFg{>}T|6GBL7htQ8Hr`#x_&sb5xrf-ixyRUi;4$qfWc(er z@3@cH8grkqHQ@@;7HEoolo~Q_iZ{>#>(w-nae)Y2O9BM~NyjunNV-HMNIE9hK+;Q* zQjql0q%497INw(U9~pWDF!djif=+ z$CL4p^oe95Bz-cO3`w6#rb5!Elj)H3nPes;y%FCC-cs2*3@shCq+adVo+VwsL-*(i zCY^1o!VmL^E%zeSnrmmd8|hkG?gGMlGPc(Ep;d`mosI~aa#oh;lOop7awqobdDMt8 zgy@m4B8TzjFpTpxR-oAzP@G( z-+*tZnfh%S?IG=9?Gf!!?J@0fZLao&_N4aIe@L@ayGy%UyGOfM`;&H`cE9$3_8?88 zJ*~yaD?+#y!e_K+wdb_wwHLG(wU@M)!F_W-Mh_RZ@D)%7ehuuP{n1DG<~)CPtwXpk zh=k;@DiwAg1)c;R&tQ_r!m4oyRqxCKBM4O^MO0kWI(PkDZ zCGIwc*f_QZmI8S7plig`B7Ms=HGSuz_z~%-*P}Y(XN25X7^yU{DZmQ@dJgOwcH$?n z4QM(ItPcpeXb!O$H`X>%qlT=3=WxXt2(IJ_&Ig+bt}=@A5q}l;ia&|_#Czg>@qzeI zd?Y>=pNLPz{o(=fy?9VOBpw!@iNA@@#TVjB@s;>mJR<%sz7da#$He1eu6ROxE1ncj ziKoRg;#u*WcwW39UKB5hm&GgMRWVQeS-d7*7xTp%;!W|Ecw4+9z7q??U&On(emUHQ z3GU4dl1?}@X0WG&R}fR?)509Ril%6L!J`p+8k4YDadWW_SBKnAN2;~lI^^+YY&Mwv zza9Qj_F^jwKZ{2oF|W8coIR;W>T!-_7MaC4kvZ_KS&_^m3%E*V7tHdwYG&8WZgI6W zL7Fa{hh~yy5?4>NSF;!Pt3DQexCTN^p%yeOkA6+{Ka$!1P8`mPwNSM64hgz~r{}p$ z&R=^~o2UI*drf;?o3Fj0y{WyWy>0o@@|Bn_E)Z9U8^mp5mY6MW7k7wj#7*LSaizFQ zTqmvo9K zGu8-LpnmeeyEz5_i(0g+-owsE+cXkuk;tq?V$E74HmpTbiYzC~Ia{)xtmjITy<{&} zhTJB%xw8C7ek5ndkLE{n<lj9#Hh`=m^zs{akW_vx?0|~yo;KY`t@+I{N3`6Woac@!Crx z7*Fnl`ofOiz;9%_4f@;iHLgc}@EGj4RHLhKtjgv_e`bt&&ztYoxW(Iw?!a219gLbhnChytG5wDeaPWOM9ff(ofPpX}@%U zrFo=#Rh(wMv_aY^ZIU)iTcjLmtF%pmO&RC8t$SFU=Ad*)IxHQLj!MU*<5I44LORLP zyw-g#PIF2+EuE3hO6R2W(go?FbV<6*(tHu=idVxuUy-g#dD73)HR-yPFWr!CO0cMM zMAV2ZylaOV-HdvV|*z!jdpirgO51*g$MnoJN+dWgEGaY%7-Q_y6hwLeP$#vy=a($Mjm)O5JO#`{1>@EAqjpXm-#&Q$6soadEi597EO~Z3F zms`lba!a|D+*)oUx0U^5s%watB#taj(@t(LcaS^E0dk<+Ne+@b%hX>W5l4#?k)}kM z79cZ1B4UWp7f9EOv$BqOmF93UV;Ir#2OEeV2VaMV7;l_46+S6S#?jVdEb5SwaW;tS z%FQyy(W?zXjD-*&bc08p?gDxpLJy$_Vj_h|P7rnqJ2|bePuRy<3WtTmoRyF(Fg*+jT&AcN*2+m^0j^x;pgdM}PV^r)IH9N+H9Yfck5dmLZ0b=xn`%k* zRB;^7x8gS=W*B~k`GEAAgkOjsX1VeCuqn};qp>`1&!-{2Jwiu$`{H=Q$08OMS9o{I z;dd3s^W+JS71TUz$ow3BA#ZpGhVy$P-W2h}_*5R@qAQSHJo*6yV-0*Cz8?)68N!Dk zp5}sBBCZwU_Tz56(8E?z;*Q}>Tg5x_RZ)*B@pg!Z4Vc&PR=iDdJWqUi$RhgmglsDj zt0zwo(+55CYeZinz6`w!^w3n~AUTd6f6@7Q?hC=Q6L&DHQJd!|3|UFCz?8ucYsigH zq=GGAEZSX!(5q7^H{`MkmWX6n6$orJ25+#&cy2N2iMo?;7x2r&&k(Oh8!!$1M_L+a z-tRBLM3dUEws;^W1HYBUj0x5@c7(-70}Bno@dPbM<$PYS3%!F4h@ibru!6LRF+u%m zkE`EAFPoq>Ptg7|a8&98P+mA8ObA06i9o5bVx>kz3An*Y!X4obrC4FFVLe`Y z4ApE!M=9ZM#`qFPLaOPVc;LOnqh&LU>AESIvWp0c{E4q=25ca7s80JT067o)Iw8E1bofXAmw37l9XrOTbIe zPB3uPt#rx->rGEzgEL;O#gQn(%>q0&-A2Q7gHz3oza7V`TLbCC^a(Bo# zj~}udGHs}nWbC2jUf(W zuv1Qh2foAPCV9upyfbDp^yG)|v!I!e^9B4Tm90vzYNP4{Z+r7pn^mV&_t2oXQ+vS2 zUSD;pdLh1Weop(I*4GWgy049x z`*YX)i$xjC@AI>W!0Lu{%&$3P@j&1Od%;U+FZ2_}!UNw9yrCyrQ>~-6fi_SZs~xY+ zg!SZ#_BrhFm0>v##;C<4jLqz~yk_|ty_D)$85e@w)u1nIgWN|xQPdn}c&Lb>GL0Mr zqSR4T7|1yoAQ*}Y1K9@y1Vd3_P#(Yl!BA8flo2pMFccLAWurfiXZZ6cuJ7V}M{ND$I|J0fM2Z zFq0Sq1Vd3_CNl;IhN8kuVGIxqMTMEl7$6vm3Nwu{Krj>)W;$blU??ig48{P#P*j+i zi~)k7s4%k_0|Y}+VP-Q12!^7<%w-G^3`K>R#~2_OiV8EIF+eaB6(*fAKrj>)W)Wk6 zU??igV#WZ$P*j*Di~)k7s4y9f0fM2ZFiRN&1Vd3_G8qE|Ls4OtF$M^RqQWd^3=j-O zg;~KEAQ*}Yvyw4DFccML6=Q&4C@Rcq#sI-kRG2l40fM2ZFl!kD1Vd3_)-eVMhN8k` zF$M^RqQYb|1_*|t!mMWu5DZ0y*}xbe7>WwBkug9p6cuI@V}M{ND$Hia0KrgHm@SL} zf}yA|Ig9~WwBk1;?n6cuJaV}M{N zD$D`K0KrgHn1hS~f}yA|hZq9{Ls4N4GX@BTqQV?u3=j-Og*nO?AQ*}YbBr-SFccN$ zIAefdC@M@YV}M{ND$EJS0KrgHn3IeFf}yA|rx*hSLs4N)GX@BTqQabE3=j-Og*nR@ zAQ*}YbB-}UFccN$JY#@hC@Rba#sI-kRG5p50fM2ZFqaqu1Vd3_E;9xQhN8k;VGIxq zMTNP_7$6vm3X{heAQ*}Y^D|?BU??igHO2tJP*j-fi~)k7s4)4A0fM2ZFgF+j1Vd3_ z?l1-jhGH>8dy!`KDQXTgRG99J0fM2ZFrkbAf}yA|Js1N7Ls4ORG6o2SqQZnR1_*|t z!t`Pc5DZ0>JFNRP*lnoYhcLU375eq#U=^h{99L$I@nJTcCd?8P!Yo1EnI&i#`pdoW z%|!yctR-wGHDS|e1mD6P;Z-yOwv8d&Sa_G62VQNkL9kFDdfS04)Cr+ZEEI$gwL+;4 zHVGCAMqDrpbwQ{L3w1?^T5Z$@8wCp?uhB1}amZEtXlN%wJ6Y%^LilkiSU~WVDE15j zJi_0E?S^39g)O{+d1E$KPcFfDx0$fOY=Z~n3$VQ0!>oZ1u(;R~M_5~0u`@2h8S$1_ zKYlR{Q%y~KOe|&zjiK+VI3|O|;2jmmEM+k`0x|S%GwD7HEh`S8b~eVLHa3P(`xajr z^)0Tv6=*mIYFT3{)T+i1YEfedwWcwIS`s0{y`o;kIko`}=Rj>}OoiId7(#7_kfA?r zOKUhBF(0|v8~@YszfbYmP{-lPAya&?4*vO5 zF~UtSx0cQVu{Yk)TpZn-w$6k;#+dmmCY{9);Aq@K$&m)spX}`u+Q*~zJ>wqc=)+dS zW4=dYSet!u4BV9(<0|vcV4{sS@uFBO9<#OiAZ+#}QORI6VH+&i1;VWhq#!O8}KHI*0bB$y&3Ud1HtMq+HH0;?~ zxO$1Ff(0-LHfziQ!1YVUdyz)CE@rr4+x8V>Pb%X)X(aQjSX0ai6z*w{&%4*5D#?V7N?(V`@vD6Q7ku~1<-k|{;kdl4( znB5DNvP866sa+1b1zr*i8uIVjsPT22Z^n>r;LOy5?!@ej71>`F+ z7}B>xXxrs)+8YUKGZl`a-W++1?pMdt(Hx3n=L=vsf+8$y^a}L5VmjL|1HwnLur)l0;u@fhbI$YZ{0 ziP(6|7ocN1JlRh^l!yEfJrA znRSFah%-S473B#xk(D6mVeT5SDG{H5nSTT&fPQ^jNsSqV*c*Y=Sw;zGPmh_7UWkvt z&!7biv9$?u3S&Avj@W^a@jYN(iWT$gSE3(kB4nY*XUgt%2}8q3kfF5D zF&%$6N^RjN&p@E^OGiH2a1n@@W9B_}?2jra2IRb`FOT6tq!T-qF#KNZc_U zb5^tQV-q%hY|6%u&Di*{CGN=!^Ks}m9IB!|q%DF-AgiNkOHmz(mL%>QBU7|>L;ur# zg{sy|&o6dGNYJ6IDY5YyZSEh4JF;|I7M^QXx+@X~- zgUPEByAemd!3^o7uhOE{=Wb(^iMGR(v||x_0<&7_*qjneb!-mi#?q%!VuKO87-Lr` zbtPh(B6d7+WD=~Tbw+Fgu^_fzrA18*o&TE9_fOOQ&$MF=GThH7!-UDO3i5~5F_7LR zkVq=MW=wj`g|)C!SYSM|2WBk&cV&l4Wzh@*gk`32F{VhvG@l_&3~6f_BajSH+vC~Q zXm#r$Ki-IIihV;|kq2M;&N+N@5=Uu%qiE&AFqok$?prc?)~#z^7oKDWnh(Nia_S{U z%e?GbTIejSIh}>AMLCSdI9OER?697<5@&DG)*^tbU=a>qyVWhCEe3EdR(9}_Qpc(n ze4f;^u4&zzYi9ir-hV@FO52piH{R%d$!whi{q6)E^X!Wm9!dD_NMCLaw-BLBe0`)Z z>S2OeXolyIQCm|_y}lSZ?ubw@LOt<60`nMr@z#?O9)Yy<858Lf!QTgvdW=Hv<}G{* zVGmcPakP{X%`+emzf3*ZUI9gTT%Zh_&kS!mG<=E0cm7|_9UT`0nWo=Hh{rDpVVX<* zFz;*{!gFv>3yt}rGx{)Yj9h4pym3eF1S5nw;|NC^b7T;EmOsrA_>`j0s^md&zWk%P zpuzlJ`dkgzI}e8MYg)@0N?!>e|Q#nsiE=z)Kl29(l!D; zWGaocyc$BZ%&tdyRrYqFMAF$ShBszwe4DiV(s$X%_*RQ%J{aQZUMk+XAqQA}4X;;t zUic!TNL!{w?^G$rhH`E!xdM9g$R9e-gTSi_MJ5R--T%Aq+nQ-7s+&gOr{q^=iM`dx zO@e$gi_%5(``NB&Rb3+tC-R3C2zzG(^i z;nZ4G!V^2z9=11XKlF!eYH45z1j6bEgoO`?)-@28J77LT^rjHL$?z7#+Z6H54~nod z0byZ+zAx#2ovk^A2bRh3zcLMeS7zy^>Za>v>Sn|53ak(RCBK81f2#}E^@dOXKDr29 zBz$K?>H6vV<7|J&BO#CX?Fip9vG5)<7Jg?E;BO`keq)m0H6|IJW@2=4x-q(Ox&gX@ zxaum~bsKa)={D*z zbt~X=WWMf@E?u`kw@|l8w^+ACm!Vs#Tdv!uTdiB8TdP}!?R6D8a+9T_M+6Wd9ielwFa0i0egmiKdURL1;m2&htzbm*=SGw z(HJVShtPg0jzeo0Z6jtcFq|U-wp2sSTvRU`>bkCIk`xqW(n9J}S!}AO; zFucg{62r?3^CsR5@xyHCiln_@{+tGuqEQ#ts-v=TTMm2I$s;B z${X;Fsl}4-$Oq$lu5@;8JmwkG`McxsW!G7JI-h}g%31toeh0qsdYC`KpX0A!{%`^R z0AG83&3`}_(^REZ$*MB=?rUXLP0U2|QhBSIs#@U-uz{+ss-CI{RkSKWm5kYGV^tGX z(^PX*3ssq_)%YrGj%t@`zv?JvtX)v$;rp<6RgYB9Rc}=84re%m;Yfy~7>;I`%5V(Bu?)vC z9M5n9!-))kWH^c8WQJ21PGvZa;dF*G7|vuki{WgBa~aNKIG!<7tIF(c(+I-P zEPRdOb%yy2Z!o+=QDzb=Gl`X%#L7%!<(`ZUW7v!0|IlciZIK?g{te&#ae*H~S6WLj z3qdO5=y*?UF3|cpyv2S8KfNk*OQWx1m8JmSUI;^fS!G^Ba|z+jhE&Xh@83v;KKLJ; zi`@sUrKr`_u#UJo*9uqA8SVou+&?(Vz|%YU>pZ=F(GwJ3mG(Da^@UxrjP(oHL+GsT zGr00Gc%y#xZH&>1K>KR7i;uHKDl@}znvce#O6-?7rU5$!wW;+>_%C)xFQ-H<)BF~+ znsazJxQF7sFhgI6^^QDB9B*wno<4nX+CMuI9SIz10o2kU!iGOOKEU^hj*Y~B8g?FN z2vZBGvtL+ZtaHnR@cz!tQWBz_nS_%-Ydb`FKXbRzmpc{hUBq( zzpf@))sb!_&?Myg*n5jiA zQ!M{at;-X2Mu5J9-nm4KeWt@Gdl(Do)(++sERlzaBpe2#aF~{`>77cPOl>0#e6Zj7 z@U4V)tD3hNHfQABqe~uK&qytms!vrP(xBHg#JE^DQEx>f&8*EjhWCkyi|ym) zptq+n7S^S{kLsNeH!v&AtER7F*ma0)78Tz& zJi)PfKnuqf0sak|>3uz1>gelvxioL#ThFbEzLMdI?EmnI0>TrLqI!qxQ%S{=IZWW) zD-}*15O2Y!;wzhH@5P)xQ1kTq)uDN_+qtNkwH(-RN7D=EI;Y=w6W}%Y^7s~&`yF3* zF5=;jN7m{VzZ~Pct!8eX*U{G*g;HF^^H7_zn>R(idl5P-ZS9mQ8{TJs}rutMX@^?4P_(Xv!xjvO)3mq(VCw^G}xZCP?j0B78s9&P#=6EQ#Pu1}J8__E@oS`V z$;1*;SsO|8!KNA%RTC3@6;ZEqv~F0Zk4{(s!i^*D(3z6^nU9aWi>tLP`T=&_PZPvlAUte?b*YYQ{H_Fcy*Vb)}jBI4~u>ox39~nF5>0LWqvDP-p$C#JJ4Wh zzg8>9pNW67X5r0O0W*E#2XKWyJs$R{P}5u2wnLY7rOHlAbST`tcdh3FpT)04o6AGq zRJc+w=+%rw%WT`9<+Do{WM7aUaSbb#(w>DHdjd6fse~Fk5q;TR_B?!t4lZ!qiEnaE zpYm@}7M1i)hC**wEG$|6X+ieB9BS)*{n%x^>v7$6r)-S$AJ(tlr?bjZO zJpUnO&yiD06BfL#;xX@C;4Qg+J=t}6{}t&Yj`cd9fA*=5$Ge@kJoUStq`0rSvnH$4 z_kJV&f(}^=NiWRapK6))as1_uD;%nS@NqeNcI>>g0pZfwak=Kr)9%FG-}EV~aq|^x zeysFeYU@Rp=X7ar-KEUH!e-j+T9-!Z8%Gu?rk=>DkUuJ@suJ3<Ewv_LGCsern@= zR{dbr4_i;}8>8<)3%8_(zF6+7Z|?TZ`>CUMqoQPDU9*mxXMN9Fy*%9A>P5KKaq)`i z9p>UuUmxL8zqdzSmpT!>Jw5C8iRkU&q5nz&o|GP(xR7HTOmgeiu48Mv(=XkkfUI6tR_Ah|9|KJqj2X~)w0Y+C z0aZh<4Br;rFn4W_?y531%U2s=_V7q}g{@~Tw+9}pUa#x;`$G?u-4^7&tKihhnb$YO z>bf`o{nEzY%3bz9u)*p##|1C%e5uy`!I8qSH)StWx2U-2*6H}v#bpxmDxDhQ-0WH5 zqy4w;oY{_x z_JbG?%X*#j>sI%i-JssWOHccagO6t^bf`YnWDoS+a)Z9J2&+@ojeMnhb6)HEkvij1dB_qv?>pnLZeJz6utE{N7j&X5luA#1qiiqkRmKg5X zWKd$?xP++06xJ%!>+98VgZ`>thqlVxjl1r2_n*|W|Eg)VIiX8PS$&^<<7j^#4&c;T{GOD6y7}8)W6c@1n#ftcB#h7vRY|jnsX0j`?${EhXA^3O)hiyW>+h4{?lbN5(t4)jLi~eLtJgGf-`@6WyWaON zxb%9_!smXLhI`|?bn*Fald1+h7_zp_OW(6~z3VN`862{r^y0}UrKv&Q2eQn2s4f<1 zuuy2Qu6iBS4Az7cs!jAN{41fo{!o+9R&jZqT8)lFnqD?FH+EJ^5w!_BF`B={aXf9Y zeLnBzf3fPs*>~pkY`EGjZl(90JQsc0;zTyQTI*oJ1#pAVooU83`AU~rWu^9P98_)Y zuT`u+)x2X7FuTj$<@)vpUDjIPQr{w@Sw@qz@BX?jE0*^Jh<0yCHq&B(MOq75td$;0 zxo96+tlnSKVurpAEikma;H>{qfANItQoqs2s=gZ@$2H#MzO~lM@ekC(eJHDPwm0Wk~g-q}A7xDt7)Vqr-6)0va@ zR@-J_o4g}a-*?zF-v>p1!c1-1+ zGd_1mnGaS8lMgKO*}ymMR~WTmP5~S~<{6{~m1{a<{k#x; z)oWb;2SfKhnP8@SYo(s|e8Q;;C+k%HVbROik@n7?hTb1v{?UE^WlIlK3OF(OLyNQK z=R!A}+t^f{`F>^e%*dx^L}jS!wM$b=2NfIe+XoZJIvzhgV(ni$09F zGIz@Zr@15EU9f(o*&YznF{j0}C9SwNEhD6AH6m8ey?fDgbeqigV^>KnZOl`bjD6ZE z`3p%e-(EA06ZO7Nx8JPfyZf+9;F1jv$xYk_pIUIM;h33A!}zV`EjN97yI?apQ?YGe z;d_%q2OWhX?Y$1#d)0rYz5lQy{FU|=ir`N1pG5+J5Pj{2& z*S36XRuI3ZjQ^r3{Vft^?^s%YVWi8E4pxtPg?wi_??=b)3e4=>-=A`8ljP=8D?vE^ zDBh=VoQ3tRgBD>^o?qQj`mz6yBae923SGAE@t)yA)1j9F5}cmtPwY+(59vlq<16A9 zuG!4{-Fs(5@D>->`|ro4o$3(uU{U<6=&bsFm)@l8TU%yGuNuE)E~w#QI@qpPu8%`Z zh1BQ5G3VW9n{D~^{gdHae_6gd(Q}9YkpY$Ds!4)($4LXa`ZlxKvt`T1?<0>dX<9fc z#c9;yQu>GoP32I#$YUf8D#hKj32BARdjVokTu}Ei(K1!QwM$5Ii%1v9s9<7Fb zSFu+MZdUq|Y$@6pEILr_hQ{F7=BEp$dt}<)eLehH?MK4hwj+59eME^2$yhL|XXVwYAORryaFX^AQEaghmO@qJSqOV+Wl zx2jVKmojZ#=h(P($6JC>y`tyiA1e3SJEgkm#9`yDLTh>~JD>J&^fTMVR|=n2Ump?I zp?czjBeO15jGEqgW0?lgr>C!UJ#%u1{KZzty51o+uR?*3>dnQRisrvs?Q}_Z?|tpY zqLi%ug+=W0kj_$QeokJgSV=kWUdjSXW@bl-OCmBY=qearT8(%MAS z*xh5|t~q5RyG4o@5ABWL{d&4ndiU<99SXOX+u9(bW#6AJ=j=PYJKrbUs_gI14@gwA zDpjT&sO0>+*N$<0rSF!XN~meGG?lNePvt8sZ^_gxl`n-TiOJ=Zf2im9Jd&m1;wTJ3SU#-kRLC8{3^;(JeT z*!G7FyH7g@j&Aa{&5DPMZkBUc)2w5i&2_pyZSg2y)AQzKq2KMbPnS&}cr;)UA0%f? z*fIP1o2FZ}8#aC@oUwOxQvI+gGcNC15%!bgtSVJqS5!$^xWpyl=B8HGcTBEqcygs_ zx3Rwm-bzb+utpm@G0!=bXx|N;H~ZHzhr;8x`)T%-X*}v!L4AJlWcyCXw{Z1?x%!Pf z9NzbM(QnAmG@6~-`jh?eoI0U0!bucd1Ma*h%6!^gjHk{5ZNSvvdba}44VO$D2zIY zh)l$Yihu|X3gW2XhKhj5APRykVHH^-AV}`_`=7ei-S6=NIx}B&PF3BywVpb4&Z$#% zU#wte6Y&x|W9!|v+xFKt?*6aV`oave)gRb)>vwE3aOxUYS!1uQ%}VQSyUROwyZ`>X z@36*ujzu0=e*}GPl4L!QkJ9gdHR4idCKu*mLWh_BwH|)9y4|bgxqtj6?Q%5utf(R{O9eL{m`tig!~&FM#8w; zCeydVk9nSP*pbJdv|V4a7X3TS?43&vU-ZGF&Y1F_*IWIJz07WI9&z;h4%}f$`x+}e z_ch+1f8>ED9W&uWt@|kd80DuOx#;)+(~Hs#sB&@$OLy2I#ldP?Y*dR0zhdcO zo0I*}9zLCFYpQ#v-KI^W)>igvdgsb_6ntuiQEvtOZmX&t}25kG}i4dln@a|OGH@VuTrnlH< z(mkzSt=nL_g_V;(F#12(FypwVbQB=eDO5wkJMxYC&38-f{c@&)dhs{oB*oNiZnU{<0veH6ubeU~a zo@Tq2mol!0p`$Zx!$^Nl6C2n*q7~{9Ze}Ex*@lA3j&^3mRT=zL76XeIpRv{eX!ii% z*y65s0C248O0MNSc-Pz)Z_75M-Xn`YqCEiG7#3*!PM5pdK9t|5-m-nvj^-kUibH=# z6+f0e4Ez#!QGJNuv?h83n1{vC%~W7|@fzEp_!Ao}mYH+tzHq&5;O)K14&wcrpyML6 zx29-TbR+t78i77o1D5=N{)=uk254M#<~aJAJy%-S&R}j%0M4#lZ@X140q(N1Su>_J zBYM=D>C_EaVHCp6XxS%2xDZK3x;>riwSL)M=I&&d}{?a2Dcnn_Bc4Zx;#UbggV2(vZ8G$7A8Yb^%*Ry1l{~K?{Eg;ExD;RG z`4s1E@E7qI$L}`K*edYqe6I(;qwyN?xT;Wm(Rou&U&Tetk?0;e@O91l%-dMEILqD} z^N$WAeQM2#p2S0vTWxoz$?Kgq@0dn3}ePbU-})jD9@-!E;Q{VDw&Jb&}-w#u5> zuS<7jcb0#g{l2_;_TBR1*=@z8;3LWe;hVJ)<$&;%e!?121|&z>X3mGEl27a8leWHO zfchrhU%r^RfaiesUw9hy$`M4>yUKOm%lro^n)!;6T+ji z$4bAkEuH5-XJ?ikwQarZ(b*&LxRc9YRejmdJxy|fdX*;nDc9%^G@QK3x?sK2mtR)5 zu?f}vc((|7CAs#bO(;(Zd?%ewC^{0|Z-6|dj>@yy3&}~gu)G^-faBqAo8WjL?+6@7 zo(Ko3^E&vm@bGEM+-9GsvSzCvC4bwdR_4*h-@RXZRnO-ARBO7tx!-n9z6>v0$hiM% zgW>_@pIf!`JKH5qp%uXC^iJz9Z%q6VKx0;z%hA%8X&>HI-p00;3`{rT-LJtDc`C%y zc{aJcm^A1ezPDp#koXdt?)>I?o2<6A4#gW;A6HZ=w6&Z(tSN6>d{ON&_R@!KvE)E) zsVz%CZuQb$_7-^KIq=E733n7$Ytqp9D zoDW|<9~_o#&C;FrvErRJ8)z2qu-WwWW6D2Py7I?$^x81Xz{i2FO%LntA5C8sKkBAu z=O(*npX@#}zdbxW=R1od|B1Y0jBsJ{aQ5{v(w(<=a2Rp9if}X!ia39xF!Gkygi&_n zeAw4Qie8rMh~lZ@r^#u^mt+4G1?Vy==QXKrf<=2*qDopTm9V0zj#1TMOd+ zbmm>_T{3=D80As=2=9^Woltsm?{oe>*87IxFzcot9WB=vdgNA=UopH0d3Jhy5AV7k z{Qi*ea>8>RpRD20VJ^dRS(d#To>>E~LuB6<-;y3ZI(&`HdjlC5=OczuSBl{%9VF@^ zov_0fq8_%YFw)&B!qIfT%4hZ^+8bzpqHwfK_5F(YrS>h_J9O#O^+TRVhUgmTQhhGZ z#S@X?#YNf6(vw~n?#`Y~@6KMTw6X_*XMy{G6~H}$68hCxknWhh2)tCjC|eFZ3;bT8 z%T3A7RRD7SMc{AM!?TBhXMx`X&*$MilDEJG$k1N_KO}C1F9X*A*Oq>iy#&0RtjLz9 zld@;hzUg?=Kz=}A&I2RG85l@VBO^v;typfA z;oaGD`8+>0-W zB4fVK$GuT@FX8jRUBKO|?6>GsI-cO}>`Uq0)^uL@aAA4!aN)~(BB`x(GBRfcb3sbY41A#yS$a3&w*N3 zV%J)UZ7DmH@Jzx1!uJB$#IkPy<@}jEE3f4FVJr0e4_ep+ z@QjUS9Q(?0g^)SkRQ@f=WE|lx-1hf9)>?X z<@?)fY-)Kb_73SPSYeZ!-5%lmJKcwT`_R{yY+UL5>`$^!0B4szg)XreJ@^*y#~sO` zc1JSZHkXaAzQ~rSs%vqo;cBDxIbeCM`cp16;412Xn$=7U><{h}dxPtzz$Zjp2O<(V{ zUDMy%A&K^re`kDq0rXFGCnsmmmG&VW9I;=km)6bhW{$h9=5ehTR=DOv;E+uCkQGJg3k->t>9rz*2my@DJdE|lzB9iIMUQch*a>s{ zq~nz}lDukrv9I4=_7bnG9DbMe`otzoSLpp9_JmAZ#WNmv3PlQ1oMK7%j&=~7`6_ea3<@oh0UvlZaE3K#||ld&nCb>n$Z>-ZRLdfQGU6@ zbaZYYxdJ^tz_x_j7B4RpWc$}yiN|Hz*0W#}`lFI;7MoY%08Z_&|GZ!{kpI8{*`H-o#BO`6)>RSym%Q697zJFPiv{m(EXWoqf^6Pm-Kg^x$v*@(1ew8(IXnG(# z`Wj>~b_bVd1L%hU^mafF*AfaA0UKjid=oI;&vU+P7m{}NNXYJG-QGvq+SI>4Al(;T z*>&Cn2!WMLLb`O<06DMS6dk9I!dowY+1`v?S{GVhn0ycZ|2^WT(?@g!Wc-oXi^jQ~ zbRT2__ExvQJ^^ogj&-`6GqV6|Rt~28HO`C0j~6DKy&%)43fvz1HO@KO@S~Gmel3nN zT<1=ui)?ewcsEaXMmLe1rf;r8==^3s@|Tg#8}I2GlAzVcz*?T9>*BYw|en5c*Sk-EY>+X@dkt* zFCzbe4T>ico(Mi3v*E(Iwzcx2PwdL`uAJWt7q{k}LIGt9%c=7*&YdOy77`*$O5?#p zmHZcEe=4F=aNapw`~iGP^@(39zw*UAPare%Jf$P7=J`m2*0!pwjjnJIecy#O0LYe= zo@Y}koI#{3vfm^dqeILAZ!^(lH?yg=kD>S7jtpD_*)Wx}k!8pa0KBf2O3tmc)k=3~ z*J2-AL$-VLu&p#N$&ZZvk%{lmgqFS^XzK6FljpL(QD#rcT@N`c@OgV7yHT?{>KK8P05m>F;XNFTue$^wJjkLyEpv zc6~O~8P3GDM?zQBn04-__woE&x})eywkz*H@>~6J{dRZyCA$)O1@yJCY_-yny$t7n zzGql&yD^u;#dq0y#qSd`=Y_|uUbxp9#h>!b95D~Y!j;VN7i<7%7S7F%^JnBsVTJ7| zy6`!FEPKr9wG`l&_2j_9WCGBD6{mwA=#qDf$hd&c;Xl>CGIM+T^ za4~amALm&6I=zZEMQ=A_+l5BizikE7ff>N|@P)0EzZa7EHdLC(IW%Qn*EWKE1bfAO zz!ShDz+Zs7fQJC3KiRQMMEk_3kUZb%h0*!zOYPhL2r!mYS zP|k^d$ul%6{fqcw`hN(#a{u&S?UGb?0}f*!|5v+Iyp%cRzEdXtO}O%1#e$s)%q=T*yP=pva%FZyawYblQDONiY&$?T$!;j^Y2Tn+D=Biue%tGw*@V3<6mD%a!{UCX#C=Q?8m-466-wor~d1j&6T-s8;Gb?-BDWsjJ(BqB^;R9ey z0?M19wvU}5sDCQ}_<2DNoBAe5%hrCi2G6+ZR5CcW?`wH+p_aYb949 zgNw{-&-`i}YQNJ~5j}!7;`qA#^05l12QUW*#E|$z>iuBpMti656loxijWqRVJI2rM zcjXg|`%%3kTpIJlP&f|nxMyZg+s87;f~CDc|IQRpuhHHw;`rkj{?X9sVZ=HKIA%N@ ze6KQ3&z#T?rzyheJ@J^?ZvP|lRaxt`0mB|KN1&?1=VkI zrbGS0mF7&eJysaszfmZ95v}|q;pjZQ^ez0*kHZ_%7<4EnEvqpJV)2X2&}G$POWGzxvg$ zeuBB%gTCyiko8yMz4|C#^Bv$hjhH`lAN)xfo*t-?h!>>5_>JbhgDvHK8?PLEqO9J?HbYEtG$-rM$2b21e?fg_6T2ro@LkEg?HSAE52yoEWH!h2lykl&RcSz zG2N2^A0DEga`~A3&mN>f(de~YJ`S$1I`N-{c*O5N6GA7F;pbM4u#-y%+dQ|mf!BE6 zoxaa5U_U%7Z*I(hJ;|QH`Q=Bk6aCCCAbixrN9=->`=RMcwmkhJ@M*iaJjIrmAGWVB zzONAOqIgfZr2KHPrL^?J?8~}vYx)?r)1{Ww4zt0^wb;jLN5C9^y8|zAcMqLEIm;fy zes($V&GJ>rw6wqY@|YceO`_{5q-M-ib_=@hHt>Sq6yIdn2H=kN>K5#6mhukHlzlF} z)s`d=az~`XdfYO5DLu17}6)61y<{t}W4X@{Q~z?rd+(9oYrxwWOcMJ=Np5 z>-YiNEWOE=q-DPc z%d+(ycu!sPyQ0v+C^ym5K10F)gkC4n+?pZL5&3_{u*4 zm};^K0IS98IE-*7fbx2uEedhZqc-%8JSzX{xy083mN6!uJIY)W^|RLtwQjJ7&n{m` zcoVP?8-J1g%O2R7w}Mwqz|MX)YvV!e(9e3_a2N0?Z12Aec`0)Nyu{PJj)%y{85#91 z$zfUg6m?Qw`I29RdU&@08~4KWo20EEjk6Kf+DYZRY)Erbv4TbfDuD;wZ^>=pVo0KeOu zu)p$2;(y8BUHP27pYwuAI?EtFA6v-g$^E?lob6F=SV_RR_D?6-{*>EF=_-?Q-mH4O z-aDbgUs>DVUtot<_9OlT^}hlQ&dwgM+(f;5lXfn9!ef!`K|W$@?`Q(=J|2XrVg>U^|r8rasaX`aCb^{pWf2JZZ}*_ix-=h33lJ+4lA%GN2CJ3YXf<-s~av zvLc!twx1J{dzqgd!0{Gt2Reaso`sxOhji>h?6~3-K=ge7y=Ph}!?+-{zeowh+ zgzqI>9Xr4=8GBUrhu9`%Q!1Tf+j$%Lv&t!7b|t>^KVTEtkvs<` zU*(?I0d{dRi@Ux>ySQ{6a52x1``zD*v7udDdOPQuXA^!3S@{vW7(2x5bWZH??vrf#uAN!*I^n&+8eTkrc^tM6W8gm4VUH!@13V0AM zu4CT7MFi+I;$~dlhersXq)(q0u8>E|dhsQkMex1~cM*E}Ec`}rTneAP0B(if2%T}o z@#UfL-V2U@jXj?S&4mNF(46>O2rtk;X)%5HflUz(lt*I~PBkv?+fmGGKL4f1Ip0
qneT*%=vC)>%*v$QuP1|_Trf)oKD{VZ= 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 A?f?J) literal 0 HcmV?d00001 diff --git a/attic/WinUI/Fonts/segoeuii.ttf b/attic/WinUI/Fonts/segoeuii.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7efb70d6046b00cf783283278fe938a7c805a8b6 GIT binary patch literal 508344 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

^IG~9fc^yQICK)89wB6nq2KERK(lAQgxx{IA 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

^N9T7R*BJv)3-bd#9`2WFBSPw_x zy2yvv_aVNWLGPJUB7fui-`)`Uh}eEy3-5`1G8b$jpDq*mY@EpFC4i2z#Pw_d5TCQv zK)$ocKD!@I!d321a)5ZC%omejHS7T#`vQBuR3RFO!acFBU$Z4+i9%N6vZdIllpj z%lT7ql{>h|^BsA({Hs*t2KoOT3+v&!$j@T{yZ(bu|G6Y`vqj{;%3u;KhgP7R_6bl{w?Hhgb*R_C3OE2?iegeB z08#-Nrbd_#8(=pag$r;;6bEc@z(xmbcfdvmS*N*D*LVFw(74@6-LKVOVSB7p~Gt@V5iqda9I>@Z1GM9;_bZz(BXXwu8YDi<`o}e#TrrZL52@9e30QoynK$q zMNxPLwqhk7)>>Eun}9ZBJql+5Ilhh%4CwJCpD+1*vBUQyoCjj!=Lzvp0@&g=16IQx zI0H9D@kfR~w)jr~V(w4f_+zX81wcjsG6G_u2+$KS4OYNb*azqfKwkiPJ6jP? zSOB{LTS9&mCDa+>p$sO#YS;~*h!TdpFl-3JhA?ah!-gLt7vG{Rg!S9lwo zfFDJPa0T*2;9tZTpw1(SUnF%Hc}|olL{EC;v0?J=v+Ww^b*(s2StgAgbkv^ zmcUS$0oWPK@mOq%Jp(sHiKBcR<>M$HcT$x2Y&Z+}pWqCkkO}3`2-uyl4)y{v5`GpX zF#rkxy?E|WU|-H2AYU%!a$Dg`QM!4QNHeuD8rA6 zQtu5HMH#V6lm>x)qKu^M$P=P8Qb�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 fwTu zA_lev+Qgn4t&R_`dTIOOX@lZlD!(MWdgSBt7fI$Z(qVANfm4P?guNtghqklFDc9{0 zO!5KPPdws#nf9PaM@Y0aF0QE+U{{*p&}f=Ut?34b7ahg~kVj)hbOIszGT;k3dj*?e z$-S;FBw|uv1}li9i#HghfC`Z)ctuPf!(tj;MZsDk*>!pF%Bu%%Ed5ti?Tyi`O0bU} zFB~MXRfRi*nz#OYBC`8GCjY`e8Mz~W%Ft2U2TUeQFObxu3l`iyd{TJ0^V*3|_Y7O} z+scwXOWVvTUcR(=(W!)lO>5@eUsAMS!H0{c7lW4Tt_oK40mB4giY>HSUAUfin9V*8 zop>>na#B-_;;fYV?nGkQ9_?7CR^Eh>k1 zg15oooxlh3j%c&LBhZslSY@HODuyDmMZ1K`ch}mqGFEBnvA*65XKcH)V%ZCpvI+b8 z-<>quP#gNm3kNR=H@F$gOaE1Q?)@0+nv^Yrhuu3_R9xO+NsntYm%Q}yzRkjCofJU_ z=WY3E`Ju{I#i^~)qk@;%pb;L(rJ(3IAaqnhCRGLzUKZl;F=WsgaiA0#T`zPjt*v&Y z+M>!)gr#meU_K+UURKxW?ol4fJhT)PaC6it3lD*$>-L>^!@qx4)46L-Zk)HVO+8;O zYLVHgcgw79U1gkQ_*V-*K2Q1b{>6g+WQ%$A%pI53{^4w3QfaBZW8sKa?Z$~RL_P`B zO)Ws$oBWS5+8*&+$B6%AdZqLN&Y&$*(?Cz_Bg`#%Mp+05o`8>X*eN z?t=}h{@7Z-fYG(X6Vd{U35Ibuzuf4V6;B*P%4v_&642pr(4h^u!p{ggjKYUM@35Ht zFfl+BSIo&ki?W}hK_s)%mh^umzPNhgtG)bA*q#>~s4gXFUAmj<980g2AFS}CxF%a{ z?FUlsfFx3Ui@RzoX>JbtIX5T9*ToWiQeC4AwY17riHXqrta`1>51zktYjv|lZ#y1%? zmi#`2K11CsGYgSOw76z5=%1f8FdcZU1QO$v+#6JtN#g?sQ;Y-ct{f(<7m+zqe29;~ z0~DV7_!A&j(KU`0gV(48fN+%qGXO|104uJ)UWR04HI^ORtfmF_jMgz3x+NiV`nDOC z&??c`p+|6&1{qRntB$PSfm{}8vt&0(88JRAFhbpbp70+J3Bt{Nao-=4JvJh8q3i@G zk@j-X*yK2FokZdjq|=7csaI_DA9SA>!%mAoO6=Oa<{X-2C{deEQ@SB<(jwVd(*d{~O7wFYPbH&Cx+;QK;} zCf7&VwJq`AzRRsTC==Inc=gpQeTN(6Tx6_I=C=z@MAfSg#>~B38fMMZs$lO{xsRPgY4mQv%BWC>`Q!q?E6`U@Y`oET%sEK z0Wo#w(+>-wvj!Q!f!_KR_1CE`t*@;0p*e zIdnRGs@xG0hJIu|ks(^Up6E%ONDl?BCeT>42t(a62$F|U1&SD==sFd0DbtVtlRk(V z;=9#}l8kltzY*?8;A zw=d5s;#WWEH@mm+$Ck3z#f#gIS*>2Jou9OjRU;S#i)^qgTtX-JWY|Lu%Ctw#aw^fw zLCc5nd^1YH&3J9RBgEXQvc3^H$bouU94Nqy>rl`}@;*9qDj@}ja-J?F-Z|~+-p8xXYTH?KP%l3l2 zwkb`cBbufs#b-51CjSgI7ftTF)D|)@tJC-<(}y$}mNZy+bo(P={<{@Kw*ObMet2n~ zaO&mTUmqvU&K>?WFTO{!w8TiV*wi#RIxGxRX^s#41a3;_X;t6^P|T-uEug!@J)15ZL*uS)JK#Qy%BF&o*rn6O*2GREbcX3C+&4&PMK-JFk#Z+Q>;RGCY^H5O%Tqx2wvP*6x9N;LG@c?NE~ck=aBe{6nhO#7Ed zym<4-I=6_+*bqh~+^?N1fjdu4pLU_pxBQp&qiTlF89Sm-5ZUgT~Fx$vPx_v1|4GPi9YDy6B^#Da)w*I|unU05i~|k&kEe z)(1JP5i)D2H7d%A=E2B^G)KZM&Aeqy`eDafv0afno+L^+cF*-U$?O25PGRH!Ia@f9 zBD^iyAuv+*M0D|+HG1?67y$1df2r@Bn|)-DfB)v=4_vlLDzj92b?Y-__RJ-huCL^h z7M8dWnCud6D;*NgsFeGg{mmKjm}EyPa@#TzOyLe6YRpnIkQslEsS!wN6B0w_hNo@< zq-cs>#oypClK0EJ4@((}y0z)hq#=d&?gz+T>J!4F-p5GBSpcW&M|TL{ z4({Cj$Fi?qy)R;{w;p(yfO&K;dx3F31jda*X1u@FAqn7lQ$VOb!eKHa-4@%R7=%)m zM{fj?ohUe>`~(&A6c2G1Bd6J`s+&iyvP2E)GpsBm^}sit%tAhhu$|r8^Fmy=goW87 zrz|b`{Lg!hID>KoUqD1?5Ii zE)465>vbbNw?u=Q!RjgRyDtEitGj}WvCLEG?{mi2HIN1EdZ_mJ^w==8>l}Y30E~0e zg)iWVb7SF&HsS9>@ZYY+3m5uj$79EtzRRE9uj&n zgbWCo8?rKl?-D{{LkJ=OAv&AGNOXERuoiPZGLKk60fYhbvs3ZrqArRS<<#F+yV}%{k)7Ljn8eRHguJFO1=Yv*uib!}3GCKoVwTa*j)@eQ_z@ZPW4A7nsV4{R6NvN5@!LD5EiPX(b$g(X zJ-2IAtatF*Srm^2?whvpYo>95Vx)y~AH-Xu5xLgXMv};21qN$K9Ki;Eh7u`N!FXuw znxVPASR!+PG&Umc)#GYzP)L-Ib;3;A*aD~nAMG1 zI;A+#-QWZps`KLP`b0-+RCu^LDp+nZ@oG&#h(pO^eN+d6OPkPt80qW8=38z(XLBia zk4_>+Od{o@fx)r}rW70Wr3W{=X*+P6&V%mtyu~@Je7ly|GJH&AnDd)%ypMGL3-2(R z9zHa5VAlqE?|%D_ld=^he@YgG<#7LWHZdQLgZJzn_Fx2>YD%Zi*^`lDnbkByDr;65 z7DwXjmC0fLwK=zPxSZ6MoFYc4NH*fbU(!^QAqjE#Gn#P`4Nx!RafG6;(>hGnZV|W! zd~IV!KD`SO@OmgZm*-VP0^o8n^vYw(4|@HA1t7_!#xA?(bm%;xz&|X$ZHDmgUvGb% zwKaar;=N~Mvsxyp7ES)Cx@_K}zQTKOhmyD%ZH7Cy&7UiuGOn@-zkguK#J*cs59*QJ zZE#Nh`kt@6cXj{bvCX;-7(H+0qK+dv^q$_^(xmz8Qy1luQaDVV|7tZ+=-(r-{gA{6 zdcV{j?1;1R6QkFGm0k$5D$y1Jb|7=xGH#)6e&%?gZg_+*nLG3;mn}z*-&Ma?vx5Be zmat~?`PF}H9D8WkoU!<)DDbsY{aWxpJ7<$?!bz{!_niyE|5gDP?NWC+&P%$G<4zg(N?bFa-=kzW zb{sEwAw3NknDER(Ww0LdmWo@Q*gD1*4u!{{7ZPwlbqs*u&%`_l8~1|HCi>9oOTW>xl@Xqk6$#~6H_wr^G!w5%aU$? z-+ADoZBz1_mCqSTI+4A3&66T*alwh%;};Yb3-d@oR7+b(ED2wdIB|5}(w4$kf~j*> zP9po23G1e!x|&*yQWT;hj~muZL~{q4_M}LZK$`|_rNN*KAZ9NII(+0lW}L=6dXT%K z<>&%aZd4_TFPHQZo0^He%^DeGA^?jZcTzWO@84^sWx(2{ljlrbY*}GAai(h3+yQx; zR}>Zrzdtztc0%a7^glLkD4yDl>oK5v^LFKV9on?=R<+LU+R@K{=Hh~dD7YBeZsa0A zseWSbZKn@z&Rm+bV5cBGQ*d~^ss@!S-8As>=Cd#OalLrzj)U$>0lsP-J5km9y#{{+x22g zk9A8r<U+d^lBAQF{qR~pghH`?K=4P#Y|VF5aY++p@I2QeRGS`PeaX=yq1JZP<} z5#AUOy?Y)d=$KO&fr=EA8{~X|(d`+%)5?)z9k;gk>EcJ*PJg;{!>~@PQX+a+?_0g0 z(}Vrj%BDIl1)4*)cjU|ey~DZYAIA;|4~O!RVbuw-v0T8f1$H9cJ8j(;lus7}BPW4R z<3OQ7UW!VCQmqFj@{2V1`N6lLk-#bp&`a%ZtjRU}8`M(|K-WNSMRbqf(*Nwr`e*Bf^4}Sak^_15)?wEFarlUp(TC=WimuX8vf`s3z-VamuZCB`!{%C5md-d0= zmu;%CsIlFOuyK~84JOP& zheSMzAuYQ&IRB(je?A~3Sep$=6JSt0@)1!W5DQfyth)!(ZZB4eNWXWMRc(>oW)TD-26PE9& zex>Bc3XI=nb9kNGFnyPe;SF56zgfoCklh%b(xO9ci8yq(OYS}Qi!IyVS@h8b7MyTT z-^Co>|CYPv@Pg)l1I@n)xe|v;P;H1x7ws4AC-FrnxefXWE3Dl27@nH8!pyZiTXGqA{bBQfE5rN#G(-+rk`-kE|#VDZlu7rJ}Qj8FkYb6MpD9@=_3ygKk)ufOA8kY508r> z;3c!x{OP#xb|x9Mu4w%xhw!JP;?40zOP4Pyp%LG1|Jd>pX?x-GSI?B-{Nn1qg>Tph zcbXCBiI{Kj39FUYoX~5PCwNi#h$=tIb&izdbRJ*3y`S`TqG+9%(AtiH>Zjdbkgo2p z^64;c{LfomUkCxNFX$~7bNRfVJO-9ms-&&ms;IQaMntGFm^zlks&$nTlhzbwdSH@H zH5HrIn=mM*?&=H1(2k~%O1)Z=eDm=q@deW#Yhe&zwW87Q76Oc3bzjjayDgKdBh5->1TjiQ9eu)Xbp{<5bD!#n6u-L1YX&m=b zpY`3l^vqk^t79HNIw;t?ZP?0iwI-`oWvew)Pd-{XGdGHq&mJ#P669eiGG$-02o?3~ z^^=Uk%Y)O&yjDA`@D3FU|V*1%8}9m+76nQw{bxGW=nSe7~E&WfZ?^_ z14pj-w0Y!?!RTWaobXxMF!IjQ%Z0-dc9h!5#ep*~l(uQPcz4H%vWe%%7VWQ|v-=yb ziIcp(-Zj6v$A%^o&P>x6c67UlRu{H!z6QY z#NN?MUkZ-@q!d{_&%3!|QZNN3-Z$=!eTRZ%&@Q_@Tp5pV zL}Qo!Tqa&`HluYz6utZUq!PkS@%n1-+`ZLB5_d0d*{1Kt{xi8Zs^@S2Ryk>+Z1UN0 zbE@|j(OWE(O*}Wg$%dY-?aOy24xX0pAhv|vOPhD-v#HmQpFKU^^;-?k5z+^;xqO6e!@ z!F@OP9aRmaDT%4GOQV2~X%7LD53h72rE23Gi5f#?Sd=+9SncPCiGp|oqQaeNKV}%q z`8v&VL#rJY3kUJb#J(SBKLS3h$BGIW&YmhbBycO}kEBsvz6W%Cy01>?vw*`V65lz+ z-gElG-t?t+yGQTxT5~IeOg53(o#RlX9vRbWl-4&>Hp6*N8JsEWrps$JVe6p&$*Hnl z`ZKmDZf*IvLbRxm#Gn&Gcfn!Ii)#K@6muCXoQ7cGd-5>-kVO^{XDn*bjhWS_d2XkDH%Ar->hxI;*JTs zyjIgiAEWysN6|Os31;o4z1XI*2D^gV5Z9i9 z^G~Nf{IH-92kdKYgd4T;76^yqz_| zua`evztI_@)NgB>vdjHr@+-a(?qr4K2_=(O&b%DL=B4s1g&!>EHZk@Ci0uM1pKhW_W(0VH6>GcJf9g_B=2uw8b5 zFqf1CWY|Y?)s1e3aW$-qt5{Wv1oMV{auF9VwHnpo=w>M{?_IV)a0YlB zoKEXZu}t)ranaJ>FW5-$M1Iw4|GpZw-hQReUw(-ZwV0H*qobdE!#AS~pW$5cH@hjF zriafV7ZiqG?#N8Ym89E)bJJ5Cu_QqY>12x}2y_NZT4d%pym>Dws^|`KKLx8$lc`}l zXou&LN8+|zl;xi2jXh9Cp?gt?9ONcAToUeNqUD&dD$lyh>k*%z_P^3CVZGNrX{@jA za<7O=uU?FIYN;6OzmN%n+1aYeJl&?iZ%Pl-i2&{tZ+_39W|s{W8IN+_S8 zzY4B$9-|Urq&l4o(@>N*sIFFiO_~o6a92q`dqP)xYzs#QrLHW}q)A3%Qc`M$wo~hN zjtE~bsZv>qbe@oqi0J4rQv^Ez441}D7SP+IWyACsXtP-Ha_I}M8>aVaR50+==&tE& zHjmS?*|Nc$^k~>Wbn=^r%*Xl2uX!zz>PP0S&sCH%8ptbV-)1O}qHPizLz>pmt~iErDDh*noukJK!~-JwHJ5pQ2X@kZ@yacaa6Hv||E?VoJW+ zYt_EB?tAB`w6wUco_iE!a}MLKY1Hg){k7$D^z?G+Ee@cv0lsP*rpqPUP1%WYjtHxX zL~G5G%;YpI#8>KXaES=L%W`A$? z8mM%J^EkT?t``c%X#A~Keg!m|B55t@Yfo;SmCmG0TvY@q$FTCq$Y8z6VY9?(%^~{S zoMsNqaxaG$=Y>hiK2qwgp<4x!GWxtOGAjKZ(+WI=keft3$qi zd5i7+`ZXuei)A@vWhQ!MlJ@F;YHpQ+m>rrZOB5FsV00wLkuZrYHN6kaAFiE*7!Y8~ zlJE)%8Iw%>labOwNV+3TOSIY!El7(d4!MdR<>R!1+yWXw7d?Hnk0k5T#;BY6{_r0` z&?g!$2oQLfpEf(oipb92NkW4RL&98IH!EA#HOd^;t=A&!wJisPX57Mlm<E}56N<7VO*Em%w+M73BqxN2CunohG95Z!Z%%7ah$u@WPO6$A@;rCtrauo6 z4+;0bHg?TVl=3oR`Tt>OdA)}+5#QaU9zKAI`2W4T0ie!H&|b|XE$v|xdt_%Okfz$y z6iK*ML#fjeXf`nXVKh;FO2syfb5gu<9UoM_<7-j7Qa*bcX++d3wFZKuGTl?X$uBjg zMxoDv8iTNw8Y&EKs{KjrmPQJW;p1nZh$r8V9#6N;2R^yZ7?Hd7l!^nTV$ag9*mE>G zZ3UQhl4y-l5@iW@_{up-p!HlRqAKi}8o~_E{{=F+c2Uo2(yon3aWn8e#rWHwPkuLs zvnp5^eTPJkfLU1OZpfP!-&K1Hf+AW~0e{67j&H_ghw z)19hk%4MD7{+Bqd6e&PDX6T?NwJ!eb7AW#3VD0}Bt=zSG@_>Juo&-f>X_zD3Q!?J( ztY_O+j)ayunT{lqnwk)0jgF2@&~|Izq?03felybSpbx3?A@hC8QHosYMW`7OYBH*Q zgAFdDkg_k1s(`9d5v7S{L?aE=KL?u zWSmi0(lfHL5wYArR>5CXo38d3@>i34S>BU*=h(lsD6CCq$C{ZCY!YNGC>;G4Q(`f* z#b!A3C;4W;4x`?V#&#KzOar2y1$t{D$+ny0GIMMWpFpMA47XWMMtn|qc#bw%qBgqh zY9KHO`*f}Ib(-3UKD19cJrs>S0WN`G@9Cg;#4QV{5h9)C_G28~C6bwLgQs`nEj<$` zsyT3SH2BW4oTP!Y3JSP89{!A0W4pWMOWU?l%##NBCwepBjq>zn__}DMLDUz}wEF)g z;p=@+5DP8?QS~gZ(^Ep*C-o_Blgp>UynI&Jbp8^n-eJ;EkH#}}Y=e8R9^1L8k@k{s zg9B;z8{#=?F_W3Fx*VL@n+Nmtx;biLEDK^;<;W6-YIXRD?R_ut{ws_WQ-&cg#mr{jSG zPk9_qv^mzR`LI3{1Dj;oBa#Ot?xOxiQQx^R89hZ5y)&DX`Wp@OhLe#8&t|=dSVlY}Q+1zePjCVu^ zn}UL|cKzpqv_?aEBz7B?~rNxa5qxi6o5FZwa3JBz0$y1laP zhH!36iC!i3ViJiJ(xMplLR(2kdu&z=3A1SY($dqTlN=I4$6m$~-jDc^XtlQ^rm$4LE?ZkzX79dw)X=GkhYxrJ3XnL* zb)b$qd3GU<(o7d}JI^1FE=sFr_3Sb&uXlEit$A!h@A23BwdoU=+K=~RVS|{+PJZ4- zjf;1anE$AsJ!5MES&=}hG-S4_OvS;$8EiJkqRT*tW}b!&(iEZ|mp&|xD0E%hMwIRKVf#GrVf5SJrKnk1iLIp!3I2NRd@qFZyh zkAi%Zt(q!+%a?_PI6rp8FZTC!GjHiuZj=^NkD2e%Y;~6AB+i3BH%j9xz6LM$D#+e} z(zECchj@WqE72QO1{$SO1bfMNj@eM@xw&_p*KxaGSv0Rk4O4_a;UmJcv&8<~R+-f( z9Vm?Z>g;}D&Dv{s$k{`sm2xhm))I@!#y<o3)V-kr)hFX{G)n-n&dch1^9;X zi75I#MTVzY3U4^LN_r*aonhfQzHwTuaHFcRZqx8Y+B&VPEzp?e704|vFZ(n@Hqx2o z(rDdGn#LNf<*0x>eOAQ4TNbQ26O|1Dyw|~?5`T>&NU!mdn=lzks!%A!Ui_l|`joDi z1rL5wp#0URJ#G97(pOMTwp;url8OJ|>Age`^|Reh+$$q`c!g50b*Lv| zv;m#zB{mwB8yiKULah#?pPUOY(9Ak|_f(CbH@*v$ynIbOgzxZZmfnSmQ_LXR9hP$s)QS)oh4}iF9iPUw>nx5b$JeD)%9a6x4mKh=jj0 z6WM?*>|wr2M@j~1-K?b}Hayw@%$<|vNJvVea2L@F>gl}eR_~C1Zk3O1u&ZbY%R`a7 z9G#xQJZ9H3kdqw+xk7&fbJOc}epa?3($n#2XK{lD956BLn6SRDWtSJl0sc{;$C>x@ z$v77T(CEmNOm7cos5)J^%^Xhkpg`ap@q_3=FjR1UW8zS~b4@)M7^+SOEvkegQaes0 zQbH$WI7~$C@387LT27oTmCT}hp#Lb^z=z%ui>9JR1MT9{>3CeEg0VUt+#0`NNJ@B6 zPVShI`Z+>>;g1^Pb;5EYdHsi5=8Op)Fm3$C;gMXIO6{9{e3to-?wd56Yx-xl^iKKB zcM45wgS%|r?9A@sTG3ATio6_wM5A-~1Zez_o(NU+xPC>f?jTD?pRS;T*Tf}dXVG$b z+TMn(mp?LQr2jYhEz7S&@;_OBa<562NsRAT9vAAgY{lx)ea)k!t-a5m@hxXd(*OFK z@z2g(Lg-2Cv+5R-jFqT=wfSExj6u+8jE-m@lg3Y<<|2+p`*KyL{2wl(5zWYBK)_!%rkUqo z%wI_$W)ron@ymAp?CJKndxHIWI)l zLnZp3_{$_xE%I39$iIaYAhiD}a4Ib~)4ovvF`b@m)ycA>h*gnpC2hYKc1Cb&;cL>? zvQFB2*v^fAe6kL?u)iP*))nuFNmzD&^eNV9t9X^lpzty&Wm^^W9TDYY8R0C##VLp$ zneN#QQ>Urh$RO={;XgtrZms3X&QLDp{gq3m^n1Hg^s%$2-jGgMFMNMXsFH15NA8_{ zW9sm!y)#b@JAqq_z}|w{-VE3qhYyJ~LRKYFq3$Zu?uUkWRlLH_+gqtn$dqy!mLgWt zp=AoR5CyLge6(q2HolO{Q8Aaz54&u6v1d(B=cquw)vX&go%1rezbuO5mJ7?s{Av8L z>L!8CA>1(Zk0O#5cz!cH&n&_8G*cDY;*zbway1e@s_4}|7As0vg^iWZW~tw_Ob9T@ z;K~AosiU(>L!4jcPq_VHgWx=pe>y!Xt-8me6GPYUD4)EUJ13J0L!>uOZ~pIsP}3f3 z+@M{fmMm9sZ(#Sc@brOf_krwY%dz`vtVWLhIdXohR8HuIX)T2nE&h>ZMcQBFL!8Yl z{9ctzzA1y|_tPD;#of_N<`m?xYP7tqDm+{jQe{viiJK6Mgj}5w8rNb#nNdM(Feq3_ zE-aX=EItG2r>?YAY1=~==g-H4luO@Sym@Ns-DT4b4>~Y=#Nzb_4pmP1<>28~b9!z% zDxFqwt7V(Rb7q_yeRI#|_w6O8XC4{ad&AU%iA$#JoSabMTzP43%C053Kfz=9IAc6ugV)2fy8W=Dq$0{u}qd?Ev}L-j-EdM$Ex3}&%V0Gx##T7 z1M?@1t{ypm!r1Cj+>-Oc?L!}2Jx6kmd~kcQqwKepiybAj=Q0MgaQmden44*|`w(8j zX*rHVZ!mhw;1+t$lv#L^a8TG5%$Z)}M@`tc_D{55B@!x z=Z9NryKlQOX`GVlACli?T7KIW&D!;C(xFS+v>l_D%<8{k@u-|ZsT-;Mnjm!NM@R!9 z_Y8F%gt4?^dNbg(Ol+<0b72hs0s2S!(5~+2OX%gJQ4;M|sh3GEVX%P;2Jnn)XfTwp zB%9Ys2!HRwrLao__6~5Ch2A5_cGfHv1mU)nf3mSs7(=SozC=F$@X1CrM1MuNN7wK= z*6^y7U=60ab>bR=QGCZFD7v9adx0M1lE7c-ZOeqQ{IB$PmF0EE#ov{?f45cLw=T&R zETO+E#rvX%65iKb_ac6mYJ*t1Irh$OI+1$^u-`_9L_Qg}sqoe#dz=3KAiVMt?nv%! z$fN6gN$ADDAT_hI+Ad6JI4k_jeO7XB6aCvd0ndKo+SAMbV^3X#vCO zY%S-dHvStDBzz@Jcg`SH9Rhv&b3!4c0~)vSC-MFoR1;Vv@h5%E=Sh3JGFhLi$LMfr z0KPjVQ-}1ArcwT{6y@ghdI#;y|ga+++hFRoc^`DD>`ar07Nb=TIub)GP&Mh7@ zdRd!kBrI`Z@v^SFVf*FnJS$CKG_`PzhF2GpB^`2vYr=c^-GptFn|jwh#%Z^M)CxK& z;m?zHr;RFK6+WLt_aCajn2BMd$i>C&413dg9~7$aA0`c-zUsZ%$G0~t9u~2v=B`jz zO`^^mEa8V(S}yp!eD}qu?7i)XH^MQu%G-#@Rg>pd)lT z{_uPJI$kGrn}E@};wxW?_LNddFYF{UxA1#Lv49%ZI07c}@OGW7v291sFmI^dkZ?^G zxH)Wb33uAr{hgOxYcIgNfZy!i=r7JIe7%%}-UWa;t3-e%kG4_Bf@#VCErg$WS-7G1 zl1{CDxWAB3BR~Gbd6ax&4RHQ|#VbqLIWI&`qd0^ie+Ga52RQ=}=?@b_gzBUAdTltk%X0xKV-Pp4-T zz@AKKOAwsA)NhwCG)65`AK3cv5ZP_>;W^`$tvu6iE9OYHiOE}=Pv-0KuYLb^zg zf{rPo0Jr;rfW1{FdT4ZBlxU)|uB9${B58~(q(}D)UmX8L_)j&7IQ|h)9XVMw>$Rd& zRr6k*#?3q?ymgRB-#$)a4-3La+s>DLU0QXn>`PI`@NZ$KDv7_ud_kfm?N3Xkat&nb zX@ycwNsiV+QD#Id1O{5u80=zF^{qO|At&cJLzCg61qs!Hu@DPLAGpoKCAV(7R`)yJ5qCyOSQY@CI63hkeX#tRpwdsPw;eHug(sy!~;S-C7ADGsX zf}2d6GWbsIvbp@M4g=fd^lRCA?chO`of4yVHA(K*4Mi(m+LrZMai}TfgGta3pWxIK z691D-ADosec}5h}nZ`sjBc;hTUh3L>(57QI zxem@t!uOBq`=iN|bPL`exbd79hvFO>BcQE4urkO1ngxu(kl94K#W{4}+b3rm32zuo zYNhFaz5!mhmuC6rZ025ay_5Viyi+K=X}&UPP>?1d)Jw1Q4q!wQd$)r=x1ABTZ3GwX|ENtDo{zw;J!rSmVo;zerkHlWfxnqC6 z!BrP@YZ|^S%{dk?7Z&x59kqzVOpv-4u&@5?+%Pp&qteTyN}YFuxS@q%R{Hn|`gEXT z9hEh7P5i_&CzW2jGE6x3GWq?xvs;m-q|%Yz=b*>d`bTP`h3Q-xM}&&BKy@J5=)6bw z4lE~)!PC4Ydb`StNO|5{CSI|t1`Rtx>VWj1Mv_`E>5FD?zwz zqe~p`>TkDY7Z1h(cl# zQ{Z{aLP};-k3i%=_^1Q{WU6fXbP(CZa&Vv3FJYiQ;XgkI52Dq8?AbxK+TwKR6q^c z2s5c=0Y(wki8}D((o?x-x==Ov=JGT4Grf*PIcE>p4L$gz&cc-p*aWpGYQ*9l9d^&$ zOqF8M?oPXk{vT)G0nqfd{h#|C2_%7pOhytCLI{LS7_!4gK$d`P5ETUX-g}EH+Tf_G zbyTgb)vB#_kJrBL`D*umuYK>?zP4{G`SL&aeiOj)`rhwftH3pWzvrHF?-`$S?zyKY zR=8i7xas%0=0YlS!lv&$*6|dqLn(Abw>$|pxmdtp8|e`H0`Gi<9urAc8(wMHhzZU3 z4gzR}jtwRD$-!it8vNr!(crX29XkEwxj$}f+<5#DHTKdguQB%L?{}T&rp$+T*G%6(M zUZ-C-aX2i(i)vw^Uc|MJ)#-GMiuN@wLfKbPe?-XqIj#DAzISKsJ zcYB^fT^}{N<8$xmQ-mY@XRkfs9sM17GC#WWvS*a}JK++5H9*IQsEoXic&p^esbsuB z0H@P|?%T(AApNLuJRkn^*AO)_PM*(?e<=9(sBtU>etf6k2Qp5)3i948&wHP|>-Y|& z9W{>M%YXhFl8lU#+4AE%k(i7Vdq|$|AkW_cU1VThWX&C7$H8;(niB~=65KaD{w@2( z@c74q^ZYnhi!qYn@h_<91nt56fd-E-&aaLgD1y8fkH-?3@Z(>?{YhSaCJ{R0$a_CQ z1~N{t0rL51GXACD9Ww6GB9u@9pYW`s&4g}#y?lgw26)DwB6RcP9}Bh)k8d2czCM9l z*vRK$K7bVf-TddjK%0i2|16;cj|&A~F7{GgM4rx5{V`IIr_^#AaI6kb!Q(=7Xf~!1 z=1vcick*-p1PQ#fFc-{&L6wjb4Mlp?G!wLWsGk5QYT zrQY^IS|6kpyYFe-)38Po`oat*AlJ&`ylO(-li!EXTOMc|ltqw=$B^=m_phft1? z6CvyM>tD6FpS9o+osQnJ3jW*j&_fS-clFu!v?yyD?7^)TT)Kl;%H@8};1XZX>N z@h%&BimSzuKJbMf{o)yq?5F_37k>1U^W+JzQmSG0{AWdyL<))_;2D4g&>F%mI3EO( zxTYeX2985)4^K|wId1T-iX~(fVhBYj*fGr@kX}YjqFxat5(KoR;8}4SaP$uU5QRs_!5G8TX0Y-`7PB|V+g>^UT--!gD2o}31@LXd4PTt9Dk{xKKXJu_* zAl8N_l5unh-%~UEdAxJ^&wq*1LHd9ya83C0fcL-+%O7aaMGflKEYxh&&>u;WMk)^q z@Rh6CE8v;o>%&Pz;EB+Y7ZSNMPzQ*FT1_yLX$#d{%N-&6_pw*GCO}PguBLr&58iKH zz4jE)OEe#mH?OfiLIM1m2YEe2B+ie2jFiLUSA-ETKNtsl@;Nvc27&)$G}UD4HBlxk z1|kQD!M-JYONSX@3-N)MZ!|=-@bB?B$Vcpz&v#@M@SpxtaD;ps$De!1Qy{P-PuVa$ zUPL~R$6?hJ;8hb3xH3em@N9ncvnlx5_!;v@efG;3{Mi}sS%?wgvzg=xpY`C+&fqqT z9z};vkx?8^k|*$={c;|bXb+7386+wLtQX-p@q#~#kvoSUg?)TVEEf6m&>(i3!Py~x z^9VW!*+LBDy~&*}Mk+mbebVts+&}fmx7ZVsa+kMo(dc(uP+31vMl1-~t-R*{5J?Fq z_;IY^`SFinU*P%i<5@c5^KzmFQna^*k&x%W9-EslqW$G<=YWSv7C zEBu1+B!@`m8v2+#habn5f*&tH&)ju<2bDQ8PP7I8`JL!JGR|8xypJ6G^I?DCd69AQ zd47DSVB^R*St)oN{FFxcG#}ZK(LC~$9XuEKaq<*?{1d^W_$i*xuLuwh(LAt*7uBE_a~Urm|2@@5pB!w4 z4?;}(I6UJD`8WPhPa?Z2c~$bUgq9%M7Xa*$*b|@vi0&Y0G2!&C(h7|X(r~CwKQt(j zQmc-?dv2o`Dp{>ucRGDzP*_79ND9-$G%^vMUGFjcU0mS2Gs(Fr|Z?r7eB z1QyX}{r!9Y1GdOhORSm@TQv{$*cJ(iEkZ-PVG1XKqf&wYB>*@W2oa$lHv|!8U>rak zJmY3k_Z@rtp@jh7C_1@D4Bt@CuE30p1Sy8Szst4(9?!oDUQI#)+5RFTiS}H+ohZ zKM#z{!jsbQiXHkb%mX9i5J`@cQZZ|2=#5Z%=&are1VE_vqevYu(RLxsUE$up0J_2SbCo!BrTr-**6>lmgr{ z3PR5#JP(K1FCai>6l#5CIDo|%AKa;gK}}2%#y6lNA_jm7%_N6{^Y?Zo-M-Vj_kf}P zNPXC{_wF^P?@teUs^ZI`Vv$NkV|?g>Py@686-l5%Ja{;U%1GZP4-}+@pW(2YCtams z-hJyF@-c9Y`ioCKwtwZD3#+>IT(tp(PnmH)GF{mF%~EQ|LGH);{{Fh5V>`~xe{bci z(+&OoB`?i9j(qk^e--3TbfufKnn*e>y2`3_X! z9jE?5#(8gb$M@LEkR3rrdGBWj$|s-ZtrC6;UTxT`c^8lK{2`xziXZpHk3bD|XLNd} z4O{J{g}x(7hIO!d=oiKS>mWp6#rv`NLa+w!p^HkTR6zg@nXi-p8YEeWh2X_AJm~I|2AWstIP*-D`dpw`iR(lMIJA^r|y}fTYz3q)&lks_<=nAw`+9j4PyOy zneTiU%g~dRgnxx25o+l8&|ica;JO~NAJJC?1|VOf;Zw9KoX;-4;HwG6lfec6qobab z6R2Dvm{tm)KY}WyDiolKJ=~`O*}`=y)SJKMexJN%UU6k}W>c&oA~`lcbHVa@s;vF$ znX7;Pc1HPC6gqDKefl2m4ELAroDkVgO>`p!E`>jGg@?8uKaGCi4n5IS1$1IBL1+Uy z;Z9zG<$N$U1{cL}C!Z3&xvYS6rw14(^zqsPr$G2Tu7@lLA_-Y$x|*YVk9~Wr9l6_& zwO_`xaND4~2Z*^3UFTGgC@nxw@ic731i_tCcB*wa7 zIExK|E5K{FEJ`D;Bfoh(M^rIoa4M|F-;worPk|d{Nl>^+H>R4?lEwJ)pJP061=B{> zB908P?-WIL;NM^^_L6wzdounp>`gxI`jR;V)JX)IMjT;* zlR!YKCaWA03M0#cp!m158--EJ4V*RaLBi<0&z-@H1{V+Z9+ooZuxI}b`+=UH;X^

0BzR&o5fU>=|g&-AuH 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

GR>#1dv&+INqIjW_6}#&CGM2_kGcs1M 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%0AUx=cgmaIm!#c_Rqp4=~e!aNtvT#>SkfA|QOx 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

    C@-4%=#(7 z$aMBmI1TnmbiVA9i+&9Ie0?0Q!@Il>;ky%mK8k8)grMV;kJ3|2y2hvNQ0So^a2A+|w#!=_~ zx4_JZPJ_&iOF0641M&_1qEM`fje0;-7pLr~xP5bj%~Iy$OhTW+e3(TpDLI&VuwYKu zxpLd8`5Cl-cEGv$;=+r}#}}`2X2Z{tR4wG9u@j>}_jn+a!y7Udp3DVH>8SFw@^K}l zG)P<$QX*AJR1#SzY?4h1K}h3}K6KOY!5mdT*z`EagdhYABLT>QT`JI{5EY2aT4C2j zgI5}taOI^w<%tA)vL3Lmn0RT+@B=lz;ABVDs_f-i&m>CtGCIAqVZOh4LrbQmZuPNe zR+Vnsu)@LIT4D;V>+wJuvfkGj%oY`F(-fp%tXbP)&oVLDh1QIV+A?#Wttwv+##L+E zsiRxxxf3MvgvYtX%MZ63eOao~fid@cNaiB>bT^hy*-<$&$jX^H6SY1Co~g$i@iFJY z>kK>zG8bkwAqfRx2rQv|?31%*HT{PFJba>={RHRp_*qSGch@k@c!qKwbl-(+6G7#K zPA8YVru0rYP~5_K1ynzZ2&32%7^cX%N8akRea+T&Vc?Mkbdj;jevXZAltyDQy_fH@ zLds8kIaX`ujyGyBEz?X3l0cj#lA_OolufrZMN6WYM@x{}!>;pKDE? zDc~yJP$?Wa^WH7}&pdoG=xXxmVAAqEZM)_<>&r8jt=|%e#%z|a-G~s$5~i6(vz8s4 zAo9!k0f6tsuPHp?EM(@uVxw!Nzj2|Mg>YWjOtuTXK;>>3JKk?A(2L{O*V4J@_>fZ< zTzK2#qca1TgNrINx+=>SRhY;XWry}}9j;8W26C-&MQO$BD+RS{C%fzKIp`%lFb@i| zuw{U389r;vu-^yE1$pA^_p#*y-v{X?xIAsK@L7umtq9+O#lWfTEjU74y6G)Ib79z9 zaD;OaP86oV!%zGkyvc;@{{%_;L`bjI=qF4rjf^)T1$+zzhY;=)4J4v?X$-@Ie~k$| zBnMfb0}zglTv1Q+k33^UfNZ1}S^;ktws7%%x^e z38rbGT?bhLd{jYv$nN^|v=Njou@l=kZTNgEIFG=pVj2+5P{i63Qm2m44`L0-HZ(&P z4%UF&PvA311M=zBKlH2`zqK~{R*;VDTH)D_*t2vt=PaK4M3|=U41N;56+H=^sjAU)e6Tzl z@jJ2Q$*;fuhv+-mc0RDu>t~^3`d^?2L3ElPy_#r@y_2fM@5IkS=b&%1?~HYQ!@b#m zjCx+MbNJvB!2j@8)@ns7#a1iq@5<=@mdvs+7T}d4yA|#4^0;TwO7XL>zxnvBWOMvV z7vQ&Ii&(-0SQ+rVln)|hoCY#5pW z7aeRSm=+B7MKnemb$9vl=|CIk#TkGba?Pf}c&lxjs2x`lE??#teE~S3t)V zaSB69=}C#GCMU;8NC|>I2@sZU5b|4*g{ae|O&O8aV=YAZ9S~oxt|gJK|69$PTd5DmI}9=XU*=zaKu)z!$eF@~QC?R?Mc+2gp z8>MHNmp~U(xVeSnoA=cXherx{fYE4D2c0HxEJm5{QG zgFZYcI)eBpZ#u5RjWcW!s}c`Y%}Y$tD~SS?W$lWGCm}1FB8n*6TApL)P`dsjxWH(%`<_Vy0!xh2V*VM6B~Q>SsT{W=ePTGnGI{I^E>=HWNU#mWkA#Caze^fhWh;KDxTlP`Rt~5X3KVNP&8E;MVR;xgk@*yyx`R1+T5NQFr5DiS622sMD(*37UK6cblrV z<>%+WK)nwEglk50lg~3hMzf!wLj^=`B>+`%c+@0~@ox5wC}@E&ZOETQVe%MQ+^Ht_ zw3hlKd>?BX-Vmn-=7fo!0Ux@SRZ}rLU;*}_v7X`$LCVA>(88@i$431P8r zXejDOU%*B&U=uIkg+%;I?!Yf$&c*-m=^siFKY;F~zv6uWIjbtj zptW8|-Gyd~ha|8T9Z$!Bd5AIzOeRD1nEf6||Fq-IVsS5sUlHX|c|BY+T~pN1P!wo{ zHl;<4jp&QT-`{%fZRWEt=vS*e1?3g_`IWIh$+Uw9|IML@UZ7(D)`sX%10CvJ=`lLe zp#|sv9~}hO?4^D=mk83!y!z0)H87Vfqc;x8PKv#{pRO9}v1Eu~Hop zsLR#K5}58ASDk$2jbBF(S0)DknDvp(tZG5-w1?hyB@G)|vlZTjcfEhyzi!Pk2eH+cR=FIN?nn%|2LHSYhq!=z443Xma@|g; ztrj9yBggxl2Tz7K*C$9)62HUEtsfX(U`C}o* zNoJU{JiOwUT0!L z;kVAb{f3K9BZ`^6Wd6M7`~~%1DUaLT=IX60Jp52@-=0oun}fOQt|J>FUpDD=O#}AU zwY6%OYTiIr-7@fS{sepaA<(D>8lhrR#7Us^;dJmX?O`z+61f7&hCrdkjPq-)P*?yJ z5Hlepxk@&(x5NSN0_IZiU=zR4Nd%MWeg9f;$55UrG_dt}*JnzF^9ot9Hxmqc!w zUB^lM<{Jt=X?0v~;k;VVcV9u&Yy<2$>MJW917nSX3hhB?mLr6^Y&KyJmrYK`?b*f6 zB)VZc$mTGu3PRD@&8rG?+bi>>L|VG_hDyS&2T&!UFjHmSseCYrnvGtgrAY<8wbWfaZr{|dA1oV65W0q zAZgI(#EUIE7L=SRog`jK&}U@IDjSW~!j)?cO`Sd2#RFhLj!*TfgQ0**t`+`T?#s@| zWXmM+g8Z;#R7gqumY0-(DnxXdx2SV;QdGg#y0OW^O%x|u8ndf*R}>y@W=kf~LjT2X zgAhdk0UI0PqI$p-@Qa}O#}zKnWOB%p8B#IuJwhhXt%TMJXw%~g{-yyGlmo1U49{tB zg&)1RDErNNW69tCxz&M7i2(B^FQF1rsN9f3bxTL4ASpS4DwtdR7ui0iLh$3OL9JI( zn6Lg4XIG_{)i+u3iU3pk8_vb8;Xr0pdDu^oCta`}s}j1;;1%6uL2|G@Z&vLH9v`~h z(?uXRThlLj;JAH5@uPC~Rly}9H!hAbe^VjklDO-_R*;amt}h9=R03YNHzaS#8_Zji zN99ck1PYtfHfAGiNGU>%L#-|6q*2M4Qm}05w)bOy?+PwLMqoIqG)8)W3wdTULJU|n z)(9<^A`1*|lPr9cqEy)>jLN_M@eNBJ-BO{iSbpr{ro5#C?V3V$b5Ebm*Ik+=Jn*9f zl~ldlU{5V?B!vdCqrs~?P_@0^8yGviq~Y$P+xrU=A))juxhY+eW-m5T{{F4#%pjJ; zEr%63!N#f!Y0Wh{pViZ18MLgiP?mIVNZqO?)oO)j%C3~4J{n1qprl1ID4`^YC-LIk zurfB_0WIVDA?Y4@?_L~kV#6N%*g<+#p#1>JHk)kGbVF2Di)ygNl(_s}f^(796f_lP zboF*y^YpF#%e@N@FRMs?IU%vdo|{ora+}sJ9y;^Mon717Y=k2#!?Uo}m)Ln|xZrBj zzBThR(sE4-@YWTdOLeJYd&9EQ;@)+Nhtzu#HvIR43p4AM1a+DIzHwi2epwyJzJGx1 z`yW_$38y5ak+^F@&UCJ`#^pK+#hTKR65kY8dB5oi6A6`?Up#HHO=++|M6n&@zek}> zq>f^ECM+YqQggb-5DJGOn}~HK(ajW^Iv4cYM;{#XyV}Qsgt^#}?rL4RahuQ9+taFZ zrB~E9Wq7(u&BOgGayRZgym-Xc-`}Z|CQ5`{NQEdaSx}LaL<_ULW#-cUN=LeoClm`l zOh}d_NOZY6m;YjErMoCWngSK(U_*aOp&Ww(PF2XvHJmzXJZ&V6MvtsjIiwteSdUbx zOq-G^cRG$bPCF7$O?>L6!kTexjlmK7r3$ zNj<5r+1OJu&##u{Hf=n!YWpRBPWkE9{kPmQ_LS|}9e0fMSlZi~O-^ff|FG+OKcm#S z-L?5puai~MV6`;WmAN!F)n|t6kl$N$vBH~|pD0U}d?=KQ`8(K^an-Q0Vop!Ukw9~V zG(`}8k;r=LsO_|kwAuWrt(qatms&c32sOL0vQ$%a@cyg!w=wjZmMwAhz z^5BMNaooy{C8_-{OIA=%KE)L^VP@T@VSeGP%u)Q`7B4L+LcBUUAhP?*P5*iMyP_7| zA7K3kPJojUg5HCtLMDaKbjs!OoD?eU?9B{bnPF1`<7BKY3@(3R2FM&xD$v=JJvkO` ziY8B^6Q%x67=blM9(i}os*8u)A@z;A%fEirV0D(Qyoc#+~fMQKm#AyLc zGPNL_LzIB#H6*waNN^Kt!l_EpBua4sEsP*Z^k?+0M|l8UcO3o9MJ2glQ>bEME>^UN z6*owF6qbYhJqUYh2JZjziD7~KNfyrtiD=t6RpLpC^1!S>B~pa&&&$1 z-IOLM*mmo$PtU`#&+PUsEjaS&A34(9{pekL1`Bxub95JTiCekx{sqV>FnDWQ+bv%r z9O5JJp6`c=5!VPlh9%MK zgCu{y6REX0K{%tfqX-&Gu`*KU9P@@&l&-mOOU2m5ukXm}?QYf=lpd~m@}-SS#inG_ z^LfOda%JhV1n<}*<7Ym)+T#F ze|Lx7v0%w~S>}Sw$lB_*{7kLGn4CeWlI1DJoK#zHUypV8*l?b$alF2A)98qMBrWB$ zWT`x>EH|UnnJ$+xzOv0#IUZG(*N}y)4$7Gn`bjti1HyDwYH?VnRPf;d0Aqwens;`! zG^_%rF|(-x<*4{^J5jQYC-UUkdYYk>n+P!%nO9<^+nh z*lmJ|7Lf17WHGPBk;S}xV~uedp9)|y_Fy6-Pmr}yB2hv44aE-tTETpHJ*KuCS;WC` zp(cqJ&Xj7x@+iUBYy3|%Qt``~B?2k)%qHHP+ED!R#^;F1<(mIYJ@cdZrT%`F97P;Y zz;73!iy}gVpbG>bYp3{p=pQT*Es_D?42cXNIax#~UDndJWC`&aQ$oD<6Jne>O3DYTYUlOU)Gk1=D?DKm`rq^L91-IB9{}uY z13nZYPDmst2}J^Tk_U_!?M4M)1~hE}z!pm0$jy<}uJfDD=aI+r;E&5>?&ZsopQ95> zg`aW({4f=#{8_$St`JQMLCS^FghG-tiL!AO(u66om?ozbie#Q58Py#*!`vTlLv;Nn6-7-$7pGqQTAU28X|YW6ah!ZyXqt?u#7nzWrn;La@Bsx9P& zW;!xOzQ`Z^yqPB3BYpfq*jPpg8G;vB1QnV^ag`84ATmw-7qSx>L z6?!jQeTkJ()GwqwMkG|Q2&QUZx`VlNhqY|D%wR6<&Ch92Eg=F&UIM1gHKgbqR`O_M zoIGkMYI7BI`1Lw9@j+z7VOJ?s3b3|5108*g`zO!~NzXtrv<7wzyQUzDVwGdw(gc8s zVi6NBk4IckFDj{6TxsG8ggjDV$a1(GSq23OxBdBqRbA~%U_6`*!woKjSwiZj47El3j-@Q?j@$KK{5rCa*~;s6kNEc^^Ui0D|Z7A zLEMw?22MmZ z#7!1|=;q z&bnz_?9ub;6uje6B4_P*{8B!MVPccF=N})4Y8LuuAQe)e&vZf}vQTj|5Stm`NYD|n z9zJkI{>i-gu9X%@1q+!E-Y1%WXynpl0&f{%Atf6;-Bt!{UPjVn(D<~(6;KRpln(Yq zg?k4XLo(f|kX_EVg9B&{%cZFh`$Y%LI)K33aY0`Ue-a3FF@n3tVI4odv4CDM6XTsp zp^H49T~p+cFuS^lCKTDttoG+hiS6WynXvA3)*O?hE3C^F%wJ4A2kCRVg4%3YJKOh+ zMfNiRGc#~NrIJZh>LjFsa8#2+E?byVswX)qlX8hZoP-$@X9h-{S7MID1AlsK5%h@RT|V>K83jq3OIJ;_&s)sW%(KD%>Y%?k_@#Qi)RyiK^B~M4 zWeN17A|enP(=H(EQlrc<9B+ckg=rZW3-?TyCQAjH@{W}?E&GNFcKw>jK6m)q#j)~j zPp&Ck)*V<%*rftqb%CkOWAKdJvuyE``x=Y=nZ*u6(uKUn{Pd!glk*?_`l0rk+kdiu z!>hM9rFj~OM;fgqX`wP*Xh}`^`W|=QlDn3*E;N=6lps!l{EH^gohVvmM^(ar=5e6j zOqnjtfZc`+7Et9N$XQ_yNpSL5tu&OxqS`zX65&vD69VD1DN6E>gUknmy?2iI=AHT7 z?TZP^;+`W*ygm2-#^J36vWOwvnV7mnMu^o$l8Q1-V4yZn(no~uNR%fh(af75UHK$kday6u4SiySvVy)X zmBeF_by6^?@7T3t66} zuwE;82jaA_PGb)&BADWorSpf5y12&_8kAUXtK`?vaoD3{Y5 zbya~?VyXj`C_zW5;PlI1VqX3W-V4GXe+J}-?7OdRrI*~W7uR7g(3{<8FU;Xg4Oik+ z1y!U9VGZcrAjjsuahjI+9bt`N@4bmB(j>2$=laM(Pg4#;Gt8i6G{aB-o=JP2?hmr`)Sy|%TLZRq)a#=>%d>^#Q%7VOq>^ZA|+caRw zr-wu;!AYG?NF-=aq6-GTbJTn`8lf-_w{wZ+!s0AD6_g3H7%%lA^F$Ue#puq^)iSTY zPdvEj#Bd(8kgFlIPKzdi+2rYNAE*tzZ*pprnDaCzt8Q_id`Z14iJPdi2Qo?ZpDQZe z1yOo#2YON*iAT1HlHo87uXeDo0uX z&}00YJsAZdkrM{nhW)MSetlM3ObtX+_^}Ow-4hh4#07|K{6|IQDSW|leO<5=?Dt}w zd+fRWhDx)5qHVe9A-&mLpE0tY=9Z;H&%VrtI$xE)r&#A$c5b`1wXrgt;s}*8kuNhV zKV4f?-QzFWI$X@6*>fT~zviW)MK4Ph0FP~2b{BgWRvgyo2BvyHvh#hO3efMKTbXWO%M{~UlajsgeD zQ2-?PR9c!IA;FnpJxd7!gK>ghtZoLN*r>G*@dvmlv+4TRdHebH8))l$)c)wmP3R+! z{)AaO%l;%D{|WJ%xn#m!UCQXlbHFPB*eO9+uCcOhdXad74g)bIAB}La4pH_q>p#cUuZtte#q4C)%ghAN#t#6cjYZHQg4T%B_!s3wcgm768s*yu#S z#f@Q@rz-w-nbJYzL7AhlWkN3QIMw~_6xx?us+-fV={BV_R>xo z48{aoSfR8SkpKo3K=%$~)M#&FRu}dPF?XZ82MhxsFLo-hCZ-3@<(*GXkctE(MCbVe z9zomY4KFR&xtA+QpdZb9w3#SvA-Y?LU?gCv4i=^`-{bLJCYCP}=h(Jn3k z{-GVkF&GHc?RK^J4F+$6y=t_sLY1nnZW=tF?!g>c$^**ap>Mw}mwOoEvN5ht`++=NrOkb)6 z$lP(?x3gN-op^fL(nmL!N#OV*pQd?J%UWA@eXGsr&?X5Jt|W;bKD+d#2W}nAM|145 zmSls5I|la3C$L+>*}kY1(!Kc5U(rZ?!n~9Nqg8Y{fVDhAb`i_SO~YODdLk$|2hTqM zxtPC&FU|10DiyXEZjsR_N9n`JorNDT^Ceg@VF9Z|49B zbP4Q%1onVJ*?!32BY^ecKh)g@GK}PO38SlHF4ew9w7J0?OUh84g+=tjT(VB`JoDSk zx)gPJCZUD3oM%48*~U8HUr|DhG@Y1C<7g(eh<%Z!!>vh(X+LsS4IoN&_ClMM$QfwS zLXuf7ML=uH>~d#Sdo*HRL={U&riLO1FZ0s)8Rn#<2c^lXoU&|HsS>3ngJ*vI{Po53 z7qFfLsP3_bQnW{5&RR&aD?PzPWlkDx8Iu;4mWaxq{wtXA3(K{{GOYN~Y)b6#0uQ0| zDwZl}>a(+|Luc^JvwdJ57~fs(>Mpa?u0P&zMyL2tm@bL@B1RpgOJCL*q-joH(TY~5 zI=>~q9df7Y+q0TtnbYXZaeW+6X+rW7&|l~<1L&_oqmTh&fc9zz_=WK(aNaY(FUr-9 z-F5558$jQ`g-qG}Y$RMvSxY80|BaW)%5 zu-S!7+m~pK)V~JA3qK1RInN%Z}`|;O%M>^BF<>q_`)4fB*Z<; z8!M%b@&zGhl~c8J(A3o4nHA_d)wkrKjpb%&r*E$+Fbj!m4XgUvUFLw_Z!8WarfB7a zGDCwVN>r>{w$N<|lr=)33c=Y2x6=v~K`-s61(s}F>Gw3GG$K1@nxeR7px8*qt{U2B z&rHD_$xm+0+_eZ%iApT;epA1RbXb&xvt_Uzqp_jZ; zy1#Md!)uH47TkL7zcyCw%`dR8@wV<5hQg}h6~(s{GxIdMmZO(8+(}R$Uf5odni@$r zR;&%5d8mH!!3>y^N}-BPUzPrhOYb5d6YN>o00~an~F!&bG?^mv-;H&iVB9qitM!aCP|n z_XaAUDQM~H6X#zXK;u@(N*_; zc2ASFajdSOt2}q<`@&S4Hs77ocW9t|pjcDjbfTWkP_@FXA< zGjr1YvioOHYADHp>=iTOVzb#A$Hi>+iu4!Yyv<5rQL^bgQHBQOVLFtGTF2d(&0?;% zaz);j#YKj8ZHB_H439zD4-qtA?XPw)-{1A zVu3C(I?(sU97jkaQ|l;>5qglJjLtO@T4I~xa5YLv?jk7g1e+@OI?`FV!xu5v%R|Nv zl1oT=S!SHVDE^H+1LTgA)@_RhetEEbeV4m@_3ickgF!lh|0+@ZT9O^Pf{c1mUw(zl zzmvSG^HgP8%baShr#j0Tg4T`twY7uuO%)46&1<>iqkn>oy$5nrMquwm9O<(HbplU_b_}!;LN38Bg{uX>o53>N%KVEMf?o1O zDM~;20nIFD4idj5wUN)sl&dM!BQUWVp9J}D_-S0g<>)X0ZR-(S9@}>EjYvIg^+Uu~ zNEP}L$2tIQ{|cm)3y>tp=~k%oPdcO_n3cfx;{-tkzkrfC9x{*wdU86JfYQn0L}@gE zjM|-2zI-aa=RI^5X3jFN^>LGu#5Ape;V+(s4Q+OH>C&mU_M58p9#x?}xVW*vC=u&j zrp)p}yD=4IsZ1@7?~MQN=ZVJ@UY|SJR*|PE7&+D-oIH7Ww45S8WWUGyIN2s^x8_WTtH`gqFKJPW6{Bmi3Yop_vOoCKLu15MTW+S%C! zlq($pdB`?!&8785`v8GWcmahlt?fTs2_*Tr`+OyHsq*E#mx%w>R1oWvFEbZmEztb( z24jJZ@d=W_*D*l;Zh&KkEYG4zy+q3~pG=cFAq?*$CQ(%xgl^DH#re75E!-@V9=YeZ z2}@iVfeia>{6Aw4;_LM{9UlY*0?Vk;uN61e68v1qB_Uori2aM34H5d7N%`^IIszuK z+(K3{0Tf?@zGC^XwhE{d&kLy~Nv9x$z~P2Nnu6p>k0g&%4fm!U{AS2Bh^-HpDhg0T zK5o2~k1&&OT6UcMZzDlUOWQf$C@v z(G%kCDwu?*Dzrn!{u;uiW4j0XjTJhx95$4yHzRgpi9_Hu&8<3N*@Zjp{qgc|=GtAm z^38m-0=&J*T{rF*Vx>Z+bdc(dI*pfaa0b7D!Jx91Y@EAgjIhj1mN9|ltYZnh20fCw zs{wy=aOybj=RDGYfQFudAOOIY>x1J(vd;<0^yc}xEH9!>VIn$I>+-h{C{Q4&J&ul*ufYf~Bl+xJ#< z6sBY;m`9R~CS#Jpr3dp9_5pg$y$HIgnA6Cygi;X5?+xb?C1It~T4}QyCo_-{%A%2o zYvuy~Gv4WRAMLp*&lmxeM?p;LfjQv&B8@D+xJ)14FBtdlm2w+uTb3!03_oWB9AXble5)l zF~5F#=Wyq*7}AR!Pwc0}ik;wJaApx3DWJ>ZD%7$|MtbUuOMkYmab<-r)^{8CDW7i6 zosw6OucQE4yII8=5ntgpQ@+OhN^Z>61j^>_>rDS{ev&Lvpv|x*-=v-`F~0Z>^ll>4 z&HD^^tqJt50_R*=H5q=}WVR$VTqP|4wnOG6{DO(E|A*`=xKCIG3p-1^ zURlkS3$qFVR?bTH;R@(K{f&A3%f~$DjoH6{-Luq`r>QX1G|E#U$pIh_$N-s1Xv*k) zXm`s@;Xniuux2uVlsT%e!}Q9_$G`WiRQNYxa&yNx&cKSx2ZCMbyZ$+M0pv}Vacm(W zH#5mV%Q&blDX`Xasj1p2nY0jj{%jx-TiKR4DH4qf;zA}@ zfnFo;F;^)V-po_%XReAq6od2?NVvBX905(!RFZIGIr;=la;3PGSh(-zpMgeHn~Bmi zktSJL%)Cn8#ymmTGBsIAL^E>%#)l+k>WJoRS0Y=860z8*5M^nZ*T@6$9}=3_51}3Y zC+x)**b6=&&Y2-O!4>mDN#b(hDY2NBkffka@lYZh4%^j1QzY2H3r5$V?V^8Sb>_T#-r2h4rQH=2mrrd- zTX6XM+ZKImUC`aTiCOOqF0HerSUiRWV`=L}8c(f#%MN4t5=uvl1Kp#cozHLdy9aOU zPR_DtOG)$kXKyLXAH21_ZRbGX$cKa>I21Az+LX6#iu{j1Cp(y}*gE$ANP7>!D66bt zcZ&N~>go!4_|CmE38DDz?*Fe#%4D9o=bn4+=_RQO3b(0?qtM?`&!?a+ zqnhUmnCQgZK>ko5u_lp9)C`#tO4P**zS4YDNQ;4X-Ij-G^YCu|k$TO7O?#N)k4|N?_m=zHf;f*cwB-gsv zY>c!=)|KbZYbno6kWV|frlMf!zG-c{=lMm<+|JQ|v0|?e6wH(gS{ppIkkQTW6E#r zDQnu&mfBEMvdNdW_(48D^wt@GWPG&qxjI z`t^x!b9#9~T)EehHnYEF)hE-a_}IUfeIW;5lR+L68>^V{dRI-8A*-WoXh;%ij*vLg z?aG2Bd$ARM464VAz*C!xI~qxMv)MxmU9v7MB25mdQ$&x&E_m!zylU`4u;~vEN5~-G zJVerjqJegC)M2b4kdL`lSw3%TeQKxOWh!t~OqWsf=4ut(-YQd!jC&22q|Hvq_Ea|S z9MmWt{UBKyZA9rM!B-<|Z|Tlb%Kj{sSJg;VTb8(&q;Tga#ph|39KZLr$qV%7jN5KX zou9Vup(Ksp39s#`SpaQ{C|*0zD4v{ZfIbkAb8fKjq9_?M?vml2QKX`TOw~uxN7HTPrhvxe4mFp zWM#|l?4JGT_MUQQ!3~Fdw|;nFmYSZD*0H%E8+w0u+TnY1CU~N;%^F8~S(*Sc$VL{0 z$LRiR*NP>_$gTgS^BP4l|MLiCe*Bm zL^)J2=zv6JLc=+O?fJ*!3vhp*DXfdgo*tNU+pN@SN0IEv(t&z2O`&j_N$>sLbsOK= zRRgTKX!@3xL_@5PyUW|qM<^Nl!W`yx65%~ z%is*$FSc$H$&|t$LD`U-4OGJDJHg?%4c+Fv>@=myqZ6rRB7El`1qxIHw}ZUtfJ8Jb z6so1+ykHQNR3rffVi!D2B*bmg!KLW2(VzaKcy@(b&Y%;iT+UwZrC01dBX4a%N?H#A zwi3KSTu#}30{fvD$&J%$DSPfUo9Yz@!zD7qt zulXb0cHu6njIJ9!37>%=f;1bXtrz^CVc|nwZ-QtD##Rj_jEPqg)+XjL2@wg#Q-^@d z0?5}$b`&tPAJ3>wH^n-_Jtj|CMgH81Sd+KTA2(WkBzba{Ek53uqEC&iu;(wRN`Mlk z)EH_jcVfoS(rIz_1c~rlLv-=X+?*wAch4+CId$7t&x&&<2?bwCWY)aa+`Jn$-!>iE zPa^QK@z_S-Jkj85)9QHwg@6)->E%#290rv&s)2CAfxxNh!hvubuudO}0e>MheF%9C z1u>+qnq+q|iQGWZ{93_ z2`@qy%G1Me!TE!e$H&Gvu>68=$#jg`%tG)Bk}mdfZ`W;G+F;~ViBvixl!-^5OQz`f z&G$dwb$rcVPu;yNucYq~7dgM`zC%ZvpLy@Sh}_&v!(ZNeF{86GU4j(ynl%Ss{<3c$ z4AwmN6Tq{WlaX1Z6}PQFv7+$ohwbvxOJLW^g>p)SXTvUs{D$Xx7H0G$d1kt3u_ zfj&j%pa%IhR?Be;H~E^LHWuzAaU}c;Hgm>);eVJo{2}+zF{Qtxve>WeTj^hOqjl!I znbz6+msjhU|6-EqC#SjZ?<%07{XQLo!r}xXK~n3EuK#qfDPREd5+J#p$E(E{C>|;* z9V#d)s2s|QNMz06o=uI$HOW_DAm~Mj!QXO+Cm!mzlcsM?Aw={%Huok;9Vve%SnLwRlf?Z$$Z>+gN< zW@&0}QErNKW2>iUjc#&djeh1(Pr3e`w5Gi1=)yLCW?Mn@`i;)+II4a0#pqI<%kOD~ z+S_xZFUFVX61^!6(5>S8(YTebKeTC@3sDq>RA==xO?i9n>&5ryMz}wF;QrWgK8txL zL6eSSY_(7c(go^+NuE6pSSt@|uOSQ_$REb!ii|o99=VVoUyi=YU zo0i`ZDP;w?$;vfKmowW7qfv%)N>uljCl|RWR>1yEwP`3%pQBCk+rlodV@_Hj@Y0cgZ`G+&dwUV5coYxKphNlfnHVzHiUlfm6`TEQ z)>~)JooQWs&+X{aOK6Q5AKv{Yu1 zX84>%?J$J7I$EN$>GTP@!j);pyuw2B_3!MPrZGpGHPn{qxCDpY9;OM$G*3a?*#tD7 z1Cd%)j?I>%OBSc|<1%)!>hN80gz|Ctl(6Or{!=foX`%?=2)W)y+ER_1kL)G8gEbW& zc>c33(14>he$u?Wg{UZ_C17`zH9GTi4cwbzap{@|XUzWnaLe5faeLNmShA?)_Vsh) z(B4J&%ukP00 zJNt@ZH!wv9NWu=af&dGiB#g59YwD6)@1HaK_Sqh@zb19cR}C|x z(sRSTZZUU(rAvFamDKE8Q*BNwiL2o1XI7Q1I+Xci#q2;t+@#q#zUES|&Y7(AI86?N z)SYND$t;S>-iqji+GQ2VRe=4Uc~IL1zZ9N^um`*mhGby3rpQCjTPLXv^r z(@>fnUVX4zpXNzYdc%wDeKXK>?#9Dh*9Q8s^x{StR(GJ`J+;Iz__3MR}<*@lr(Bnnsahe@s6wc#8~Cmn+m^Em=0<2>IN zLAm7KNKtQiS<+EAbx^I2%N~qWGlOoPXfO`zdM~{l@)&_u0%-!+gF=+k zF<;Sm7hRG$WCl|XU17uVb&S-p_BN(; z^gsQ@W>sb})&*`IT|0U6%#4`g_Kcd%Gw^r5k^5N-kt@EvWL{}xqD2u{_0aq~etopP zqW{e;;Mn`<$s0>)?A#mef+2@B-saq>vG1_Q0NibwF9U0jOcu_AtPx1o;t7Ww$TwsR z)>o2E!Uls{ES4qUF~O{hMA?XcEVw-T@Xd&yH9N^*JzfA?&stfHYjEOq9E<9rwh6z-`=E}c^xHFIiARbd8ScGd{; z_qi8}O0s(okYdJ?O~1eXE@b@j==J#&O^GkuC3k0Jhx=QL9QpHau4r4LwY%Y-gR;*K zgWS=ApD#=-MjB>Nsf6K7sxe(36BX^PeP`alY7Y#Ud2ntSH-eU9`f1-js$ ze_Q7t5>a6ydWL@SLKgjEL~^#Z`#_KXbv(UN%XKpwU@BJxUPm}2faWeJ+$0&s>BBhC z1an)7H9%_lXb}H+F>Pou2gIyvxyNrcG;KVxwBUR9wrX2axcEm;`<905@C+_gN$W=! z^gObu-HgH#|3d9CC#7kpZ0qvksawFCFCK&Q!yXbh_GTszQ97Yj2E{PiArod<*oO?7 zDX1hsnnV-h0XO=$4w0RcrtTd44_zSO;rLIz9&)gnZUR`nAT>d6Q4Xmhia};(2j^sr zN8^Be7%+(S5EF<=hEZTxUm3ekGPqt~i-6`&jttUruuw&lvD3-yDXncuvR4#mX*}BE zntFTLj*W}!-Khl@$yaG2Ui3tZ+Y>$X~RkA@4EP$7*Az}Lz*5wEjPQXB&JFl z3Da+r^Wt<82HKiKt=u`dGzd{rTgJ2v)57x$@?e7B`aj%U7Fc#?$E{yK(B^Yd%7hB9 z#Zl1a|24{+J+~iw_#jIQ_jrVULnXMMJn8+^$9@LCSCRhmq(3nW1rB&_0nkq_WSaa8 z8ny{b*MO=<;0;sF7qI5Y_?qe(HKp3E zR`Xyzt!X#-;U}!A9>3_&X9Uv1AWPQ^*tb7Ey7b9DvLyE@S&~a~qf@~p8Q%D!&CS6@ z$)q7sBYTS1z;g#om1Voi%iV=F0}<*%7%(JGV+RyWnxBldhe@U|;+uegQz5Xof9$-8 z<1PdcP5jlDlqr%CIIpS)?p`uw&O>_tn~K zH=f{reaJh%v))?$T+iNr9BfXQvi^7fd*hM^0;#5w$&K+H`B# zWdU~-cSaQ*uB_kl&iZLPW~7CQkR4GR$NgQVD%<`JrUURD^IPCdq9E^{#pjNh6L2Tm z=A>fa?uJ^mlY!@0mxAB58b}gv8GVO)r|1jrA8CF89SKd!Wrzwlyh<|$l%k49(;#b$ zhbv3YAb*EDrGIbPEyZHBxa#*SP_DDgzG>0Cn_l7mNu2;$umw0~J#b7N$YMOlj;HL@ zXtd#-45N+cRH(F=agy)|$xy+810X<1)eH#&z%`~0HSUy0Qdej`lB9A!rGC2dktG?K z+rE8l^yx3TUs91!kBZLBn|G|{g-P>^tgP$o+3dLkQ=0BsSIrchoqxez-^|@)@l^su zH-mPt8=`MIsGWp3nOJ~I8U09~1W6#{h7bBwDla==m+TS>qjv@3Vw`ciqTDgG(`CrRL)8b&YAd{#9&mwD zj3>dvKiAlV81N1N#+*bXV$T&{gBcyZQegYziyZ?mVri61MH8d(m7GUs&%JxaBo&qC z9etmYS$(y=<B=7Y`i{vI_x26JaRFHG zzDi;#Dav(6xb56qVLFAV<*vVM8a)Q#yGPc3^1zH(XmJCbfk4aQ6A3aY5N#cCIKoB( z!UUrbx-3N1XnUa(k3y?efG%K{_w)9{p+I04v`cy@0ZSOtTrl{}70TDVe4|+01n=MY zc&Btbh+G>^na2mDXHP?)S@)DuuL5lZ%H*y?9qs1)K$an;Xm3^5?rzVAQ%JIB^Ba-# zZ#%J^w5FxLG&v)o_kw%6d)8cFTJj(4F}c0Bw~DxVkO?{iwH{beNSf|a7hyybs|2c+ zfVW+KRBaH8pco#T>Od?u8!dn^Vhr~9(R46m0A(Juo>g*x$lOrIl}&~_dLIobrY~B- z89)g&2~T#T*RSUuMh!P}QGm%p)TWQuXrh!Qb==4!pwaFDn$^HPmOunbepD9@>*32h zzMjDDiy;Rc16*yaoJgQ&G~C}@O=<6>r98=fL@hwmAB91rh-E~KQnq;#$|?Wx#~SW9 zY)<+yf_O14i#8}zZRdL7K)^>Um<2mj^Q_>N2$KwgU9GT&vnmnRb+DHilip=}C4_dx zo&~ce?itl_@2m+D*BW#Ss{0KLP!*$302ZEr?^j|1s>XSIj0rXImV`<6V7Tm&7%qa5 zOK=5o0y#B=UjuDijvM|&++6s+nUF&R3jFXJSV9N54#3o6)PFU$E<#+6zaOw=hg>NG zR48;x#6lDq&sT@jkW`ij*doYEX5p07G8U92)(7WhW-kQ`*$=pPBr>HbsnolGJ3cSJ zt;Cm}9m~Dyo!U5U@s5u3?A+0pYZgvQj#P6`adq87Aq6&#sTxwqpR;a1Q^q}R^hQRc!Of(|1O-3f4|lZyeJOkd2FD`{E7!>7 zmjJapW57ELpkg}{nudcl3ef8GI%LxaLz~PKoJOIj$*$neRxI^LR6&SpRo{V_Z;_SfrMs+dc~GBZ?%;>fTnwLEX$iO%<3*iKXS6-*|VvlKRRQT4$vJ4wFy55 z{KWzcN0LYF#9VC(~;lQ;>THGajHizy)dW3j7Rh}x`8TArYoSJ$iLJk z7wh9eFNY5-Lx=+bB|;`K*yF?|9!r!*pO?1#^(!_!?RjDQ?RuCi9ox~-WJ|R*x4So; zUV8F0ccErMdR)u4uDlsVc7v~}?|}tcuRmRroSl}Pc|%`zYlq|_4`oE(v?-;kr^J>u zx4%K0niKfeo>3B2--3i~oo0_iD>qscNGCO_StLAuocr7~ZQZ22RkO-uOqjoZUaos~ zXLEiGP1A9S&IEJhtm$#-5YUV=n^PJV<+N;WNdlu1bmZH)>GYpi9n6)g4!HWf{oegv z+MBW`vm$OJ5Qwjdr{d$I0(t8)6$%9?&3tWVpST}}MDwF|gSrBy*BCM}rg0{Z3FgC- zM)T|yn6eYi1l0MUjfP#u2Tf8>~?rQT?@h_Cd zAS+9s>)o(1WA@ILtJ@GS&)-P!%w;Cd8S7lEh%Z}mz?hnBj*pC-(VUPh6v@k;&=Tlvy_rFTpFPv#^Ie^{-C5cpaeFJ(Uw1$U_qryOJ zs(W8-PTs!cM-x$^Gs2k-BC}d@QdZn@cl+*7 zhbP$zXBEvrf`@PY_>Knd{@BW%qWYWDoqqKme@5@3D97s2Pa=1s*h%w?8wb4BRMk!1 z^qvKDN!`N-Zwq)DvaDSXe6n`>lMn9Ao3^m|t}lw$PjwY%$Is7pdwq$*XI#~5np`D; z*!Hw!AEf_H?Bx{?Ui0*TC1WHeVZ>lnr@OwlU$j&9fKpRtw+ooxB@dwS=4)`Mu zEd%tnv3m}B7b&Fnz?xWq~c}u z$xMz0`tf>w=TESEFPJpZO0`{KEsv)jnYy;d;V7A1kPNiH6m;H~L8rH4Xw(=QIY2|Y zyZ;6>usTkI8h5nt*%RE~Xh)Q!Hf;WWVMbHNMPT#?$#MA$_Fb7G#Q~Y?o6M+^_ z;$y!Dj|iSPxF5dLFptzC8DT#M+b@f^0QwC_RLLu|>*$`cq5Ozh^9H9YG6p360df35 zc*1}Qk_69y33%o#MmV$^_K+YL2rRHN1R*;RUmG7-T4O#+0bGvUV2r{S#fMk1bIFIT z6$qY@Gr9sPAk|3dUa-iTADS;4h6l`=v!-UHuDIo{Hp%vnZmUI~MWqGj%u4HaW#B=x zc>HWw%?@^1T2J5YGosq#yxLq#R=2b66sjzvDVh;!H4_m_P@fZ^ZX6##+XWM7cT9QY z?%~|@DcQEJwtGLN0^_4-yUI%AVHT|qPpIvxIPaVajmyI1Kgt!p-1YRYqXSXZMq{>f z;>l?6$@SoS$yvmDCLeUn1gQK^514c0*@*>oYsOGYM9h%DIV7xXY#FLln1?j?MGk2J z%cB^>pe+EVFQJ+7_<}fQ>;gbAj6Bf$LRr27@W=c&sLe6wb#6YiK!|7CMr5~beymr3 zC$gd3hC%_JZ(CI+#FN*U3;!K1(dvplF!|12H{9mH?(iVCLAF4lh$5_^J&HA6}7*$sgdeRfM3r7C1l#o+$rO!&W zWVmz-MqXJ$UTIxQH=+~C4q<6_-0WqmGdJEBS(FgPFV7|vw&A|Wa@cFm#XW2mvm9*9 z9MJm}wyfwOif2){6FoypwH#C)&*=$!MbMCfL^NS%AbWzzVm_}LwiVnHNG0s$2yK^7 zmo9OjsT-T(BXip~J~VGq*X;OK$h(TnX}j@(Io09udHT%hdA6)nRkq8hC}+G~Qnhen zK~=lVY$K=lrKnNR3b_q)c}W2SJK$9Fs&*!;J6jv;GUWp%Mw44OkcnCNyVxc9=hJ6i zBg_SOITozA6ei?{hI7N)AzJaj_eq_l=;bav*BsK%CQaoDl=e|Rbv zbk;>yo%p{zl`*X|X7(tu;}g^MFs!Monyv%?uW~fLPZGm9Kl)8#QsdSxd zC_|B^f<9wUDs^Ql{g4zqN2Bj1oXk55RVAiNXmtQqLJn@gB@O@tow>k}fstdrOv;al z>;DqM!4K@bHbQCFmUpoOsqVnpy^cbV_x`Yi6tAgnaf!8~!(KbN%#^gMu4Y9|Oh<Z&mgkTlX%S1UAvA`z|$xtjVb zJmj>2duB@Go!3utcMhH!y)ARWjCyOKxwx)9+mbNqyf-=ZUbepUQ63VPtUs_a|17p1C#SzDT~s?C|*D_}?0V;CTXkZEJ@ z0H0H9z{MAdSh19*83`2@hGYr|amblUmK7?+l@f_i$*V+2sFYR8VtUWzVMm87tCuKs&a4z{13Gh?d`@n(CT2uWo*9 zP41#aRj)HAR_Ej#Pfo`1tR2iw^dLVR^s-J4rnJK=*E9X-1sI1YVB)xEfGUN&IPM+6 z<7@-2kpZ341^QYkuO70Tw*<;_3d*Y;@hRRgmC=m&1$ou2lj4hGytN)xlHBYM=iBH; zR|{&%J5@aCRBguAu|X;$ya^x8tm*EawPY!G&)m7Q zmMxn#cW(F6<)bIaYhC2)=yUK5{?gqIf8p*Tui+EQ0ok=+lUjIp z1`L!2{QEk+-mC!cg~eh3C#_5-e^!cbuT*NJ)e6j8WD14yS(QSiGSQGr#^9HX49gm6 zu}B0holi+5F!ck${AWXWI1J4^_qgd4#O=ZTd^Q7SfIxOOR1b!JhWmAzya+#JV7_n~ zU%Ajv9#`-r;Te32aCG3HM*>Lrgj7%DNN35v(C;k#joI4v>JDz8e^(Ey<6i7XZRZoX z{iu_D3xDN4>3L$ug%7zq7oaSvqh-dY=t)Z_r$10=uZVqR4o)CP->yEq zG=qDvx2LatmslgJd8jcihM^|iy1FZBacw`#aw>LjUe8cZ{Y)+&JydthF$;UoAA~$| zJipWllLtY&%f>K9Niwr@=tLjXdnv+o&@Ls4BzEDj=Cy$YbrtMD(AI6T@gbLE#ZS0q=4Ch!2hgdy1N9;(;M-}F4e0eMrFJKd0tKr| zAYUKS2xusJ8dqP*F+d~lp!OQ70<&Z_A8P1%a#Kah)Eg#QwqpM~J;gtI){}VSC-=6k z`iOh!MDl_Kv$z3dvPb2wIkvKVNp;-l^*E*fA0;=R-uyiG?rZY|GLmcX66D7);D?Li z#XJR|J|9p?m1T$?HpBc)4P>gQhOtZTED^l`Ujo4A8`tzmL}+4=8T7-<)C0$-+%!F9 z>y4T^?!*Vw9WHKvv~Bgtn=57?eanI-NF{SCUv|v@>#w9#rO53GgBt`vRNxxpymKbVYf) zE3nf362?X-&I?=*xbwfmM>74NPSA^Py}R!k*znGrQeym%hw6FePAd?*+pj_dB~@y~ zzcpzOb9(j*xId}TdrRhsis*y}XekzpDTM~V5~fTQIAIBo=Rxt4nbqT{7KGg}c}_?- zz~(#av$3bU*Y~gQHiTtYHC1JYaVtg1IYl`x5!50w1KiW!ZA#pvM&;ZQF92X~wDzt2#}}1nFos)Ar{4`EPP}$)lyl_T}rA zx0^u2!~M2C1c_k4oenfmFCn!^T~b;q)rax4e7zhBX90E$ek&0M2po?DVt|w6x#55z z?Lju`0upiupiL0>!mo=&O3^|m%5$Pj_=!8UjzPQ8O6VB$8KoKhmbo2V)rSwmm(d5% zae(0-@b~`&m`j8X;Sqxtnv6h&d9GKX2}gFZhY=%)f9C&0&@bHl4C>F@{$tz>Akk>| zWtd5Y^V|VEM+Q*w1;aQ1Pb{Gj0w7BTZ<~H>eB1YPFQ!u0wO_VZ+V~|`1e=6iLd}ri zZP;ZPWP2-_fq+QD7Y#(YA*X9lAOY^`fxhD7-Kr1}1$cOgmlx_D*k8C~H;f)y%{>L8 ztYkG+yP7(a!3>`7p^8WU2LhBYQd!);f~U!T4KRlR4_C3n&{0(&9*%O;0<91YlRPlb zgqB#LPY=b**{8WP_v6UozNy^r-$!|q(agzIJ8iu1CAyb`3?ObB0w*hEv2e}83fM;s zNJLYIvR6qdH9Mb&bQ<#jf?mBgl|yA8aAI+hmxpySTqBGn2D(f-#9Sdig1cppT`nBr zCdv@=7VhaEM_>8}_dm$RoTTrVC?sT;3lV1B`E>vy#t7HVzYj1H%}acWX9UTi1<7Fy zAAUoP)b=5fh>uu0I0-A*)g1#1;=?wUL=Xg82BAp^?o5;^-*YGK=l0zXsG>h^xJ+_5 zFUc0#aN#S!-0}&+Lo+5;a2$NW#jn_}*dyQ#tAcDPwR^y?E|1I~jE#*{4@jBF0Z_4V z4jaazlH_2rLEi@B1Gg9Cnq10LOAR)g3+2YcJaz2tpuracY7zqNh$OUOR~gmU{oJmW z?1i^I_4X2_U6~zb3|nw;aaLsJv>c&IXpgDfc4~FWibnU!9+Ar9&opLD9a*uo;x2S9 zF)p&u?{vndLr-5rDfoZ3|Mcqq9vECqaeqTp=lvhAEnZregtE8S-~7YlbCSRhcR%;X z>ll$TjQd-xFVal=s{#qrw#~@ziI1JLd=2bA_u}`=KE?#~=4AKjBU!phmco(vc#C>O ztgwub80a;2Pc|8901|4{bout7)mkdns=z!YE>HwPWSr24oud@fc=x*Mt_S{dy~tqD z^3&M}Ve;hs)F`DUvB)iy3nMN5xjS3(+Vicmn&DSVK}3AnOwY79-wL$AXGw~XsWdqi z%CtGR&mR8af$4~1s8<=jGry^GwmYE~I9}Ryg;VbCtBNme_pba)Gm^?*iqOHrROgiR zss>ByWJ?+ZCU7NcE!ze9LoDbIYSRggRN;~$snjAKkdyo`Y&b#uV!#OsL@2}#-LJ7X z25u5Q_)tLroUs5j2z=1NphJ3EOf*lKri!+u>RDUcNX`BqH@{;t3uYTo72=Pg?QiA- z#5r6o@yx`-y;p>v(AI>ZFhy9HcvxW_YxhqNks=4M#(Mbg#i zO_0Uaw6me3BXf&8W%|;}2>|bZ;$CEaqI`P_PTQJuWcuvhMDq`Bbw|@BaFu^PdK9_u zvxEb*_i!uN8ejoZp7ALj+<<_H+9^;W(I95Ecqf{1<#_>{oMNv z-~7zY_A^VF!3%xV=nQl-GYCcYgqPeT$N+1g5KDNKb;vJIk~@w3-4d`;dTQ2F53%YKmR)jttJDRJl+ZOu;7t=$xm4ar# zoq`wn6i)`YlL#dPa+Qcr4U(eWR47)&k#9#RH5T(qyjL4431ZIAEqI1%`X?&>>5c7x z&+|*cl0X9PUl(p-)}QYiZ9`kZ1606mW}anVr<@ch)ZkJ0U*6sD9r0e~RuVnR#Ud%Nc70(?n z_1b_+kY;oy+Db)^*KDD)oMyb9i&_NmECV?EL4qW}w1u#!VTnW#uaQ%`1zI+A=)t}s zpsxVeB_}=+9x(YXL4*&S>1vF>cOA#oe%4%ca7xMC(rB?T7iEZKvM>?LmlzYQ-nm{W zfc9~VUm3k0U5Dv_ zOh6#PX8IUTp{`7;@pwo^DG5$c0!OGs9&=Se(fJQ$XybyvZOrfa>y5Yn^w2cRdzFFIC)_~{jCdYs1ok}yb|t%%%s}eKOI2P z1?^dtHxwk*#dO{L`Q0rQ+uz)5uB_yDWiP1zhWs1{OKY$ckh~ z0*-_nw;^Yw%nhC;ocrDj1sY+y4Z4gyZep3A#e>(eX5~3)stVptNLCe)+*uGMAScIC zAxJ!hRMKHtfiGmxwSc#&^Rfkn`?w1)P@0sQY#6=XE5P!o%sth;_GbjF;wS$ zt4rLqbFv*N&caqNHHDlhS53~e7(Ahw0lV^q!R7SAv6d_<=_}b^a;StYDapdeDy9dm z>dAvy!E*&kkui3#gawZuEeQq&MdSFT0blz6hr@0xuBv|f zr+3u!UDcjqLKh&SE+dSfDS9PofPJII(Z;Kh_TN&A`=%P`*>gF@>bm-; zC;ZpcV~iIgN2V)gBF>fn$HlawU7Hh!}o<$7dz8R}FuU`_Uty{LU{s{N= zvopb$M9c*LqPyqica=nsz6+MqLV-vKWftwr`j%mP_~OgpX*vVk-p)&Sil+p7K?C-J zQa$_z7&s_=Br3{cw&ONA!8|lzp2S>0%wleTCfuUe6>8)LG9d{7^WI>;REOK$p z(3fv7c-_HTKm!3jL-WCgH0+ea_#>KDfer%R+e=pDB@^{=?0ishb8JFj0ALM@5ERbsn0zdu=Na5n208_a4vI*OoXqdn<+~w8} z%Y}@b(gG-u#D5tm*v5l@I7KFeCJ;B0iS{PSITgO_p-;Ag1FqEpX4IZT#!JTMg{n1A zuF4W=FlN@SAezF8kfvaJg6If{K8DhsWCqYBO(AH4lFW77(|Dq2zFbv!g8OF!_kRE1 zGJaE6;8sv0Nc4Yd3O9u`h3J4RYIw4w9VXOCXiyihs&JUUn}+xkpanZqK#k{7#FOHI zeoAAqR*hZ6SLh2e_pR4%#uq0g`jqlv58f0eCp$|z1o`XN- z0Q-3GQ$Ww_=RHJt&tl*`(7*+F(Ey1E!u$Adk(##yHtz!&6A6t59JQvg<$8S?ZK1CiEUR$d3Mm$!p=fcFOPF8~Zr96P8{ zW37ldYDsAlJ{z@7WrJ*5(AO{XT986Qmh`)VnmMdGY+@WT?uH54&!YFZ7hWGzcm~Fm zo+up-jDr=T!l4_h3So^0OSRP21UzglL}Jjv0U8(u`!N$`%@|l7%SQ9a9FHEH=_+maFm-LmfLz=>82OfW{cEjjET@}7wG4GDEjz9U)Y`n{tar}U+$%XLK5PH%#wkGM)-cNRE4(_rSKM9;tP)YEEQ)uuF zz`F!4%#1_JYXVLwSh`cMH%Oy*CaHNlrD_9#0ARr0 zPq0rNFvc>pG#&JULe(-+CxX2Ku)!ZPULie@avq6G0&sMR`S#v}i+p21z6t(bm~WCC zURti~Muj~IU%inve`=x1S=YYkpT|E8!pi-Xo&nYyu~5j%B9l^aNOv zX%2b9cy<+0ilD~935i>)_7XZ7zXI@cYjQYWB%kK?OXa(kL` z6|wc*Yf~>5}j-fx|jUeB@&Er zkDU+Bye0Wg!31t_3J`Hh0=PJyOXn#vyf$}~K^!`qU5BDozDcbaM`E5>duw--qpr3( z%H^EW+UfqEH*n>Qw>ra)>ivFoe10-MmG#$UO?GRZE%c?NiB$&q8HrjZSR1O5Va)CT z?BGdm1+xIo#>0z#(kU1e3L`uzSm{k3@aU9-5#($@$t0Hs7Yqa)j{oj(1VPUg)x$EY z`>rai3I&VFk!%*TVc4lw|23Mcu_uPm6l>?HQAGC*H<>_Y{{#H-=yM|ku`jeGk5|MHvk0=LEyk5B)PIU;q12#AeN;C_w;cWYyOnV zLOb57jJJOS^Eu5KCX}U)kejiS^dn1Ibu-sDc zPNJf8=Ak&95(=BpFmA*)VJCJOZmWjlUU&;$6@)yoaYFV(I=znBEp*#!uDZIWIeoRt z*ch8ALE_N(XUys?rs=H{*p;eb?Y&*?yXR&|__SfiS4Y;>$H3>&->_`eF_iN8=$df` z)jiOfm{_;6GOifr|M6TL-9upA1F#O6bPxm}&V#EV1;DUzd~N)q`!B_0QO@RT;Z($4vXrld$s9b34)ixZ z?m&J^M$s1?piMa=S)B#CqOb5a?)0k++ASYjXv^^P);Fw_ z)hafEOkJngp*WzR73v}J1diQ`2ZCLaumB**3?4su2-wS5Dss``8wz`$J%4Ll^OR~! zI+;8*zay^L>kx9^rcn99sO*;Yzcc!J?_Ye^w|gu25{3AJA@aE=<}ETN<~sgXy|4fJ zmNbC!9*`v9N#og|T3#xZn)$#9Y>|U7B?`wzLYyFUm{*ZqFm6J9eXUE4sjZL1pCF2Y zp1b-22WgFJ#Q_zJuU5ddl zYnn(`mDfG6c-8(^rxa2czT~>buV(v>j+Bh1p0sp7kESA+6U_hcw?Rgz9DGtx$xVGY z83rnf8C`uZ91b6>wSU zMa60G1N+ItoHr*KitJpj?A)Z_cL)r<%)G$-ng1cl7dB%~W>{zD^Hjak9a2gTu~cw6 zww{4?O{Zbq3F}N;lN2JecBV9Q(xl9+%8JoHWL8$^x)pbDO8CD3aoA&Q z%;YPfK$(wyi40f6@X0@U6jcDYe=LN1V?aiIXhl$qip2HM!WPCI;bGJvj8EJ>b1T6z z_s~S_j$@TVuQT^SZ~HspL@hkuVd_JK_hb@>l_5)*OcxM_7fjZ*>lW!~UAR&%L_%2T z@IF}yG#5Yb7~rYuOOjtT1HZV-)E2Y z3T|hAdYF3=I!bE{npCT2N{(G?)FxmT5N|8KL z=@#~S#1vVEvzDKb%FCouR*^44IXo@$^P=E8i?VnKWn#;ST=9g2(;#RvAYTMBxa^?8 zLnIrtdC*Qmok*b~Qh-~QK*Jr_{=p#yRXi)NXn9vZT{W%U*s}Pj@O~k5RYc+Dq#|ax zd`hl&T8|XS#_wC1uq!flrd`TUaA*zLU};=L%q`Fe?;h~CVmTNF`O?tIK_hjb_)P1w z0GtMZkm7eBF)oPfLo_z@|Ez_A{idS1# zQv>b-iu;7wiXz~AR8S*kc#fxr4T)i6Ciu<^Z45poh-e5B5H^C_BhpZd5Zol*Qcllu zh6$fOZGF#DLHM-k(aS9~)81=kXlCo2=>YlK^0GNCQP%Yp73jdAJVM&K2fl!-193kC zmR=&dOuDc*BZqDjn;g1tUwzl0k-5wd6yUW5~mK|X3x0I%qSuGnYCh0dj zhQqa;4vg9N0JE)vTOg&#&WnGFr$XK%N{TfR0+#`bZI|y76F8m)c!{!ck4mTu_dt~j zCUF7=fx~-zpMolzT|HG~teZS{rhy9VLO{)M-5}q9%q0wEQ(&fo2?=rm zF&zo+9f7o_y!d=^?#P`ZMbxCOTSUw-iVD+-i}KvupQ)d?=bCS_!EA5N1F!!MaPQp>ca2L>SkO9|$05Z@^*8N4oJaj5DAWCQ^~9V0Mi zIG}czwQSBl_%U~?DSM;`sG(xfLUr|$jToM2sa9O1vLqO}PmvRTE?CKZPVs7{x3#U0 z!gI$901u=51K^3V2E=j-eNSDaC`x)9U=sit@(JI`gV9NFCK&euz(5d)j|?#j%^tW- z8Y;Wf7{(XMZ~Y181I*>ar?xV;@ZJ}AAivXcI7}gW4)!a98ozK1M+t2j0elc|j%J&HaE()%b1T;o86% zDJ?`*1xzgWIrz8`Z!Wc$=CLor9$*pzlAM!%D--;z{GMoun2(GT*d>Z4oS8cGSrJ9K zi&TZ5KKxlZRkNU?oMoxKC`Y6aq&9Fb(h1yy9p$-d+~p^@N)D`I=h=?JB7&bSSZs?$ zVP%%@wT7RS-;%WJ1UTv|RwPMBAw?PN>>xQ$SbL5#F!#23?sjWbWPQ@~7P%N885B=| z1ASAwss=9foeD*MNlM3#*kmlLUW3fC@7UvzK@8mYZhH%v*8@zenk|D51E9`&OX&<$DVm~bw?I8?SRx;HZQvt^%Y zsDk-nD*A$K!&xf2W4;hRDVOS}s+ebkpM=f{#Xqut4+F^YM`0`yfe(-a=l6Ng|9+;W z@)w9SaW?znaL;Gd-j4aAlkjO6rYJN>rNAfIKttA8eulg4qF$#yhQ166)sJC+*9Jc{ zgb%odnAw9Gffb6e&mU{;?n6KMV^$}d0gbSnL=|hZ_eOd?g9Iy@(rPs^=pJQ>E1-0l{0ka-K!s_g=hS#to;<9|oW?FAoT5j3T6Tz- zLLw=&F@UdxCF?vKkqkCmk)<-cSwC%Uap=J@7Dy`&^Dr6^uaMLk`) zkbAv1(yGJu`yJF?CIQy9^2A5NzLTB<9Ktd{`N7U*K=~5}O_8Zoz$Da60{8cCz+20N zDVKi}@vfGoV9Ef0>xTkh85DIBbA0q8=mIE@lDX{Mk5m+QLLRNvJ7g$}dr@eVgvrqc zjC(a2rY*2GOal#Q<;Y0OA{E~OJu;9({5tb7Xat}?F2=K=$Oyw=$>bP4Lbn{kvqF6> zXbbmT@$H??3R9Fa-sDUSi&*l56mu}0<~ji9)$3MCB=?BKW=#Ts^NY+Rkr^bcI|)=& zgc9fbCf3GDH}riSSw6WnFB zFGwY!HV)L&kuZ$R9$_m;x5ih@U`}juIxXhS`lNzHUqdDYFc9x!<|I1HpBns3bRxie zUT`90RfIkh34)!Da7PI2vO#Bq9~xcYu_RQ?;7{FTcUo+l4X&aDUwsCqwr#)xjc#$;2NNh7s{AJ*$lp32my?2PmXLtJbE z>FKf=pm`ghiNVkaEz!Dj(5W?gA~a)u79Eyi#8nPL4FDpAKzPfb~Mk@=K7&4b!O7_%|{G(75qQZ?qr`140nXxnIKBAs@EtN#J4Quk}1 z8~ls+KBI%!A0H$r3%3p~fWuBBJMu8PcLq7nSJcK6?^B2cN+hJ-7l-@3RB z{sxfz>mdFcMg9hS+II0eI1>$sJkMmhIQ8)<40P7YyqGHXn(qodhnnB#F0Wfnu$`VUnl{8pJDmTS)3oLyZ!x??3V;ACcILyi0 z49{eSoDM3!Tzpu>07<+HpRIQ2vB<`y0WpG=$RrX^PDqZ<%-I;xMCWa5UaCD9-jjgg z+eB}sUF@d-pWsnG&xol2icSSFxK`7rr-}#G4SYHE>m7YNzM9HB`uyDIo?HC;=jT5E zJfyWyytSx~-o=~(t;TUvfzDy5wVtNTLDx3qt60 zNCb@yaUg~|7D3RU7wjy68uJ8t7k9H*tCB*9Ry#ADzx&(N_qgv&X0=*lP%x*s zL_@ka-RQ3JMoz1?XJrOr(QDi*$TxboK20qLd8To}?m9q+`yMn#8e}p$M*%}3N)6nX z0#G^l4I0)0i>I?A@ z69+6#r6p_)2Me+-v0dJ>NNYpYo-JBsbn4)4rOFu3s|DC)--*ZciJ(mYCV>rMlRys~-bXLx zz8m^yE>vlVg=@K=k$%T7Srp5P*|mVEuetvn;7bK^(N1JW*4>O2^owD*6H&mk7qKTP zK7aG=upZh7KO@+@1WlqK@bWDTATP3pMmFqe|d2C<_S;Tf|n_~ zvRsmgcU3KlO4HaEo#j>_9wsqBA zJA#XXl6m<*=f3Yuf^GeMKL2Hb5Ht7Od+xdCJm=hV&k4StGou0>@&PRetd{8ar0%<; zr6I$*?}?TMD@&HC^Ow>2{9HBwXAx2o8dl;2vQD_k;U|qHAl4JlF4*$a(+f5HBcKx# zb=c9Y1PD6hL2A}ZHE4g{{~1XVqa3ZP9=NQ*?wichyEpTd*Gpf~$|EqHcQ9fQPMDPi z;?17XEE(y|UWAzj*Apnk)by94xFvG)JMJ2(K0ETRqPyByW!qisc6AiH{c|eO4S6lc zo6dER*8oGh$5Cu*Fm;#~o7S0j0oZfYr01NOv58bj(fS5ZzbFciHkJ@hY*8zuQ&o>S z*_1D9x}>*QbC>!SLwuswsCX$V8O_^Fx0v`kU?md+B=-;LMr#ucD`b#%KpS)O<22;0 z*Up0ILVi^fqq~bFq9W8K+(b z{t?aaJFV!(af^{{H?sN0HE5`X;b?aG+U$BJS0qMC`8&kDtGmDS5beviIuFfwW#D{R zW_KW{u9$Zk*#;w9W@JW5V$X5b%trwJ3vOa$FjTDmL=km&ak>IH015P6>p0u8TM3M#ovZCWgd$V7Cdm6(0q&?oEaZuu~ z_c$ihUrTyOBF*!>!geZbvBIV(te?`Upd%K86NOo5n@@Aa|3E~SfHEd%Z1z4hjR&r$ zoqB1UcPocQ>){7VsCZ&9{sD>o(a1WDOfvF^1aGioW`N0jFoA|ddsrG>lLO3OlY>Uc z!8F!WedBGNgJUH2$npb}775nTk%v963qa)PKqkZX|6zjhSlo z5%qoh*e@UTp3Li@vHvEsG~$D4r|~d0@meEWY-H)0q^u-KL7h-ye2<)r6RZb^#*GoO zV$)MB^6bVM&)!`E7Z`6()@Yn}m_RW#MF&Xq*Kw zO}*#Z;>kN~WH6|Aa=wyp=6pJ5qdDu(=~%8evZX?TAoyiMjrb&prmaa(VF8KJ7~+wQ zDq)~V66iKUM}4!D@n`-HK>~9@+4F;RjCR_`CnIS;7`UDCVVQG0L0=@Z$ujE%+pyPQ z3JnT5A_*n&p<&gcrEF(+m$Ino;%NCceKcKe3OxzeN&ApkCJxs&)rTp7E_q2z~R-eo*uB>Cm@NqT=-ti}n!0$qH8|M{rnIVI_++}Ex;#Qv5B z;qopZ`p@!B_gzN6)|0;7c&m{gmDvFqlVB@2n=ObhG_L)1VFq7yaqv^rrEuYESKZHs zlg?5fA&P5Rh^DuC)@*-RQ?I&+^(a@c&8-X7Bd=Zc><_?7O*BTPz)OCvnGH>ze4J_M zyxSBuTw!-g>?R4why97OF3zs!Y&u7_cLi_ZT#{jXNT(F#S5)-OS}+T9r>$~`y;8le zUG@51%&O76_`wGX?bN5hXqvXl^f(SFY`4PJDr}j;jtb%HrLTHef<3^fLfRUiUwG3! z`YK+K%4ozl{Lf+l1{bgD#JJO3o%nv8ir+r4%^H^oB6y0eJ(3(~`DE~DM#$^N5>Y1$an z{{)hl0PrjH5Q#a68q6TtK~j#LB0bqd7z8!4{uS$zmb-iPa(3?=NSb#6(cQ-9z&*c= zGAhDsGu~q4pt?X1-qb@-C)JBk@AIRJ;iBDZSF;vUZR# zv`=a(3{RQiT3}byxZP_vpJkC<_~4Hp0l5Yl8cWO|~H$n08qCp03Yb`!q|Q4Z_@ zxd9}rx};*|PM1%Z_N6*R)8J{)#QJq`NzSM1WvHB8d`S6u*wgJF#iI19IH1VY-HqFE|k~$smz)wmyoITX& zT!EH`UpD`ry0(yg`SO*d%4e$YgOc|t4o9qqFTy^*Vq%X9A~>*ES}!`9`uS}tjrXXB zu%H8fh6G5v)gM8n`*kU|Hx&d+Jh5LJ*}Fyrz1ZzC`!i<;u#<`j@4$STM?XY9ts^PE zWn8J=hw*3pvrB&Y0tUbMADL>wfLFSlqor7b^Y|0m8 z8dy`8`Zml$&)jI-$ipVK*0jUK7nvZ-`mp|8(uO5fKyu(8mvC${yLIhfutUP1k!opo zde-dpgdZ_N`;Zld?}78?-xON9cEbF_0kvYZ&iA3sy1eC@7QNT6v1>gU>j>jPZ8xDE zfdYehROZ;7E5+^@aeDFk4=2&bU0u3-wvy%!U&N0uYt=_*f5AQy_>y(aQ;+lUn7fZ& zfT6{c`&Sct#K?&15u*eH1V>_nqEjCU7Xl=~tDgZ*oEm)>d@?66o9~=1QXiYbWOgHA zX_T_*8mm5p4Hte;4|TjIJS?bTp(br*{@n<36Z6Dgz$fx!(EaK=Q!i@evb0WOrBXi$x(!5p$N(L($Mg__ z&h`5-kE@SOV52vDPh#6OS#48?$=8vDfsT$0V8?eUY>DREO;w~$d8y2spvQjKihS!4 z*!0mWSnwu6X^i@3j$jls-0zpZ8c*6GBijX4qg+(@OA0$K;Lc{wmTQ9WKV`2sGPQKi ze1eAvWGXdPdzVRw$MjGmEu93H9n@Y_-c|UGLdFS%LJ+ttRU+@Qd1xR#? z0He1mY@5Q?3&Ac`*t;@&L1ug8+hx8?M!=mxS^9;$NA7y0PCKc-^V%DkUYvR18G%f( zs_y?>5XclW(d7>)2Z~|4!qzD4MVb8(#N-}IzjTbSQXi;j?4I@fqqN4RI>^8x;?~Q4 zi9=l};e#wSZZMLXyMgQ)Aq}$*N=2zAoK8~9{@u_J>3dy^=JPTQky^95TV#QLePjFN zYlj{ZI;ODIFyy560Riy5ET9LUU9LngmoM*U2No{n4jp}3Q@Z;|FRkgdh5$p2C;e89 z2(WYqp6c;~{B90fY?Uxx|AU-=RX)^tVDWnP5Jk^`I<2|g(R`MOp!vBbR<^@<$jBkk zON_v}cgh^r`}eQRhdmE0-o=`A>}k!tc!C);4d>$_;XbG_gGoc5I_~R*KMyQA^bO%p zYu3ey0)OI@I<7#LEPp`LysyUNEs;I_!K-Vh>B~E{ScH4oG~J#70Uppq-6oMMj_$zkKjh z7lj^7sLLJULfy7~rP@aEq0A`4L@w`5t^8d9L3>kg^5iZ?6qZjlu|@$7H!5tZa3%jB z-6QeM62lyH@_yRneO*qNWTO`%eO0X-$%nkU9J0Ynyf0$SB4Bjcx`%nnZa1-QCPr~! zKHJ2Gn^-m&LG(8$yhCAsMwEfLFyr@tRZUr3K99yb)X}5)kb`&9sUGhAp_#wyi#zys z&y2`b;tNKG*v2|}m(2gb@8Jjuv8(?VZuP_OCF-2feCW*gyX0%s=tlmo&*KCIUBa?G zF&pK*GQSIBZUqH+XRF}j{2aXs1m;JtOsyKphjz(-^}gK(p}|WDUE%_eDHEvRqMPL5 zCt#B_H>Rd(?pNXMEUsa%uqhOoRUey%sy)pleLW*Jd2%3q0>L(!*fAs9D30n>BZD3y zM**4|l4le^#7~Pf^>hBXhfm}AC2unj?y_2ThVhML!JE_8-q+Hmvwdz_*XV zFEO$`2t-S4gfv}R4rc+n4G_sRM1^_YHNO4Lj5yo9PLIz0@@X`D$CW)|+&s(`wy``2LHk~29g4RE} z*UK|?TDmR59{C3R34kNLjd93Dc~xCr&%UXrQT{O)&#WoO(C}x!)d6A$TH6eR!>@wy zAnvBcv)#g3(LDgazw*8MM|GSN==Jq3`8w4E*7qJQ0Iz?d`XM30!~#qhlLcUFHN4zw zUo|YNSunT)x+YP#s|RS{U3C4T9_wOLaQ)J2rotD(X-4!86pBp*!+z!q>ByBJy44VTXH^AUZSG`!f) z$aW})6t3Ms_`DP!Q!h8K!roDQnymP@YLNQ)?Du#{m%O<9b=138{~_(hOno#0fatS; zf?&lPAXV#(lAyCx+;rfQgGhndSObLmS0q~FI#JYPmU-%9vrn_{^1yWO0;2gk|LZ%% z_a3UPo+7La*bC>D#F=A-Kwmo)R;u*FJ;G8&ewe=v`_|(f_1f*<^o=&F3$bL_o3(U` zajAm|+{x;+Q`|EHypr}^i|Amo7XcwoLMQd0$^GiP)4N$S!AaINLHz^ZWY3C>ct;Rl zD)*B+Whq@|{os8_B8GV#a5k2q#e^>N_Vo)b?_XyiVq)#$A5R4y(Yd6b#Y|5Wz-Y5X z>SZ5XE2ORdifcvENr88q%|`MJ`72_YLja>s(wMXTGS%0Uss-{86GzBSXb>1r2^uqr zj0f)I2^<1VoIs&?4U*u*3VhfTIn)uNy5)Hqm`elYwqRlXb4w#mNa)D zwB>24VB=e10AkBIz>5@l!*_;#DL-iPOHjnj@D1XAg%KwQRy=y*G zfgJJS?tcs92>$4H9g<3j@fKNHDAP3#{PxMxVtCcRBB?$ksb2Fim_2upces2z%>}|L z?#A`#C2IDOr_vL>bdf<9(aUeVTPN}Z$m>Yx&TN+H#s<5s->X9t089-tu~JBi&;W~- zbqe1q5s;IB;s!{grCFF8YQE`Mve!Wk(_-5?iV~VA-EYrd{m}c|WPURXsf4h6+-%MD8A{JLvRbTNj&-n0TXUm}!bh66Zl+NSO8iO%wapV_Y{s@BQx-e(>!DkP*(i zAF7ngy`OUj@v4X37*7?}yU?`O#B)u|W&#lt`=hv*z?s0k1VFS{J)eWs^U-1!KG)-? zE5~i5el+#JE}Ku|VbzZLXgE^ozE~}n_;93eJ``g~ft#~KJ|y#XGFvJ$-#HmWXpbvq zD1N{Fx{TYsam5_fHHH6y&}5m{3OYVC$^24>I4FD-3@-U`0Y=s?i-8L?7Zj(SPJ$K( zh3%TkZxM#8T&^T8hU>d#Hne&Qp;LrcJ58K4Evg3lc#pVBf&+j6_-I0bMhdF<0mx5m zr6xEO(}VjVf~OYs@7@oF@jAAvOa5N{(7RwTf1FL}P5u7?$Da0H7{*()3@Ro zSsUOf@I?cr8J7vDQigj1Va7&CNEBr^6WIM-qDC}HKar??k1%~!5qpYmmw|iLM;0*; zKThj%>$EAu!Ul&1Stp3L{;KiU&y27guXg{ZSXxSW*Sla2e^0}^MgD#NogNtFA}lI_ z2X+M|BT&-DDh-vRK8~(8;RPXMsgwMF1_gpd9!yk-?(YyIvA-H8bc?5|i%QvNOnQlM zOSAgOB(@va8fN64e8@(_NX4g~rg4 z_$qaVlMQC4okAYEq>6*R=0o{Mu~0hjtfEYG0fMXR=-+a#gq-=ktIg^*-Mi9q1-jT& zP0RRZX~sJdyN2?o7?&71Zu@`c3(+|jZk1Ry-7qtd& z_>6z?aT*Y%Q9qTh5E+=h`I6@v2^R;M8T$~<)xpazkKHq4AKJv|-?Fom=K>!JqyL?s z5V&zuxD?}R{{;s%Mf(0fUJZ(28waAX%dGDbb1WxZm~I`+)>BmiYh z5w|(Z`998Z1D3(ddGjy3NhBTQCqYGH3z4gb%pF9 zy{(J*8N!}Few3%&(Cc&LpX9*w3hdd>#DPAM93s#sK*Sd5W{I!V(HHy^-}vMaT^>Y) zT=c@6?|N4ey`a80a%V4AfTa2%OX@ve^0~8XO{~a7zK}?rgTE~>=NO4VpS0yy$qK+n z0!|X%%jQ4ny&Y8FSPXGtUte4Ys@{Kc=jBv^nUJZpP=qV(ND%|{ME1=FWsk!Bm=ork z!nTw~@{3C*%dEL(m(g$B>pcPb;+CCXxcC(4>$mLwT{0VLJ(;+S!p&<064h>_ixsw> zZpQz_No@IQkm2OeLsr_{u)P=zW=w-RX@eKlQGf&bP6f1)}WEDw4iqJ9|?JFxVePqT^*8*Oa-C zW6iMt;5{&%-=bkjj3Ijjmh{h5L~uZ&`?y|I`+8C!Ra!`4jkrtmg%tiLJ#6XaQq<*rVLE^9==}mu z61@xFMrlBAPMIm!1$Yu`0^;YmF9YO<{of(8#qv6t(oYTWSbPGcg)hX)ekwncy>CtD zA59=k2}(*_cap%Av@$*VlIn@PTz+V9Y<&xn*;kdNpy0%(Ha zOX>CjR}bO>hHhV0P{k;53rjHJw>DkSBUGvhn);0QpTl_#J49}?dd$0E5dRaqQ~1sP z^^nA(R8;R#DY%J=_k{70sOkNI1{y*jl7@MYvI%;PG1OChEwm7Fh=3#Y>^9*k04iws zTC8fi1f!;f@_Q5fsqE4Y|1`S(cklV({K|Kp7pM|bz`N6%rF(kw(M(pLgWMCSB@;9g zGA1Bb+bAWKr9eN^^$Mcdza?2em93*{EU4ajL0h)e;axB9&}r(jRp^QL(}4s}Mb?(c z5c)+C^Q{Y8q@&Ed;e0Yh8E8cvBEoR#JHN&PdId^?Xbd+_!`n&;Ss8>je??W1tob~W zf2*riOCEcZCv+in5vm?r$%^CF&Me26q&@spDtXc(AX7gT6Y`BCDGbbSM++#K&C=Nav$N+rDH>+#{xnaTOIXyqU?qQ9U{U{w zzeiph)eqIyJoX8zrWh|xYdXbv{bP_Xn~aDeV)~^4Jv*!k1UqSLraJt=>$QPE{1(PM=xMdJ!}_On%M+Ch)?F3w{gX}E1A+n`}KmtPX1 zJt4?t6WT_P>ArDNOE{x3e7?rt)n;`(9xCy%UD89{{q>hhzEJ`Q`3WPfVFFTr7)4iq zzH#)O%~KcCKy6l`1H0r`+kmrsMvC`X;4R-o7!?Xh1etq=5?ZL2cd?NsHJW`jR_th( zG=V)1N$fQmyaDZAD9Cp&^ozsl`qV#iBW{Jd=v~$>jc>RW5`4Rqqdd)bnLOfcnq=s} z`zNZE%94=r?c`Ug4QCF)KhH3pP*rv{ory{K`Fip5ArBbVNF8`+_I1ol_=Jl)(bB#C z)@#*<7@n>?&G=RLdG7}0X~T=gAMrj3@6p%rjsQbP5I*we*Yq&Umg1uNPV{(MxmW%B zmJu7nmLGo#$D~R+c(@d2r<{bYNGN!-gpHX`WZ$WN#*Hrk!f*B znO4ar?Te2M*cWO`v<cDQVKoKy;bBJg zyR@lQMibszNpfO+>!?zcfX?nI;i|^`yj1I7<5OKR_5_w3oRpjxvBFhQJdqJIVHMp<8jkfK1M8NHR=by#SDqA zt4u*AeVN7;KOX(ng$BE_a_sgBPoonNXe)OAdsG8#GmJz%z@*&W{j7aLBN7zJJY-*Z zY;4?!edy6;9%LS8o@Z9f#fatm7UO%E_v=e2E&GjrOrmtH)FU=BDpBBq>{m9M)@QM_ znt}=oGe@>n2G3NV*cT9P3G(-7a*dcYvt;!(RNZfok88VsodwBRd5+vQb!=`@LwG@j zyJJp;YUEGkjTzPw9oM%!J0Ndxm21ly(dViAdrfrkknqwT?D|Hf4%NA-2T)Q`e&(LM z9F1M2f?ZXYu}d5i?VOwxoheiQ$ByGMx4SG=LT#X4oMGDpXBPkRG4SpD(u3uDi&<;^ zf6KmE(!&6!D=Ekk|8rpvCI&?Iscm%flF!c!QJ?s{J6~TW?j=;a{Jk7ysKT4M;M};B z-Nlhvq2}E-6oVu|#&JitT~VOQSE5(%TO>+^K@o_8jL6#%M_qeneGWw^fJCWFGYi^{Jh5>c~km+^epo&Ezve5)xtqGSZBJ zfyx&qOR(8hH?}e?FF(uj81}BHtZ>M@zU;z}cK(-w!IjCI*NQzOo4`?doK`Wy5aY36 z_Hl!Er$i19E!pkyt>bH)M{I~*qhFMh%@aj1%6iWnHHiP`TIDc27Ld}iLo?D{`tk-& ztB#dT0diUI)nxuYE)<0%Cd37~(*0{rZ@i+^nw67lW4zZYkNqyz5HHrMoB7O3R2u>> zjMw1ZZ|`TnGu5y9U%$O#xm$gL)$Q3sKi?NWpQ``7v<5~`)K+w*n@~-Hr|u|UaT`Nt zmCbwhusZzopVV@mVMxO0!4J^ecZ@F@Ql^%rnoJJ%l=?*|o9nvcTDAO@{;wP!Ig%)> zR?Atp?=y%qfd+j>QOfZCUqP3!9VtiGC9udJUb%hb$ZfAcQ%&)zya5%WYz8Ngpe@nj zLD8cyNeNvO>Zo%J3T2@h;7ExIDay;KRNpNfQXZdB-dRRB*SU1A*CPTf!(0vNCbFvlERCM=|@IAa8VMdK>`nzJcL?w8pzJC7v;n%x=MCMYB z`V_07iV^R#Rq{aoG(Po#fp=48l*D#PA^a&+)Cqq$F5n$|^gA+E_J;Spub-pNK4Lwh zUYbkmH6aYVBvHjjcT-tmLUdY;Rnlrc7S)v&Cuf$K4)7H-`?+EgV#4B5Y^bu5jW0_I zKz$6ZD5fj-;*vJrFo+!i^-ejL4^>_P-U+-9@og$j0XEX>awjiV&-B?f5*M<4)idl6 z?c%oHKP?{B6F9=pBHH}pu0HCSMEK#k%({a{M%9gIwgn?w9^|heI*;J`$uSsRaRRF2 z=hZ7l?&`y=c6O_JM*sPt`p?U+AQmKk9^)$*9dB{)^NGybXP13D6%b&T9#Nb5x0eor zlc=9#)F|ZRV~~pXPa+GPmVtUpPI%=@`Rud!^f7$;1$w+tmFqlt(kj;Ezylu!a(uBmWXT4^B|^8I zVn?3+FUyEy8UF>vYkG=u?p2N^6LW?o}9)lp3kP2@ii@@_L-Ud?B_Ud*T7oj}EW3V%|}2Ria``4C*f z@j#EMh|Jp(J*%x-t=#IdM>Sj5M5Uxq(Bvedn=$WYi&_D;UIoNbv_nNT=YUatO41cn zRA1*VuJNebJ>#w(TsNa7O;QfyNorM&CqF6hkMg1N-0aFeIXM-l=CoxcRSqi&OR|}5 z=Hg;Unmd+ul6#S*aOoY)DfHnWC05BsRWlR_fqJm@6bLcBzk0^4LvEeEW;*^z40jsL_)ZhP^BGn?5*lc%&_L+KjC!YQ zf`julMRa0Jg;01VZ95cA?^UQfTu0X>vPgE_j*8{CFpz0Kn>Q?yl2Y$ z49ktV+8&uL9ur$*V0DZ*DAba+N77HKIPJN-iqpQIRdMo$D$huDrW#0D@cjX}F~Fgu zASg39lO%VzGsz~^smHxqPji4N}Qqcy16BO!RU0TLU%bchif`7RE{c&XS3|Mg<^chfu zDFOWqP<^UAx~WioWO@-Z6-;0avkI+2aTYnQ->@lt8Ws%BO=+6F?ZG)2Atk|1S8@pYy%bKJ|47S@FXcD?wQcw3gDPfbWi^*37ERbPy5s19^%Kj31NbUe zO+j4kwAD3V$gtKeD-L262NBt$eq<)t6}%z{#edjivnj?KPDBkd5X5q(J5l(= zDM@L?C`#(WS|sUx^?^Y3xe@A7p2m)R8Nwt>U_{8OM;?(4-b2hBXbVh9jxUW-FKBd- z<7&VixXs}4q}ui%cSQ*eNetm3dpw3fYakDi0*x$i&+`Rg0ceTk z(8h?i12h>bH_h-{`<0548cMCVGhKap4PNJ*m*y0zM_tTQs2+E*dEToB#a*IFeSYYR zL&w+>bu;!E{eX-|fcr}f9>Z|FBekOgQguP~n(A%Ua&>i3VRT+%wv}2SIjqzH$r{wK zH#@RoUtwh1?nG=Oj-PBiIiz{Kr#+JJ zACV%W*=Im8OZ`EnJZ&#%?@O&9(+ZQ?$4)QX{!*6g95VUJ7PRchkFK72;Po43|E02O zOY7+C$KcUT z;q{p%leUg3-g?uXr7c;JNl7_vGiy@|Q|iW4@Zsys!FdD6Pa5kQFtVU?X}_R;9fOH` zI18oN&1eJa&?Cz)F2xcSBM)NZV5RnXh6?$(3FO1`I;3@Nho{VY_}b=K zkDTu*_uh8R828d?BkvlK7#~Yj-n+iId5~V^y>RReqvp&`cS3s@P*xM6c>`)kMH{RS zTlN?tLiPZ`5vzzrPJlJhL<`kNp%;WSMV(^TT=U$9#tC-!{+L9(Ly9;}MAZ*oB- zh$HP&Bc5%bqZVat{TfBZdp65A8&S5kXGX)v=8PHMYgTD@I1xOc=UzN1jR z)5U5F)hAtSwsyYB4xL7?ruVSdWw=vJMI(@;@PhF1Xxl2&7i+?|g&z-pHQX2;9%qoP za=<=AB&wO7c_1-vp9}l1mqiw*dBN9^R|R^yOjFNvJR!VdL((WTg)(~nx_(gMv}3Gp z{C#!#aSi=jQ*%1&GiNM*DEt1JS#3Gf=k@=~;F9_$SIxU^c1h)gtLs=*dqG6=#%H4A z9G`|pg$IVjIG&wfV8}?tYo6_?zW3&nfk|`cQgx zZj>Xl+^PSq%<6_+W0&p%_fW0~>fl^>V0B(Q)DMN#I0~>x#hDg6lv~DyXHy_vjgh-gmsOLsm zD0lLgz5VO2&Rsp7RW+T-J5$K6WR(@~_Fx7$a#G+(xqyr|?TLi-7w~ zp(rK=-yUNk`H*^Lz;HX|aP?m|mRG7J>YJyS^ZNWE_983e2M5)A&%w$qtM9{uu{!E0 zafRqDI7F=OTU`PX+w+8Owf(_%544PxG)$zEWR0{>kE{`}>k%X}3_czUdtfx}{!K+A z{p&Y1%_z)mGfqR0!46Ghon(j%o@CU_7YVnaq}bptGDO%7Qc{H7nFNx2rK-NqlFxft ztor_U>M54XoHs?Y1n+rRYc{e@ox9)hzGx?^((-6E*9_amn%V2>}6Sl<2od#Kp_b7#m#4x0>aQ2jleYH-BFn6?HK z$OCJNfJ?yrY%JMtoD-j*Ri&6Adg3|ALWKdKk}$8s9jULtyZqB4JnSxOUx9_7agMa zVtB{^w9l#9R~$JM$Rp%`BahzQ7&WPKxPKyDdI;JNKP*5ZXt?InYZe|}caX{GL{0Fc za|F6IRvw+%vS>tgxLo_fl0~=Aau441k8A2@ch*M9$(>Uc)y~*HDjoeB3$xnm-N6&D z>qz4VY^fEgHIo`rhBeeqtn*me*=JI7Ms#6we#PXLteCq-9dDM@X7!g|IA5v&=}z?hO2|0Q=hzc(UNP_Cs_q>7Gp)+aKnLvn=UY? z`Y~yvwBr(%iAt7km4T#e-mYv2ZacXrQe{y#hmuEx?v(^cAg2J6qkcj@nBvE5?50Nb#3{CO%1tv$25&h&FQW8{ zA>-?6ScCeQY{+h3*gSX7=nVG0+R)$Km%OO^L5Zwcq#+UhM@XQw*Wrj{riiG$TCXTl z`ecQnm0igu_-!bj{PwHWqkG3(!%{p2an08~y@DN8C%RjQ zO|I?3I<9@~^p0XVIN#HnHRjsEsjB;QMRTr)sp8yL0gP zzJ0R?&aA1O*e@qg$+?~xPc@dZj_!Y+?pK>#g}rMBhyR0FAbR#7Gf8_8^CBq_3)j4z zAJwPtP`@gYCKsuvsb>!D_|QwI`N>!wl}Id=ZB!3v*JbPM0&x8Rm+hg7dER zyyVo?-`O@Byg4CHf9)=0)k)~F8;<)dqLF~J-QvkkG^AQnlTxKr zTWEA*bbhoHBt@r22MF@n!RW?acNu*mAEr$JmA%MgLzUW(yfW$h%KzuuN#3_7%I=y-Qvy ziKQacDPkFUJgd~bylwqjNAYmakOY)lSy~`*m->A9s2W$n&;@I6?3Xd5wbAmWExNWm zDm~V+aHkn9N&;1 z(cc|jl(Ib-o0t#F6q<_znIC2i3$p|EC1Jk8t31)Go@cKHemY`s{ns7w@Rg-Y!|Xzm*N$2FddOi@h0t)2#B= zjSoyOB74(Uw>O#X3;XN#rhY&%x*RdX6!fFL9&>aV;yfX7O7tGHIm{H197EFX*5X~_ z&H_jQ6DCWeDNvFu2Q+Cl9)39$Pvq$9A6-_azFRhB*Mxkdsf8ubqgL|T<}}2VC$JIfAxlPBshe}F_YAjX)fXTH3%TjKbWSEeB#NT% zVY>q&nY7zM=P#ew2ixb=Z|86Xb>B-40~6Kr<*}_R?!GEKBO^7WC_SsDvmzyAl(a~) zTw3zn*1=S*>8p^YIqPfKVQ@JHc~5=Ni-cl*SiKdozH>I4ktt`4RG(RxS{!!lmn+>R zf_>=}>??&3m`qZiZ>4|Nt6n6%CEgwc{9z2VkLCNfY>^CV{gdYKpa6SNQsy&c)4xSO zhKE6iVts|4n2>XxK%)|PZgPPjr-TKZGk#?`2eM%KCpF$@Nx^)r7or7mXPF>wa*1Gr zlY)D4ifT>xda`Ok7`qRaQ*{}wz5F=d$J_UvCe6rPZmAX zfKIHz&hMfRgV_5IkHJ^*9bSuFNn;*(hqg5^P;%`df`(pWFmQz1- zKt@t&Q+iT)R#eHjYX&F@O}XWT*$bWRCDqxvAZ&=tZOqTD&x=vG5}jU>TsOKrnor)E zp5{ta-#nO|;mW`a(M3esju}Q#JPHx1$gpUOi+?A15Rt(oV=&3&?+{z2aF9MpH+sC$ zJhk8%`S^$?BX}m}>W5$cFP7I$aZd4Q^Np|#N$zK-*;Z=P4Adr#65SPDESn~rS`pcm zludJG6=ISsTTB^JL)`o;<{E5>ph(p@!jrT?{a%{W3at4%!8=rTmd=?yM#T)?;aCOIady|Z zb;+Ug49z9#W8J8K8m;B;7|#l-rZZ+5j1+;CmhKYsc9RljQXlop*+_Y9#Y_fpqy1~B zfY-5rn($b47nbmcpco*^?HX^;fn+~!GeaJfvGJn*JQ*T!)yii;cs^Un%(NWu6WY(q zPvGY>KtK9Sj832Wah1843zm>@hlHot0@X8o7TWm_} zzYeoWR=n*on(UUN>}ZWv9(4;$_ih`G{`f8J^fk&X6#Zyr9~6^U*eA^qP3r7LsOQ^%_h zW8}R>F)>waTyJ^#$*4A=-XS4qGlvFExU-dpyxGqhs@MwDCqF#=X8%y59G1n(zQ(vM zZDrAwXtHcjZ*2&VEo3vue_DsL@gUBI4K~&KaNIe=S^K#_oCp!gX1dSh170@aZwng+ z|A4*GvT{^W)9QPs4Olh0sAbK)AvtXo&YG&+);>;%SbE#y*69zd8<0JCam$SRuI*y%KcLVUYaU@W}IuVrHf@5$EY#Q70nJqlS@3G@B9|1m=W^k907f zsgvA4BwAb3N@*3Z-3#B2%+d;?h`IOVb>@D^pi*T5c9f-;iascL_mlEx9y zc@gYkwLT~$)nUz!WshQiMnHFdAirXW#(8o7B{oDfK#huR4hgX<>`d|nCS-WxW+B1$g-Oe_DCVwOw3F{$y{+ zgsID&3pcM>9&kbFNXd?j8O8Uvj9L=p2)R8rysvwIcIyaN&g7_IB`MZ!_nqiK%rF-A zuGkY6XYgQp27^5y^t1~zGSZBLFh%2s$YQw=aQ5d@#5UQICWd+KqSI|5c zLuyhnPdj47xPf<`SI(jt)9Kjr)H(#2dcyVS)i@P|slOz;sfqSS;GCEzzxQJcZyz^e ztWk*{GIZ9AL>~OH`ft3BuNe|!sseVYX`gsSWPZ%`gW8+R)X&1H@8hcYn0`0`OHkst z3Ny$tlp-S%6@hdAW-t`Xp=F6>`DIesvyqXpRmB%lzlo2%ko1j@T_0Als%I?V+Sg-f zZ(%lp9OzIk5PxEad)Nn!kIZFaVwqEmMT^~r`uBAv?ct}%r7hzc&u=&faa(R=F*M0g7C}~d2=u`q@oe4Xg?d^?KHmlBb zCFP3wwy;X@eKzaZyY{El_WC#I( zQ4Id*Paik>c|T;<4C;igv;DO)^dS7JpY<%Whw+%hbj)E;&m6S9r=7R;o`X0k;2s?n zvG>TEx_s{si@hIth2q=$`j6GS#Ux^l`reO;(Dt5Hd;g`)A;BT6&s?13W7z#Toa7=; zh{0ubB|)J+%b3$lXCyQ^tJ!S45Onq%IMB~TkWgaBpUW0|4Hh}EUpTCyS5U7>;wa;o zXlH~UM46tl(uo5TM=x2kUY6s>Ph5XZS-LDAm&=>&(oB7$=1zg}SwDE_fa3mPPFotb zX&iVo5A*x0KEFIqd}w@Pe15zXkNFutOlHZ?M4UBy^eK{>AuWTp3XntK`rgteCL}gc z>l~T?97fPK&h?^oHPv13G^URK@ea>Y>&KDqYJlH zqy*`Flsbz<>srB6I7V7zxTuT|8$DfpRf=541|!L?e%!#snjsZ+m8E4dmCbF{l~)Yp z2P1B)KPYZT@=4D)x!5tdt}tkh|QL;+1TNcY^PKxb~wvWe$1di=#r!2nibP` zq5dY2?fgT229Mn`&xf3iJ?%R0(3IoXC=I&+dybiMeUe&B$X=58b5;35gSvQZT}th! zqj4txxz%*$f7Fk94)5#g@%X#4H#+^t_j1k24P|T>JC2@}61;TFgSG%*bZS%ifiQ45 zr9ZvN9`Ny!kJV*%SAJ}4eu~|mLVvsLaP?BWp6HBNOK5C*H2rOf&A_fL1`4T$b_h1u zJpsnA%}U^DE!+T{r9%!9ZHYQll$9xlUI*{2ZdVxN^Uu!9@HtoD()L-u5i`N|f2{fnPZ>OM?AYtV(EuCsn8fyRFXj=CJLM?T z`F75F_L$qw*iVO^kJh#py}m?ib}}7hq+otFCx{+DT7169<%)_au{Ln2&=X$&@nX!U zZOPU^zWoR5ko^kppS{!*LRqfp)ZkI^9a=qs|5eoVN(Yg>wg$C6=mfgHZP3{E^uio|;y-F;0Y7?`Zf?0kh-6cLBVh%bllV%W~ z$7vU)+zn_{!au`jcXxJtI%>3Z*ShvWt!>w>T1A+qlpT>`K%X#8lE)S*v3%(jiA!W; z<BGg_ed-2qO!mD!{-m8`)9Z^U)n2htOdiqZs3d_>HWvZ?CDZOEJJVqazCl z-}sCy88~LR25T9pOved@fA!pVeAD2CFzsWUrO*Z&T4 zR;R1eaVB-XYksnn8=gTCXRJVRwm{J_ zmR?%;(Jmo=4HqG(aK|TMe9+vTflVLRO9c(q`cL@&LDU)eVPp1T{wKl9 zFoOrMAG$Fu*xJl29>bX+lgV5cYDzTy!6cbHNv>v-#}V6HVDgx_$qd>j$7E+O6!%#* zFgMVVwi3F~ayd(!5&C`BKGt^#`XuwzhK{Qj@=c#qHhlcCR5o+;WLneBz=e%iQ!II< zF}C2-?2JirDAw}?mccu8K8Nz4)ghz+sURkz4kt;5|1Y`m6JED?L1EvO_kCPl`*C>_ z7CB_n*s-VB73x#%qgaXhY{ytu2x{A*?czZVjkoWYPID+GVjRLJ?jG+&idWxJ->m!= z;R#uZw62w(@V>`W)Hf3ysbSXAG)BH#1K%R`1;3nzC{IwtH_pVwfS~WV5mR=1pL1J9 zTVj2-nqCohx7S%CT_eQ|>0I7CVddc3r&YOfI>kApvRUg(1ys3daUGs=*M;&+e7+&!p5Ie~lOFlXrH+k~5&HYL_kKVRk z;!$JAZfYz`3azY7N*e5F&CD;YU(OHyD9P&w4y-L`3XBL^k;{|k204P~*4MMnJ=JB= zakJDtu_bPxL7W!MJ_Ng9gUt!jRWs)%NRxI}DM!4lRB}c}Aj(2-5>1>P&-^6Z8OoM0 zxs(rd8WGEoYx&ftt5!EY$flfHJ?~(AUPgraCU^t9gvwXXBGOSnUVUh)IW8y!9)0%t zI1(wGMK})xJ9_rSltvzogSx&F)X>!rVPOUT5FQ%ot#f2XiZrp*8%*4;9#F~bsl(5KiMkRLs{Ag1_Nod+~zUklp zR+i5SOS50KVcAtlabu)AF8nPbH)i#qHkOGTK)krU1Bb~xZoI!NyMmh7tG85!Y0 z+t0JUj)=lYm&;wYGd5(=IrU$$F{QE5>`-WG>Wqqa*`14~hu>z~(tJW)vU+7G?qwgj zRF6lrbCCu9@}o<!R}{OiSTiu$Qy3px;6cg-ztjz+wGI+Z*~FFy@zM=S zQb&L`She(?d-)GOTKsWapQe`bihcz6iu&dj_NgqGNn@}h{A28*4d()V;FHgrzKJ;> zcGhn-g@kE=NHUeBFqFRR$h0zlFiFd@V@a@-bK@V`+Bm(@mDV!5U&XK(qvT48$&3$m zCS(m#~i2L+Nls_BIXQ3C6 z)Pl5r(cq+aT|Yd)#@lWxG9U``vAa-D+^VtVjK!4k(;Zj$N`Fjk3vT z_vJa2`R)=$s9t2W;Cg@}qmW~f*BK%Bq=@7rgau2Dr|NH3yO9r8*j`2H=&6N??PF$? zb#9#6XwRIma6|iQyj2X4SF!4qvPqE&@`}a|EDN5-YC6YGxp7pM`g&PW(=u21J%8pG z2CW-khEh68Vs%kZ5_)RGnDWvw4e9!eQ{L`YZ{W7lXmm;J)SftOWRXWkh15v^Ft?hhGyO&WH4!f?ZJhHs6 zC!u3aXHG()CwU0pQKa6P%xa6&CzIK1wzh8R;fZ^{xOJ!_LcJ7hvzRL4RkOf%fNwx-7lzD0ucgW7@xWr^R#~B-G%P-_@fBUTxRER1kkas&Boh0Fv~=wTMyONhD(%_1T!vo9_&L0f zGND&6GUJ%t?!ft#cWs=2cC~%2*)b}Dq~U{ZYpFLfTFH(>F`2h-^bx&s^8+jbjOGLE@a40U zT)7XuXK^cPkZvvwC?1D+S*ANUU}v~3C39zj*h=iC+xpg+6X6x&(kTu4*aDsATfW#) znGX9;w^Y2th;+y))~v*W*2*kP%Aj@nikJOu+hEUv{SUn`tzc~D!1%uQ>gKkTxyLpR z46w!9H!wr09A94EC()W4%pWm@{>E=l?4D8_V6_LU-v&9tgGL_u z_YEln`&HWc@;|#<@*+?}80)iM3O5;)U_-5;pC`4VqC7I9PefH!U#m4VEG*n+ueA5E z+w8dHu~gLbiQkP!ub~uDqs!lXhnuPZTQ@4lDFK>Npe^{5o_JEKf}Z7qS2?&OWxjuE z{|!kCl=`Tz9THPo1Zg)J=z;Mn^_f-1;DRE%{mZH9R}VeMw$vJf3k%ab2lfe`tscMp zm3iv$@l)N)R|K)y&p!&OS$&NZEZ!S?@8!+nHL^)PsoGAXWmmrVXYsJv<(EG!r{}v@ z&0+7IW1De1huWpevxvmU8WQ1OXW={y@)V?`W@XEflGUCeg~TOEQAg2?J33kk$d!T< zU6SEw5<0%ayx@OQcqG-^sd0B1bref$;= z%@thxD(-Z=>BSvbWF&LZ1Ff{Q*3``tSEeadDB zzj2l0UUkFa_<8I(Nea#|2C4H=mPC$6&Pe>d?4;_Z-}lbA*W1ly`hD*V`k%TXxyDh* zM_E(tp}47$4274zFm1r<9q{$8fINhhR=bAE^%;5YgBg)66hU-^#Wc6H9jvdf4+^wL zPcWN{)!~c<$DpVJ!t^`L$W!+ zF6}9!!_-RwCP;F=dRx9ZEH)#dezE#E*nZ^m|J2UiF_qTn13h{91?3er zN>GF`u(+=*C8cD@mZJt-u7q+|dbaF{O{|l{kJ@YzL8kcV2$CjEoV+ANmkSeo3{8ZP zlA?(aWn&=9P2z>$Ob8SS6|RjbKLfEzmmOU3kJ3>-%`0s?xR z^1AJ|izu89AxFu;UN}_RSt4k{krZXEQ0Rv zi9{{1LKjIAML3$s*^{5oQxCBM^_sVhp^|c~`uK)h@@`qh>Q^ekX;!wAE%p9OYCYw> zfjg{4cJEHU_!MvTK4x==v#-2J%Vq}D(UJd8=%)#u6kBkRJu)CL!eNH}!ZV(rz(5PG zb1X6&Zm^2e9o49j9t?+yqvE<$EeJTyU*VU3~IlU$G+P~I^~?i?TOLYO7j5IR0_ zJRfiD?5rF#Z)W52#wD2WN%Z+Uk$=){eg6$45TB$L=446e{k%=TQ=n2lKY1`=^1tiF zd)~Bk7!nsVa*@S}SDmH!4p;0Jkta*Ro*o&5X$~)gZBEA**fs|~nIN6bEpcaM4^7J* zXiT)k=O(69q}eNrbNZ%+y%(C_xoJk-{K0woqt_2Bo8n5SPI%AzOu@p&(p7B}Z(cE? zB9^^)ys(3RpVGGS?oYN>Ozs?zboE{Cj;f^ex{lld^NSqWnQ2xO6uNHBs@lfJTkd;i zTHW1qJ$2JFSHEyWf0mM$oR*uDm7Fcbm1W1cDq7N;N9NS_4=!CYp(d?mRzu4*M zru}1ze8nT`SL0m;RZ}x-7w;b2al|54ogUnoE=}BNF$VwfQ8!-^9)0m#MqL`fu^dk z?9@J0b$G>Cb29%eZ5s*;2-^^+^hW>$@gjk8^rSuEG>VEPuxsEYF7wgDM0;c{P zEDNu*hFjAeY0YKHX$=$lUG|7f1qu|@a*}IWA4!C za$&i&dZl3P%4Iskm2OU!&g*{A>YaMOp3{dNa0<|8WH}fYZ~DP(wuUpBGEQf38FzN7 z=cxat=KMH`Qd>2RxgEK$=5o1rTIuwYuAFUej~wh-Lv$`eJ(5n(B>zE3#Qtj;^#!p4 zwEdd6;6Rk|J7`wq$1dH)rq9X0x;1B`v4?2n5vmll+|DuXg{DG1~s9 z#$Eusdm3BZex6Dg{Nf-&a3_0dqz2spKq^rz$!o%VIK2nn_fb;-retKW$rEg(v zzung~wMXx?G8l!`Ll$hlD z8Hm_MqHt6;jxDI3+mbDw3D@NetIE>^EwyQZ5w!&=#-8QYpDlUpp3)tAw#*x-b)?6& zWVn;B!4X?VQY&-faymEP*xXUnzIecoDs9Su)~@c)WY?^MR5vaY({V={jn5y)-C-wjX6p(Re2K-|r&++%Iq#jKS9bJl*3-(RR=pSOlL_ZIxPZXkR!} z<=CAcpWYJB-Xxafax*2wXn@I6ei`qppTQJ1Lphr(J~v%gI%;Wa#n^J^{_XjT zS1bybPI+tDx{vp_WskYFE!0+%ts<8iX0)~BcuGPcS7|uLITb^a14I4tsJY&Ll-4$jyaiBPsd8zk#M8tVvO(+gKG%`)9 zHlC=s_$-&k$mD4B8Ht)OmzOgd` ziga{B-6Ha=7AuqwW7La-x|(?UeYQ4Co!Zb4RLJGZ{04m9nXkk-W3VB!q9QZ1y!_kf zd(rfUhUo>0m>5L?{S;KBMoRt|4XJ&=_-sy~R^C!r7*&NIq(_?}xOgQ;U4$wTn z3X79)so>m3&wok6#H=$l_~lO=CNYOW-Ag0I;q3a}*RTMz_tyQe1#_-c^zt_&>c>l7 zL)DmzqU*;zoVmubj8ErF@`Zh0`vf1IyObx-_kPBIEYkA~UEBWH^PA!sFuk88q$#*u3Zx8#9 zhV&6n2qw3BrxM;NPkD~-EiLfC1my)o9b-9cUKZmY%gI0;I7SLiTQGouzgY+0k` zc+`7&#~{s3$xa`(a_TBZM(5Gol_2;IkdoHa3yCYrTAm5NyeTz&rxY2THX2Yj0=obBysgyRw$lLPkHVR29@RdLMWQ zxuMqxC#BrAk=*33|2cQ>U&O=Q`!bl0nL&}<;-yQEqizyTBWY6IF$HOnx?vl*0n5q9 zpk*0Tk0|<@aJoZhFkAV!*mp)W3@QgQYTP?vR})SET&ebf1=(Elj*@^bRjV~2IFGvR z1kO_nAzdthvk z)hTUPz&s_J>#Y0{GYJkiP$Tn)7wF)yLqGXU7OX-nrKr#iisnK4E(#~cnRM3J zcY*_C3hO)J#HK_xF)`WVE8UT!OV(;F6dMY2zmI|;oJNE~zevIVOg^k)mq|y-#jlV6 zFFPr@YL~S_`x-KQbjw8Xsb3~l6!BDyYpCLRkS2X}s?9vOk2JB9mbVU(gEWU!TD?k4 z`USE`7^mWw+8DFNO+ipI;u0ZO#7h*{i^@r6SdzD>(t89muV8g5=?~ zh)Q>f-Qi>jUZ*9kW56S=H)jfjNAY1(XM-Hiz;>w8@jL+ak_k5 zdBd2{(1nd@DfM%9oS0L-Y~i#lGQnEr9=N0}Uz_B2rd1XC+;#=|{mmcj8=dYJGYT?V zmNd4d4$OCkx^EjX;=bS9*ioR=8kNTdp?cB&u_+bVaY==BO)WT6#?6!DdwvvTt%@-N z15r?LImJYX0j73E0P*RV;Qa%kw!YCMu4;PYxi^}~%BDY)@5vHzEq9N&fh+*6UK3sX zQ_#s=*p?rJcuyyLf_Vf{LO@Xac+FE))m#@Gs zQsNKjc?~pF3u6y=2T;a>k7Gd@+)i)|$U73!4c!sQ#{M|(ap5*$&yU^09&pY%@NqNc z908}a`(qn_iiHT@6jhZ7GoYt?YLjp=ZNi)0~Z}l51fV{&Qjdruvjol;V zXk4n-9)OxBIrK%(!KD*$YRHGtky=kl6bpp{hwuj$D9s&P&nz9kdrASv%ee(93r3Oh zQDnp@QZZ`5rDx3WM9pm|NQn{emn+B<>ErI0Tb@61K{z%Uz95Im?cyZ*D}ElI9v2G~ z)$GJ_IzOMl%BYj5ya}U2d%ic?^P8hRpBU*mE*8?}H0B)1LHy*3oP9Y*b6(96a{78s zS7fp6%8Ja$6=OKqkLlVgwh5_yYcJB<`6*I*4D#RBx5_f9im}`uA|u9>{!|J7F*Y?7 zVO*tpDy=>gow66D@u{b+RE!nGNM3fal$RSiv_6^_INELeyVCP;S2lefH%{6$?iL?l zw@T@aw5(z*Sq-_WIF^%}grcQrDN4#8ke<>MDJlC(YAMo%Y$?4tlFox8(JFAw75RLn z$Gu;PZC4~PZ2nW}TUCYNR`fd3bMXa8 z%9)f(!Y$DAZ{M^2t&xc+}Q5U=vbs<{6BU*n4t>58ru}&v6=*#u@?gq79 zlFE#U^o^^N`gR!U6rmv^x6uc7ztjheCJ%2Aq*qJ%$MG1E$SCta(R2Z80{T3TpV5~t z{8MT_mH#xoFaJ)yL8=GOLmS6&Pr~Y|I96P2)Ri)k(YTH`&>ZkAjO17i3%cUi@Zo4b z&4E>91@{om!BW5m)B$;!f*fUK=4c%hTd_mR@d}=vsu(A{M*crwnoKVF#S#1H z(c)1&Bwc9-I)2l{gk9#UsXM1y^KyLJJZnk3D=)<^-)I@Sye&R)QT`xtiIX^-)!si~ z-!5Cao_%@Ju1R@3++5BpR5o9Ur>AwsAGZ2pmGXHh7_~}_=3CMzkBW{CMg#311+IfB z6f!InPSMtetxZfTa+lWSbopJ4F5Z>4yNT^&Sr#i$J3N7D01;h=qE6pQ zdW2j>*Be+2B%BTsF@s>C#sU=SVq4p2@gZHo>Ss?re_;1=D_Pm|Qx>M)dslKz5TJ8EuS)Sg37UH zW@i=~`!TV}2AI>6jO8sh{;9&csa+Ytb=#XNh&tX}Yt5?8teHz!efas_iYMFPldiyH zxoC_79dbEU%%u*?@xZ=w7xq?I)CRRr9a!XPm|Zw#fM>w0%|l1-XN>^D{{E*6uP-bnL zfAG|#RAW*`BD*&wH>J{9JiKMy_yXHQ9%EWXraU7jHLpI;_MlCpl_K}1i2Wl%rvEK)6K9zEDxH zdq?Mr4dv4}w@Z-|1~^KR9#KEK;bDD(phwh?{c9_+ z{*dssA_j4g)H3z+sGq1=rjL49xT$6p@yA3=4cuxICq47%}B9^Swi3U~`63N0At%QUVvfI}$^GrPo=Il{=_n0#aNN6jOW zM`$d+T{JdHNYIY791vHL6$h%OO^Lx=KZlDj(|PLk?!YPUSM0@8hF9@GmExjC!o|Qt zaM1*~2xB36*HbqGxF1NC znfwTqFU*bbP>y)o$Az^yBuri-9O>_GFQL|>Gngsx>F@7wKmQ*CC5QVu8pBd$sQL%F zhYY;d@ z2qHfcLJX3UM+Pj4TIr-euo}o2KIb#Hmv!LTT@viij#o zdjq_w{1oq%HN$4d$C!cYTxX7J;)#|ge*RVdLj)}QTpEz(10ZD0Z9n^lkBTg;Ae5(5 zG5FNhN!=kqE{inXCbn`sIu}8Et6M`RT*QZeLO#0AnrDrlC!*}rR(GMLnJUmcyO`Ovl#eT)#6r5Ax zm+oZQq}ZpBY4N23UuP>;C^jjMC{8IpRD7-IRj9Q{>{W1*8~40++SP~>aG4b%3*jn> z6Q2C|Q7+w)NDfJiz%96RP#c>``JkQLPJTdpG{7V)VK2&KV=l~5?N|Lx#W_`eRimmy zwMn&4CDYi(9Ib_-Sp>*W;`oIh zw*UwS@f@ot$01UT?|_u`(bIHYs{Nwp>qJNxIioaj4se_`@E#4)l>*l=+EPOzFj)|2 z)SpKZr}z*FEwX|a5J12y^S=+c+%#Y;&%&~~QY4#@QER4wYzB5@B#^Byclr8&aurzG_q!agN zNT-nt<|H;R+b9V2R74FhR(@Q?XVe)7P)SvXuo)UgMrmO_m8j?R~L<@ zV}nuFjOpG8(@fru)l*8 zi%WE8irHJ>u{GN294N7qykOAY14Q-F(w3IeG`*dnHUa+>Jr1=47?x!E0IRqo%P`#W21pr zG#D9_zpS=J4(wCmhvqSXCKie&A`ifcUVmN1vU;1z)=2XnrG4kFR5{@|?^BP4e{@RgpF$ag1ub~PPq0v%jVKhSw z8Rk2f7#)cCU;{Xk`e0MlOD>m25qehvFvignYoQEq^*607ns{4l@Zs(&z<-1C`c@u-@`?WM{ef6y!)UAuTpiSl!DpQSF%ovHXy@rHR|hRcr+ z7}YA=B{-3PohgR>M6bFivj&_#KG}4!=$rJ5$&#{4uP>vr2toM>4ZxB}6=W*;3!|#l zm6K6Pd6nE}E^Cf&%SbRI)1I5xFpOn03+uB3ss4DkSpmCV!^rZ4^oj{GLsDEYBdKOi zQ!G4YZD5;J<3fE&p~9eiH8as+Otfp_9ZqA`;KD@vYG+6ut1-mJRi*msi;`fuBE5T| zAyIwI!VC$Qu@{?Qfie-l=~dH*2*8fLNLPZRSPOVR?&jL3;Iz^j(6<6m`LDcM{?m|2 zx&Y7!Fgl5%I=M{FNjg=TEpwz{jdkC3;}Vl?nHdGjHPEWYB~q=5odtdB0j)2yXDe0S zK-~atrYu5aq!aQ>M`ec7fzUpa&8)kq#{`N-N9wK?^%2@qP4TKg$(KrhkYs;@a~8*E zKxMRCNS>1%4Va891YPDi8khd6xJi~7g#A`6=B*i4uk^6R9EXF1m@pz7V`9|g0#IMR z(W$8geHuyakk)j8^2L6*M|Jme-p(a?!wk6%&n0qo*w3FsjG&i?&In z8dG!&LbbkvAE!8oB`&ql=dt?J?Cv;Xb#&Ll+}j$SIMCC`7u>SMF=aqjmNjQkAe6l1 zmdwWDStIh33I}I4%%!7oGulA)T8c)cmm`Xc0tUd=M}@WvtHxED?3)4cFW<^*u}B2M z`s#mhOD-HrN+J#7GdfMMiB!<~)}lTcr%7T)?Ntx<+?Y)|jjl*}%t9n51 zHqz(DV+sEq`a$D3nF}N;iLuIiqR2Gh)p&wf%}5xh%%s1OF8YwTK9?m$hcHfr3Zfn# zQXfD)SjoaM0=Wp?TNa7h4Z%)|f=lLn(TL(sw)B{p2 zcu7WTjM^10OA%M$`Q;329eSHQ_9Dl~E~u3kX=E^-8+fiK zl=lXGvUD;Rd6pcG{8VqH=k|TOLh`87G&9aFeiVJEQT(E;?&gBr!ksI{Pc4N_1Ce_%HdW(wjj+U-e}|3>^JAxs}clhjXo zq5~c#RM1NsR=Q!vkF*>?&zD=V&ePSPfXrERy)NtByDr4U_-4(_7KGxof#$6b3qnao zCA)6@>gpk{z4udcv;U>Jv&r}I*`_fQT6Z{dO%o>3y~qdDZvn05;8z|Gi@ctZhhtZ= zb|W^NoF#_WS^Q_;I7`hXet_aW6Zc-+SsWf31$hdbR4(s7`hPAUY&I_RX>;4{Zu%>J z+xJQM^QU>ADkG`xC!_Db)P~qF+$V_94x0{(764u7>NY$hUGgTRrU=sRNAmvg_Ww+Z zL@}GN;v0RBCYrua!f(-tlIX+N_ca1Mq!XKaU+sMX_&}Lqb4~&SHvx-R?^CPwmUvhy zWd-OzC;_)6>TC?pj27^jAom` zYB1oY4{N-N#0S&t_-ruiZ4R4WtF`fKGrV4t$)Qpk6>_!Ks@ItfI+aSRR`9Vr!YQ;S zy;c>YH<&eAtI4R2iPhoyPQobpKe4UCli)ymI3_l%R@+w!rdYfG8MHR;Y~-#eW8~0; z4_M(yFB#fqscmkHsko}Hy37)957#!-RmGC(M%@oCv<@#zWax#Py;Ss@FusgUCgvk@8?-o;^&clJg2z~H+eg9Uo4_#tppQgD~mf!^XvBam`0z{~$B zrQ9D)Ify*PQp)jY%0%%3yO@{|;NKNZxeulOCFMCxQ^2i5dj0%MvL>vksj#4Bgw2`T zmC6KHQkr6`fsJJnxU{XhSOZh>-1!R1y--l4<3CKOXcQj&4>^kYawYDLK)E9t!3dqh z!*P%74(E@{40o*ENT&YgnE0k6zHWExlGTB(4aeVJE)q`?X|9^xR-I*i`zBAx%Ehv# zgYpEE_k>dLjZh=*OoCjODmy&c%} z{{bg`R?IvPGc_ErvK)0rNbtnjm5M}#%N=ivQ8`s6y$)dK6nB}k0dmJ+bsM!t2d6f} zq)U(YDNjmDL*z9Qd3O3V!p`t=T7!4tst>T}z;hS}tkO9eRdeu*Z!{>z=mioJY-Ri( z(tf90mRfHT56Q*nwu`$T8JxPZ@o?IQy<|l~&p-dkJ@TZWR2baFv$>5Y?>Uly9b7X~vn~+rlxNh;)W4v>_)f7>#iI5kjH-Op4RP0?b;u2{=cx zl?WMOH~EN<>CBvyc^b#K4vi->w^C-y-(JS+x7&zNBT+$t&mIPP-wyqO_3=PwSZw z8>7?Dm^SsD$<-s@U)25Zn!#$NW>DH0f61fXgHy)ca>7msP zTJEQl{){yDNv+Nvw3UXqL4(B8X=!d8K$PXCxK4T;>B%b9NkZb2i_6t^ubuc3;=Rqw zM;6laQKk`mElPZy&IH0vYnpwFzVBKR6Q7ho5>n%~u$?@@*m&G-jJ->s2fOd+JG}@A zdp}r+rS2NgPr8#q&}k~YBLy_U4#r}Iy-3D=u$E>91wr01VPT+RRa`7%-xeZG^HABFbQ6Jrh9 zFIV?(KYYZbvn`4#hW$-j^!$pHD*7EyrNzxl!J2e|tmezuCm~Pc!x|;`j+T+Vb3{#= z5I+D-hI&NxP*)zx-^s9T0JkEL2S4gUzASFvZDYhY$F8((jNiL;K1r&--o`$;{7}c- z6$d*PU`{^C-^JY~45jP-W8AyAwiCREDyhbSnZZr#X-Q@u4{!lbhEp+WzT_|5k1L``h__R$kioTPWi zYj9ra2VK0(+p};s$QLkcNhVH%cy3TFTdnspzM$@%eB4|b&EIfM{zB%+uja44CV$oc zQvbF2tC`z>wf?rt^}o~fYP9`f=)NYNJJn9K?Yj1)_EYVAdmB3_+L`wD{Cw#ISn7Yr zHRTH#xXt|+<;Pr8zKU7?|EoOh@Bi)jjlExTanks~a|EmI+r3?24vb*$bctddo0>x0 z{YQ|NxLZy~@ahtUz4!h~39For$<-yQdZ+wKiB-Q)qPq9`Un${}({YSEh1b3YPkIu zYN+nr`G2fo7*^$D(s)AP((z<&jEpC~De?F(l&EGN{*@BPr17NB@G|eripOQ#uZv6H3XM!6uPB6NC}Xq#q&9-sg#-%`?r%)v)xBm+(u-1p3 zL_mKPHmD9#^@z!Ck}=lDN%b+kJf6O(?aC9R5?+r3pkq{=t2jse08;Uv^PhvwLC3g~ z;D|t9Ngh5#zL7k=&g0hWjIt0X`{_VfV$Df4vN8|nY`B__a z=L{ho=u6{?{C?fJfbLx0)oo6pf%xSxXwn!FIqpJL7bhmnZ))5npX<)i7Et9b5v9BNh27imX%4k)`37WAK^n@+#~ zoE|ox{v#_`0(r^UMy3Xn^)$9XA{6c*MBI9km72&>e>ULkmpA?WCz5;gc9Qhn%WvFq z^R7RMf15pxRK~7Z^Z2G~3H5m0`KQ-CZs3Oy_s-Kp#V_0Mx=;M^(eB~XsLk;TkH*0U zKIWL+W~MYTxYVY2y$L_yg(Q2N-3TtJ4r_7ASA~n1U2$A(G$wmKkFiYPu`}3$A+J>!TP`gQE?ITc01HpGw9rl;~N6rnu^|nXU znd(f3^&~{2R}zhSuU^J@=%}gU;xy^*B&DIwO{eoQjXa&cnXY2nbChSP%gz;vNv~GJ zcDX;V!VgN4pqD%8q4rZNi5TLgBgLPMq|DNGNPG+M6uPfJC9!{g7F+G`pLtVTs5|F6z$WDG1Z#1 zxHVL*HpSxXfQf_CP4y!%c$u$aQQDnzl6;kzmGbH}Y>5$*#juEnk7Eme-jDs4;sDFJ zZOPaKQXki{V0Y)wT7FE#I`F0VzWCzrj*?sezWE=3ljoH=<_E^xNM`B7zWB7Elp_-p zEp)(&nQDAVOUt3`sZkXx1Nt;|cn`_Jac*vK65Qj%L4J=6z>!y1_*$E7I(>3;mm zEU`ysiM$_?p-}v6mPo7L)w2XbK$;~UH*S`NK%h_`5CPIj45kY`wE8*yzFu`7NhgEF z3tzu2e){FT&vwYjBM0`+CHpWscUp-q-o?Fm8 zY3@zaM?kg<%xG8wKa&l|$yx>^L>}Vjd|`94F}n-%z*m&lr2tq$im%H_I0Tu(d!d59 zP~GEv2q(D$&az<1p~k-m8$@o)lH#k4`3RMTJ+Pb=B3Hb7fI$#RDkxyXTQkKKVE?dELOO1?`nOJ|;MHd{Nhdr5=Ys&NO7%RN@X^t}h;PFIjql4Bz1?G^!Nh zs~Vdffrl(^Z_49}gd^||_QNKW_L)3A;WJaJWb=i^DT<~bMS&C)Sb+*5msVVjAdM4^ zv*d~_nN?#J)E0IOOtWMT@Z~KS67HyQ{xLNvJ=u_yV9_aj9%G8mmgzR}ch+rNzqlOcV2Yo5!&AyH$##vqVsugI zbsZ%c&5Iisyt1cFquLr{6vx=JJ>~>|nY*$sDKG$Z-OmQNGPFJw5v^#w${ufLgP+;$ zKJ90Ubl+#5NbA8oQtPSP3uSqP-qS!adU}pS0VMSGB1-s302S>5S7yr{T2OZDxZ=@P zx1~8VYfxflv7YyiEh!#e7@yL-YHa=N!QK}N0v zDnq=@GruM;FRiLAFSwwyBBynsyL_k%CU8r(*BYN)20P?Y_8`ad|He+j9@g<%IjN90 z0vGy2d9R!rm)qx3%d*D|q~>5C7%&Go_S4m$eYW~jZsVt)uKDaUS_8KcHRvH*Py;q1 zq=Gb(edI&ZO9Vt(Ni_gK+I*C4;Wn;W1Iiu6F(}L5i4t<0uA7)JS;=b!q80o?h0rMM z69j}7qg>nv^h}bLC6V$y526mTW(~2S9zx2<-??Ej0vl>PJpJTNfUl-cW|PPq!qP{> z>yfsep7t6L)=Cky*{(BPwt*M_@MX1?{C(4j_Q@pslW)WiCbb=-R@uqq@9g!cQ6tqT zYm%|DM#OuuNt!tt1bjqmWTf+AIE+)@GgxbfRjXCQ{?K8q`{x<oLj(cm%YQvak5=VGLiBk*TLN+rF|LAyZj7dEL_Iglo@3=~QNMaN$(~0_=yItJZkFsVl)5dN@;ypDE|n^drW`@d zyJT;pR7o`DEwpEWRBBT+P1_MA2O5p- z)v&ef0#43ckn$mR6mDys%x30mXe2Zn%@u=O=cHWU{7S9_@!#xQQm${WxlXfl(a+oZ)n@KA zZ#I8z=FOLDtLxQpG160uuhhnMa+|rYIiBn5Cjr$yXXoRYB~mUk{MA7=cc*)^`)fDv zma3B|l8)y-Cp~vlzvn7C6`SE_%quQGH`F_Wy_K9o`!-*B?p2+o^bIk?*jt&mkZa48 zTtDk;sP~VkYXWj@?f1;9vPo@wPW&DF9{We++xDMp>%D+nf|P6ff69e_- z8dJ_BhGWYED?{&Qr*dgqcmw-5$%paee8rpRmV|#x%D)@`iLhoP+F6$P zAZdH>r=_y4U%;P66xPlBC$I-(;{-W1Y^)Adyqlk;b!by}XiOGM7D@*ea(6>?IYI;j(yc>BYzx@wZO;@SSJs+t#<|C{=*@Q%vg)tpDx9k3BN%rzKc% zdJl>>3sn3#n1tiDT@Eu$cEQKUPK#E*LlH%_mRjY}2vk>yY7YelG)5W;ZrscMmX?uI zRy6C=Qe8@)D#a8UKWWZDj=TQ@iQ*q}w#}bCymDA7PVBk=5riR+liYt?`j8Tmu6TY> zr5#k!LKBXaZwaeol{EwvFMQJhs8HZ0T_6mCX-g0Yd{BPOkR7co=i z9mmBk52EbQ5^o_~@o_6BusiS#gyKJZ;XczK@p18s8a;pC4{wu|HF`l?PfE#iha|4x z90hB8_OqS4k}rM2Gd+*53TEEI)>E#aJkdsu^FvsQ&89p?hS3O8IxPxaeBz~2Klcnd z{ywyKg4^nOi*Q)d;xv!oh98!r3QYx77$XR=92?jE>>>8(xIa7~92Tp|lk^w)_oAd2 zEvaJkkH*MY72N7++(X1mmv#rgG_;JITmI4j-nsmR@J;xDYHG*{sVcm~=0ku?gP@*? zQY&B$hh_e$7*=>nMxLVWe)GKUO{wug*fAo%{HvGpxL5jq$;W4VR=vdDewOwdm^%D3 z@Tp11J_%?)JTQJDzA@+#Mbx^Yn_qE%kzn>%E5FJXsv43#?XKCOjG?otd=1s5@x>Lp zJ6689p*~~yiU;0X6KHQ8lEhbB3+^MndM&sQT_tl6wrl`$n2dgclz2pJmRZ0DCY);P zbV`>~tQ*OXNFfWX$5{OllCjf8I#}h)S`1T<~nfQtL#e4@5FI^=07 zB(|LB$m5(Nd8D|Atnae@R3ID?*N;eaj3C$Hsn0OC;_l-d%p7xAsmajqh|6GWAu@n^ z1W!u%#b7T?F=41Z+bf}BTz2`vZijAoar@whW!Km*2x|2AuYqxOIr7~ zO**)!(o-{Kpl@K%po;0eb%)|VLuXAHPocBCaqx!0-MrY!>oB9^u~ru{*)KyUW7mb?M=&Mm?Lb1q)#pNu8T8l5{85cgr=FGU}y;U9Uj*j~)pq8W-Mr zB&1_p2a4^y?#f>Mb`ld;vsY|Tm(;s@1;IvK>N^S z#A|IPoz7z5JX@$sl7!vRH$5WjYoF^?R3=hCcIs|GgdbQhMuPe+>|`sLaZJh+j0R{( zG3o;8dQUw*Xtho)t5rMI&RD00XWDVY5H0_s_y~VJ_5fan#(>lE#l3ff^9}(6<`}5q z0KaP;<~WPR#;M?|sf!Q;s9P0uJn3*ol?@4e3!Yihc+yx=_D4tep4Zpe%F7CLCE5&s zj%Ds9Pwcn8f8Ia_F7NhDX3N&Uf5$L|S|=wywN}z}s7ifq`j&IgED%YSO)7e|!)j^CJwJZzCb~KfQk{@L zC{t`{UOC#|b=T{2npcj@&S{ym@>V(@%CLg}3urwlObP8(+zzKv%jmhx9a>%C4lbe@ zp-bo-hJc3bQacLuL8Qj_0JNj49P+&dg~lt6iBS^3O7snX+n80=)ZA&#V>?LJ&e9G_!tYfm3E1$_}PYwX}=>Q@VX7A)>AqfTdVby+!; z0WvCbQ8O%!bc7`F1b;$IYcJ#ww5uy3ihh@5lD%@?Z$_4nvP={Y4mGq5EnFy`SaQI3 zU?cfr`O#T<;=SW1tR1nsenyRl&lipuy%27 zN?9{q`S4G|X7f_rnD^*nbumVx)~?mk#Rc*cQ%zdeJ!ld|`jWtNBTb_VfCLIA`D|Oc z3f4Rzp=4a0Jy!LA`^Z4?bnQs@NKcGWAIp;vCzk`)w0vD#T%L)2Uu6ikmAO3o#79WO zzPtSsyV_D5<)Q4@`3s?Of^O?Ux4obnJoTU{nmESHsadrmUXSaBQ4c`qKs>2=RByn! znzRDKdCtgzW~nYKbQUSTr!Sb#!zpHnCuZJs+}Bi1#^sUP+sX8!-M&}FLe#~o;HnE-h?KOEkn=ft&BqG3kKVQAgzh zJ=~*r6GUaT5S0#*Jp}YL1QbGh#o$tTZLuJhk_s(0H86AK?c?1Y=>_I;XGyoWW$rER z+Cnloi5PApgAX>lH;5JR_~exdrZGowd0uy6toC1+3gxTV@ID;Le?ouvJ>ni}x7T|g zfn@y_67)Ubg~;UdBA6)n{uIRzk?>1_7s!mhbPgJE6482-ydB;--c8=kz%Z3F-U@HE zcR0T8^M37>d$GTdAP4r<=%qCh)F6KQ-_-y=+%F|G92wIntsbX<1OiM!V5vMorN3ef zi#N3Wdmx#7N)bX>sCY;p%a%&%TY!o475KpmnIProS4!zoJQ<`%@MI)ZAFLu8x#<2R7gxRJQ)H7P^!G&I0Y39+f0wz*K@08Pl$>t<&AEJ^vZT8dni7?rRLpX8k zW?q2(Qeih>otVRF#XUYU{XAK+f)j8_85g6`DseaL5;1|RJ==3L`J*b)=}_v+?P7pk zdX^m~)~cOJ2}*@M(V-?!_dG!LyWQ|w2O`-t-fi_1O-Ut}{$!_th-;2K;tI)^7FN(#TD$Jec}kBwg&C?e3N*A9NLGgyT6SqGg(S3#2^lWR%(TQ{0Cr8 z%J@^1?zqk6Q|=7qF_J5d!y$~%4|F`Kvj-zra%7Q|eh}k)RvJ%3B%MKs6);fa`MZPx z!lxKFU=_g@d>ff1rB6Y60@C3>N4DZGGNx)^B!3M5u+SLE4-Tv%kM&NW(PAtV{^<&sBpk^A@w!rQ{V$W_JM-1{`%ZzDmxqfYky-lx&FGUWIg zIlRnm&(XhEkr~q8Z(|ea-A4L`wzbUitp%_pg8YX-K#tQQ(e4x}gk{8Mew}gs^O742fBpqYML{ zPRX72%ZLni=eSn_csbinfPd(~(Iq#>w%CH2{)qrk_a2^Kx4@Gt9JKmtq z8+{k6SgeBN)EqEkOA;X8Oud0ud&lNj6AcP)wx`HzvW4f2u3YT%WKGV=@}}nv80s20 zy}o>Q`cL1PK4|`c-1pZh;;aAS5C4mQ^o$s9O;zblintVqB`Z+sb+y#xcukKuvs`wY z*WvCS;%lu+PtYsxxP$$uC$XmvJtn>2R_+vLml9Te4ZHJ00buSjvQuG}!OS4-52%lJ zDyDlO6#yw6I6@Rm4_Aezu+2 z>t>lOCT6XBZA^^Wn}pEU@XaUPCzGCZKPd>x9A{k65^GZmF-pNxF*4s$P?BiW@3SRj zvR zpiV0LT;dq2(_uYDhzVpJ+lwaCbr(CD{nC!6nxBF}+lLnHag-)MU8 z3FN2q-HS7B+CH8I{u|N{iyQb7%!Me%no=Nhz(*{o%?L`q5OS!1o{2kEaa>%k1-D9@ zxxJ}6jlqnlI!W1*<_l;|U7D!A8rk_%8BkC_P2zOjgz_z2>CqR%^_$ zassH8CRIut&hUo!91?eLPAp3-(WH3YYK{+#URGByqTH2SIkrfX>@>05P_^C=@6xLD zGHZ6vU7k@vcKIcS{9d0Bds3#=>1CEI+sHL-SqXtUU*V|wurq5$cdLcY4{#1o@09?8 zG;Y`30t+b5aZ#laQywj)t#$F0Jr7=wE1q&m)l#;Ft?PLlw#sKvUJH&a0JY@U1?tJ} zzsX3WtOJLFs7K31bz_8#L~5dgDR_pIE%*`vaD*gtBqCs1L;*ccur zK7i``1AcwLe-?|Iw7lUm2~KizinwvGM`yl}R#Kdv9tsKHi9ER^?hj?86&0qZ7lRI@ zp6lUCgs*`1Ze_e-g9)KiYF18f`C#>Wv(;*jR^LwR$Nfw2wxXB1M(!_&t}!WaBO;R> zT00=QlH+yy_!OfdnLH={W(b)q)H>3Q$#FV;0(Rh@IGr|A+&zR~7e>sykJAg!NIgmp z>(LwRdx$(1rmebIdiX`3=fh(o-J@d~bfxqQhUN5EcZc^~?kOrF2H3P^vQgOWnIGc` z!5Tnmg*s`CR1csQ$RIE4QL`PgQR2ZJ&(czPuz%=LO3AnpjRba;!xE}MVXWEMMEK9b zI}3F{<%?87ukL`KAp1A*(;eK0;zV3KSp#$XdppDvs4W(_GG9uyC5N?)QYk<)5@456 z0%?>ImdeJf>qA`ucpY+0?O9mFmhDW2Ft-b0l&;Qx!_7!Gp?l2`SxT=Ot=8X7GY z@!Eln2?t(L>R2|hM zBIg>^DFRh$IC8V4C{$n!78lfv0%%heryn@`cBqgrrvH#KwApOv2D~7pU4^)WJx64q zIGVOih@9g@jMdPAJ%GNcyjA?iFfWny%qMGUi9zD6>`Tn&krF#;i6FI)P*bK<;yAIc z5_=mhpZDAa?NP^cGj04BekkU@7X0dj9_WX~v4W|^4rV0N!AxdmGuJUInCHV2rp#y> zK78z`#n%^=&RLL_**P(JaGhFF9p)JYeiD+BOEZ&`GfTNq3Hdp&?Aa2A)-RejZ+v%6 zhNhtPEJ0X6wM^c@!>OC?Ct!V{A_%H{8%C;%Kj;1A;StK>y#$VQy9Z|@KaRG z6w#YmBD%<%xJ(OPW3b0w@gz)Sjnb;fM_s@vBBHcB;&vJsePG((V(}*E^o|s>#S2t- zhj)y^=nFT5efcBjm9M>i^19@3P67}H%QMuf#h1=-Wn9@hgCoUc_B!;)ZK9>g1anzR z)}VpajU8p-&ai9v-kFBvpgVg=O;!Eye0P<(r<(hg`}UHA{P!gPG;ZF$2>#X_mm93O z5WydKUjmnq)5S=#>*K(eHZ#Dzla^MtY+iS&*_&t02{1d-(@f;6-%ky@N{s*~Eqp;-;&hMJWzsoxcTMEk>90M1OytJ5mV%<}V3v$|4Hs1Ps7q2O3 zoK`jQz;y#~55?pBqTbi!Qy@QLFPX?I=;M98h}%G)yv&6+X@uC5>e0-j3{pAr?zF{)1+cKe=loTw4Ds*$>8maDaCj8{)@{M#-S!lSP1}HRK>!2 ziAt>SU&jh0=;7}aAf8k`*?-+O(twiNmZ5w? zA889cqB6Qt(GC(UbbZPnTt>p;=_NmnWp^*$E*|H_!Lhv`LTknz6C8V=#IfhFfN$jv zV|_6`#<9N_*ry0>^?Bkyk477@(wbf8USvPIG@Lu!<9rD{y}&HspXM7G1n-1njlVaU z;$^>=Gf%~u;CvVG(}Gy~u|QGxM>7`xK23;z%x2j?g}R4izSz3{Xj}WyTZWy<9X69& zoz}d(RV*dXu76>5IK29W^|&SQnPJzrWI%G=!Ibge@iXD=XN9!FUdnYOKAtll(JGH{ zwxfv#*--$7U=^QgnDB@w|hd!vY6N4>Yr7-AKgpF6&02>&1A4oS?>7YfO&4WfnIoa%@ zDg!(cF}LX#oao^#k>lmWX$tti{;9$Rjsg-g)W)Edoy$h%F6e0e{?nplQ z7@nSc|3W_5qyMhw5C1eA`I=DQcGSlr9|7n}Uws5Sj(ME>-;jKf`bd|o0ynfs`Jks> z$)}f9{MgN&6}Pj0y|zB&?#l-wUz4o*(g#v?w0-^SLv?-mh@Q~;_)t$8nSt^ffKxpR z=SJ~N02-?%ErD^F{S;5&vT6?x_vj^Z5~vAZ7)3e3(glzc4Z9)Ox%R+Q-Q7KPE-$leEc;?l z!Njzh_JUx0O?rAwd$6FrCXG^vJsTWXla^L9E*O2sI9?ff2X>6kaBL#ar5V^P73cO? zLBIE3sdyi@y!T(h{|Guw;k+gxuG>PA;~>> zaJ{pk!C60eusbOsv-O6Sj)U87Tr?warEPm)VZ@#>PbSl)>9SO+1j>W`TSl7_ynO74 zD8{XJ)^+UV67QDuR7MGRb)0Vs2ec1HIL*MhUd5D<+aWa7v__^*0}@f7Bpunw5HhV zd1Gs=4H88cgQ8S_i+xxy*#QF)nfWBDnaMrbLSGB%4TIblC9_)t;VG+cUY@1Qy8h`efgI<`OH%)K`WA%uj4 zBTXR1qsONf`|)>il7KCxYez0C|X;sT16E1wN_iL`&zZOw$;|Y?zXS5w!ZGq z+Sb9u@di;tIJZ80!OC-X$5RJS ze{89}XjWCKwQBYFFQUS-hvbGaS#Aob^bIEKNq-h^M#y@KD_B9k1XbCxjp@8mt80Z) z$|9M>(z|Xk4XH-X3Np?x7Q`}$VOUH*W1UWcewdi~AIKAQst9CDD<8-d|8i>@do{XHQ=z;+{eYqfGDqz+7kl8#VpL8Vs9gi%B1^)XwD z8uAltp1z)8mej1fukt(8F>%pqO-x*ry1iPup}o{6F3ze_N5{vi`D5+5-j*n<+B+&H z3T7h0q*wW;u<+Q~3e&WSY7~-M10C|-3Pox{9i2|ggU8yvIv*TW_v+j)A-l>pmrUy) z&vWz|Zwa<$2GHl|Nk1tHrz%w{8U30bE=24o51B?#dU?r^`;v?*V?5eodwO{Zt0OB$ zOc(skg`*3#k-l1Wcz9--qnxV_?d7L7n@uXm4g`PIdxeCBczK4I!@amx$7p4^IaJ{p z77^x2Mh%-+77neM=NIr>P|r+(^8rZ?mIU0!q7dd5207I|VUS-ymO7? zF2M_zxX(QSZq6Mid{3wQrv`Eej)l3F9C;EOTu8!;CYptD~Edo9V`&ZocQ6e zE5n$N#c5tau-F53sG8|d^tC1Aqdth|bJ=Aqd=_A@sqw@>NB^uAmI*pFZ_K!GD_|y%%I64tW2dVsZblqP@KiX+< z^3h)gXPpuXx#*5%@EU1OaP!qdD5#kEh}f1`*_P-?-PH4!NaCGmY2n$kq?o>d6N$bQ zoWI}&Sry_Ac*=fY;D0>BF5F_r5i;kBnS<2HWGv=K#Lp>5SsZuxaYtD!cbGf#wqpqx z7m@tJeZ)-`Blr}Done3Y3O0b7eDaMs(&rt~+{f5^3xAVqbbZR1?SM}qw2xeWBag`V zn=FEl@T2KW;XiBCr#?)4N6 z(6K`AlWbyCH~iJtR3SD?(%@poJ^ zQV2*yEwM=lOEG=5)m4BGcY^68Tj^AjMh*5c7pUV_qT&w-*!iX;nVTr-0t3o zGHfUNwzFH~VZa_Kg*4@yI|3IYo4W%<#ylbTHasCtOu$3K-bahyz6{7q#kr$}S?+I( z3um83{N?>fOy{>{&EmI#5$Aic$19w);`?Cu$VZ4PO?UrY^b^ULp9r5H0BCZ=+0vvF z#Mv00b#6R&Yy>nA<*}A5DWpi}TA0g1#N+GGDLlp5v)rT0x{B{(#rFd{zLPdf875++ zH{9Qja$y4eLL#WdzsB?Ma5%^Ib&ri3y0bOL9X$a&brr`x2gtXGbBWOyk_mXU00%nk5e*j&C^hfapZX@pJi@X}|cnLC()%HpZ#&T+X4^SuP?d!tL5TwLQ_!*}El$t9>$K)&%Nt z9>8ExsupnzEMo?Y)CAED3{^~HV80;sBP`DusfUzENP2&H!#wh`Mum^J7f;V~9tsa$ zh#ESgJ|(+fnm-?1JGwD-{4|YX9Z~r+`4P>JMb<}i!yV@%iVcZbkl}O44afPIB12qy za{o!Wg>KX^`jE{PAN4TlY6J9)D5qU%ndBBpOM$NqcL45nflzq#`N$4d$%BZr?E%V z_@QOpgHrnS8~B56$!|>_6Pre`5E*u(NGv&>0^owqe6{!th{^wjN zv9!NQ298UfFnv0w{gD;l_;c8m@2@wuKT3YjThz>Cn2sNTgZ`p?B7p_SNjA{W#d5I^ zAc2{)kl+&R_$5ah>^u3Haj8K$wNDeoCtvHN4M zHILmtyC88;b4BeB^F}U@qBFEnd5J0I86h=gwzBjfVPQZ-iZ!JF@cQKN%xGg~L+j8H zuWhO=TzqlitpC0JyuC;7U`_itnB+raiig_j#wV4H0D#O_Ab`&^QO+cmp}zmQDCa3?_ zxxMllm-jAT)KKE9Ps=Y)E?V_y@64J78_LSVGD@R+4)C}2atw$rNDd0^TA5|ZOAZdp z1~NE_87r!h9)&cN=UR`*PMt)AKprTS_ZSp2;5m~Um;u?f9-$_(Z&PK;n5heUR(LM>WUr~NdZH@cKcoMQ4YiN#o1RVIH^$my(#z8WeXRC`)QYSSenZ3M zcTW{Z=U8>YK18C_`zYh0x}KTZt2}>VOP?-HvnKRU?z{55)!IATl3Z4sWG>E%h$({E zip8q;VRtm5Orn?_!)KMjJAiKq7d%@6m`BIy(7|oNf=Xm8unbONEzg2yk#U0?g9Vj= zG_?^nRFgoB7@=k36VuL3-Mnbp%hQhb+&H(Qdzbp=(YxB_K6Cr=S4hKcq9H}i*ZG{M zPp+WXw(K~%l=wL&*Y)GGa5CNy z6Xxp|lMxm(D9sp`+O7SHS4v)KVU{Loc3(@rEhGWESkrNhdtKC0jHtv)bO#kWo}~yn zE;#i&UbH$o&lV#;a{ND=Nv}UbY(+?MND2%|b*4Cwv;1dw+O4?>{(do8CTm_i`wfEb zc#|F_O^}NGpb`2Z>mKq0DuQ{o}LEmYi6lUtIRxv;P1RFu56BjeiBTnLuxWc9lf$ z8Q^y$Sny0fXa#|>n);|d!W>knQx6`ED#VbX*yWA$f%?iKa{mH5|LdBzjGie$a<9*{ zo*{AFVlw*J{7UnmK5XB2Zs=3BDKs#|R_shQNiB-8Amv0@Hs{mPky*C%@QnUR{d#r} zvF3E?7Go<|NaBYgr{nI0zitsHd6%yilBB005v590M^#b&sVsZ%HI|RV$l2(w_s?j6 zfh-kMF8=mdNGh+^$0V^HkufD{Au?5N)x>PNs?TsQ&zM9!jfg2p#Z!CLgluVSOj($Z zIwU(fB;9HZNGgiM)jxJXVd#pOK4G3}Ir~FelrbQ=C@#SH2gYyC@ijt}^hLmF1DrO0 ztI7>0LeG&2=&F&Dflin@hKZ|pae7XsfS!aCc8M?K%B5$-6DIKl?wFzUFSoOkL6PN= z-EAS^nWd5O-Q$gVOIoN}myyaB##L31O1D?%1P8`vg_sh;401u^8&(TL2q9e^hq-0w zJ77dq8-56@BF>KR{W}DFniaTW92^DBdwI&kEhYH{+8Nmv)~ z;NxMimPZ+UPm^?rTArk@w?shAQDQC|+_)hLQx?wIc}T(1#5 zhn74(c*4wzf`o>->w+7i3e(L2`rR?nVRpS|d}Mm5tf+i)^`N%$h0~jU%8rTiz>&spoi&HCPPi?w6ecZ^!Ct@S>miqWSp;Xcevn6A6?BLm;XBsQCk$=nDp!s^A203S9 zZ@NIZ!=5;c)1y_ES!cCjezAep{}$|;#HF=maGxISnEmuP&eoR7y?;R3)*)$cN6Q-3 zuQzVoyoqr;l)@6pAF>@-Ww>3z>%+_jgF4vE5U%dL{n{+|{_8~oK$W-*gDr)LJj^=a zcAjN0lK7){?=<_Og^d-4UcKjc%N(p5l3QepwGIw44j))OT4qi!@+8u(iDd&rr&)3W zgNKI)`UmJ$6aASPg1&=w+OSS9woWYoHyVMRScL5UR(pjf76vM{p$;R z4J|N5=uxw)TR{qG1{}-YS=vQ0U0U=s%<6>B!;=M_cfbu9oF_6lV6&z%@N@>fJ{{e? zh+*{rPs`4wX4!x_<6lOv4$GFWF~U=U-RXNIslS3w;Ux64)Icvo0fF(K&=2s}1dOkg z1Rmo(Jcy_KG+>uH;dbViiJ*%+EpGC;Epdn9frO~T)~!O@2On^fQ!uM@^lR{(5bUW6 z)T=w>jd8M2qd?*!TW}ij@VdDT?JENK{4`Sg&6 zAp>^|C)?7-#tuuH7z?8#q2B`DAn=bsNzf5J^6p;5EIL4}!T|wk+Hx6Z6NO};#d#_~ zq7XX)yJ*57K^}!$aumr?m0oGvdkG4;jBN7aEMpVxc3F_JD{AsYbWI!D)j@_E6Jso1 zBa*w}V&{oEZ(y%njfdZvI1FB6hV8!>-t&knwGiNBK2Ou6(*-s5v;Q+v-r+)NFfTS7Axx zfPT-^7@x4T1?p=p^Fo2u0$}wFRu_$q&k-RZf`^YaoGmX1%QL93Jce4})^-s(2n%Ed z`{|6|haegXE|yKs$cwh-Dv~V&RcTwhDUz)NlfKH}*eg5tiJN4WsG3>8wb zq3>Y1EW?srK^PMWyWwe0a|*kL;HPz7JghP3n=yf!g2!xQI4){biapPxU~8Vt&zRU> zW!qLNwS;qoUOG`|O6gi`_sk>(^qn|EU`@_Vx*ssy!K&ndK_>}1q2`oGMbIiwVPQ_r z!4f>d1{wFra4~$4vYhR1hHc}vxQa4+Z{D&gM4FM@C1#t@_I`A6H+A51i=$IQ&a?AU zj#GIMqen?1jwyIAOQ05OJYq7+y-s0?t~uB;F%hF&v&&!vQv{3BzSl4i@%ZTWCtfPz zD^j}IL(WClCykTFjZ2yAW#5*gjE(H8Oxu#}857Y@nYO*BLTKx6NXws>lfN(|8+8M| zN>-2iziumHZ^*ny*fFF|5CCXsrWj4Hr)JTh1p6U}>wyI^D6a1THo zgX{kQ4%l&SR%*rz@uTDa5yDa-I=1^`wz0_0=wkmzF!zUs^KAF@{xG!D+rX!X$mN)9 z6^CjB)?kByNibG})nN8P=b@|zZfjOeRC7^-9lU>KcVY;5X#`KmkcZ1f6BpZLYb5dL zvv}~B>3xL|b ziAry8Wx0||NEwP(z-8?xVpxc9+*CK(CB}y;Zy;#5c()t+)y*+@sXZ#Mc_yZ$8h$RR*f}&U| z#*+hZg}UiWlr}{Q7HyI2@UUg`GCoqA8S78aczK(gv-XbbSy8pFp>{@*Zjf(SpX%_S z_!6DaR+$+$X4tT2`UcXIqey>gb5%^-Fx&=QhXOL&Ey!#JM2rR>58;D@Jpv%-GP#Yd z(TA}A?eg=#9^&8ZZjS<@9G^wfME5kIY{Xj($(vJANDIeH#DkS$*Z4iYR0KB4kKF?t0LVLBan;hku} zykfXDE4Iy~e8_ADqbM&J7%yS=51A}#{E&@lWyALC<+9+D&(pIe)w@QmUZo3>cIjQ$ z9ADG__dI=aJdx4re%UzzApsE~2H5C0>Hr=D%+F-{D7%+V>B;eO9*w?vDFcED0k}Ud z=CVjlgjZZl5l;iFW#L>koDEF8H(Qa8Dav%z(e$Y1QQytJ_&0q_)$r*ftAqQ-B}JH! zLfN}~@Zjj2pWNbHK0K~tY?v@B^n@JO}ZRYp`u18uF9?woLxL) z^nl_&xTmoL;+#N7WLicV6JtdI!KwB*jm_sqP3*C7K>cJgDsJ2Ot=8(W>ub>~SxovdMz=c?uAv8X!c7 z=K`nGNfl0!LDa;MuJ1Y?xMbY$h{wcvPH;rUgF*(nPYS6O<*>Twrzek{P~@S+k;&{8 z9TJvUtQF79=xQ$&18+nf4o>t~vOwCcF3XZ!+aFMVi9KUCpAy>>dIDK@zH(mS3Eq2H zN)+z<9yK(?%N{!eLWMj7_ZQFwFy%%Py380CFgCz{NDE2dKS+(}F5hmELfe*zS+k;c zaFRQ7^?s_j$(fjIJ?0vXxqP9IM%q2KYN?0X-`~riVbjS8nkhKN3#U$s;vMWBO5iXb zVpLhvtqiLP8X#{5%|eJH)_F>w=s?Spmb~=11^HtKjpNckDYb81ZjuoYp3qievw9!g zACh0zR2OmQc6c2LX~6OK0wk$`rjN| zwcOVjJfIiUixO|f2Ox6o(1U<2>kL?QapKmvEsa~EKkD~S@Rikuzt2ftd#w|U1lhWM z#cW-R#A^3ddA2Hf)4C9SK!9AbPVeE}Dn}dwdd;#_0A%0eCCe%jPYqhXGItm;IZso# z)ymkbvuT+Tfk}^b&mC6XKGDi=a5QELW!Cmb$a`nczrAJKmdLWwu051rgub?Va9!h| zue#f8S*LI>%a662wr|@0aW{=6H+B8)$Y_Lakd9K?SFi{YU@+RQ4-ah%gXY#2B14Swl`lWX^F>XDaT=*eK|wWeE9 zen$Ex$J9V>5$&4Hk2gDZT-&f?!z*PXJn<$=Uee@6+^TEa97`BvZp_6?((OSZ>(I#2 z7-L?ija9bBc*fVtVTX&+%J^1<3j!#{kWpp_5W0Z{Pe2B+h(S4CxIumpi!KfYpv~`) z$BEU6O4>@~v2--u_;8F?x-d_U{K5|+U4d9S}OsUwamO7!i^HJ4&CJf(41!YON5unuR7amma%> zkfFt{AkikqU}C-tQN2f*I8hAY5q|jRl^a*SIlgf8pnm%c?5obN_}AE%zSuv-_S)Ik z?1Mk{f9c@n_QAzKFhlgPwLMaKG179Dv+-L?@XniSaSF(^{8S&8$c>gm;N5j`X{(^;^zxGZFrsY4DV3C8}dm zUg<&!&=KYXF&m*TF5%iF=g5b2qv~5y__e$!Bn94WBiGYNRHnyA8<;g_^ckEi8un;hdX zXiSF3j>BwBL>Wnw04M52*n6xO$rT^J#q<K7dfM1WPadMLkS?Fze$w~RYs;5kn-TrRzNr34peI zk{3!eDfEW#%qIdH;>(8JE%?t{GkmMAJ@wSJn$XivR!o6kDG9kVBY-bI`0X<6p_Z7? z#99xnmq(wN;W1nvkKrC%j7N-zM5EySowM&V&1c@b!Xt$>}ouyk}Ir2rXl3a6o zZhTy9MPu#EM@pJ|o$#Of@yf@)S?!DT_*LVQQ^<6hocQjN{q+0wm)_jjXKqN2ximc4 z{~gnW!PAy11}rLDyc)8VWCXn6MW`ylWGndT)j9*ORHDXv&^ke+HXvEdo4aR_#3E30 z2wa^Q4HnUs?qr&LXv6lg+xIl?hNNw>peONoGRQG6GL^nrm=}pQvZI2%3JVjR(1EjCRhZkq}6LKooLD;HV|?$96_tsZ~`*etTJbap)=^6VISF#ym^6svgK7${oT0@DJ9zro6e7ad1uL+ zq+et*F%$jnGnOD?Os%f?Mm(a9d4UTf)O%o zEOLyzrCTB*Bfb3A1ZyPgyj)x!P7a1Kc8V}FLz5AaBjWYrbey|@QFH7P()$YByVcW| zO>FS$owx1PA>IoAR|1&_WcBQ?&=_-o}yr1_4LBqye#+dEk{On1}NlZr28G@zLod-fPrq!#cSE@wcpW zi7VWO;fl=5n$9ynODHZO>5Oim`Ks zjP%MCBq+%;@Ay}H&yO5){RVBaY@|m9_nZ})lwVSaeS;rVz6Q8q{p#ZF#^73|r@q#u zF_Ms4offsMMEr=w5S>aRlhl%vP|sM-BpdeMJ*qPC&iys>iKyCAWF*s!1RWieDd6FZ zvi8!0jyvDcWmowiHNR$go{N7ig3xy438pQ@Kx|=$w%ywq{K?PT5p8i82`bcb3a^g z?7T~l-{H##)b+?~%aZg;b@7Tm?!B zZqe$zTjX+umsY_WS_H=K#L|Zlupq-~7-NtyI)X53ma+36!4Y=|m6#Pj@e~>QwSy#j zl7QKykiJV#&!SQ9(aT5nQM!Wr_r(1pm&_cvbY!>1Tr3(MZu~EOg?`UvBVn@O0KK~U zDWc+atLSg*cfMG;@yk&M4lx)RA8P|2^97Xw#-KGm2Jbcoqh6ubuMym-PptkZV01Ar zl-tFHXO=N)iv)-+Hina#(?YzSKlfk7XDH+S34L|&xh(qC$4kzQ% zK25^6zJHob0j)jr>DOb=b3S#ijIJDeZRd~%1`&MI@~=Q;YAFA4b_2KBAZt--l`4bM zp!87j3gq=LHpR@^;(ZJuMsuAJ8A~_;?%Y2*WDUZRf(MbZbp&VnE*k+CD&@)k1x&Gu#a26N zWreIYXjE-lEzzLHre%$Xp0Fc%Z%di|*<=C?V)`buZ=eh;A|1O76WW8e0hvF2*<0u~ zxS@O7PVN;~E%Z0~lA^C){B@bea44b6$PL2^vIajD)ooJ$o>3p1N^urPzi=VlF|qt2 zcgwT!-%~59jva-kb{*tEMC^leAfjA?h$LC9lBm@Z!pk?a(<$bjKm|=sV#TE`R;X~W z7Xwp3-)KIE;iN5y4ts=L7G&y(SBc5W*wn3$Kj!-=BO zizQ=9(IO6mRhE-3#JnH~5+;IxQBy`L)(cJ~lbf^>3+gGbl2;i%Hbf;Nz6s^<(xqb@ z|EXEjKZbt9OX-CWdM1RvYckS*jV1ljj5V27j0pAc3<$jLF|G$a)pw@-Gf>OS#Cbcv z`n+po;>wlXDo|Qs-Z--2+oE2+IiZf1yFM17imBN{BvVbvP&`=n7LcTqcmxr1{ zBZ5@^8kIUUG<04lpQy@J%~SEHv8?hmZ1Gl0C7w(scC)Twkc?o5gY=1iKwznGpP1P0 zA>|SR90}o!u2n(yl-o?UNGpF*_(e~z>;ET@pm)dp@Y;96cshLaqghhAlU~hLc?7F3 zC6CdrCc16W!*e4>j`XVh^Y@|Y!Y1hdom4R!?m-yu0C z*!{dW>-iQB9}iExhaPT7UdBtc>dizXw7;FuPREl6xe*4q+-8lGe{*LB4rl4T!x>6? zkmk)XbjP#g6G7$^-u%8FfB$ISt!77+uPVvTy>TTNP$7dt)(@CvP#GCi>S8Uw&O_tj zsrAqTDz!{4)qA;U^6yZI?2NHA7l|?oP0Nt=yL<5mx_N-unP4C}{2i$ES29rb`KzJ* z9#avNDHw;!VB<+^`}udshTGT_4qlpBJA~%D^MvL*^>hX_h>jtsst4ZBET3$&wKx}Y zUhFaP;Ao($XPPz~B>8(u^Dn|9^P3@oKM}kB{u45dX;X$xROp0PLn?9>l zyf0C-2p%lm?QIm#NI}>pbFzq~enASl!(z-klP;BMum&~b0c_qj=w(E) z7W3ke|9xIqw^^GIxyg)ag{GN1nken#=+nnBcgSP!cNG#-93%ISe4Z5Weva22&y#6v zp{vQ}8{g55A2OWn>G;XR3+vQNP_NFHTjj%ht&;0R84VXY;~y}aaU6&cEmD{cqGdb6 z^UdgtQn=>a`zuG~WkyA3RgZaQm-MMD$MxI7($`rR%Z>)qW-|tSwOuIUM zlSN}?zHBBP*QSA0L#`L4F855p9V2&V7zHLmA`5r?*|)|$I&0&Y>iAeyM$Z||j|jtU zbk}pdAAOPj(OTg1gXaR0K*oO8&bpLA{#4*H0`CmB`$$?tLZsgQysxLH&X?y{%9?1_ zfT>CpISDq6`9#I;AK;Sgegk16-U6m*95h~b`4+u$BFf^Cn}ntx8^9$3t%7K!C;r%z-l~${uYw;2ST7-L1 z_@G}=jdZKYg4S7p&>fU-WnLwwR6+EWUVW2p{`Cm`sr5ZF`n$u#XARx6`N=648aFSR zeQv_O`ij0|8v0e#^F4l`b;r@Q#5c8QWNk@t)nKNz zK&}*qLRvy!H~3RP>!E%Yi=bVr)cCD++8>;ja5s!@#TXDqLNRvg#p#_P6ozi5zZ|{v z;})Vl^8OF>+lZ>1MbAwf(r;05Lyw%Uy?W$i_vFT&pzmz>-@i_fgiTl9O0UiSde4Z3 z6ZcuVR`kv8+6##zLMOb1zz>`*K@eMNRFt4w4b*MEk2*0_!YP6~HTJ*YE?q0_jJ(dT z|BlEXPwra!{oLc*YY%PcLkoxW=rL?qkJ6!}$^GhYNImo1`Cas*bkx9Ti$;zp zE*U(y#Pyr4;z8`%BqqBiHZ;^P`5`EVHAQ6ePJ@EW{D3&TPFS{d0$*&+?4pSWF@8I` zzG(eRO{0geE2kfKO^ofb$s)1|~F=@nTga|FBjtIP4 zJ4)9=_pm(hj(1ZwJd~Xa9?5p^yHTPXLOb@++w_f>NuM{!(8rbKM7x*BN%~9lcva)x zvCHO8+TZZh-F=ORM=qZ;@o?SBo;; zU-9vd@yjl6p7B`y!BOL%{Ob8}GiiQVZnx5s+^!X6x%T3c+-`lqyOu+z%90)xPhy^= zH?nm`NhV9?N|s30NVZG%NnVhgm%J~TXitCf(5oj7ooIZd-mtv6^@-*uk~3msBRxxM z`j=dMX8pT+w?5j~7^cauDqFubzXbmY1|cVzon}PHh)N>ar_G6-2jJG|#IGx=mHGT-P<}gO+Wq<;9<$AGe}w7H_g+8nywhpy z%w*v7xX-OSz2-Z;?)-VUPVar5-@V2*c=_~2VFCRsw=VRk*fjQuyn!pHEeh0DjXJ(U zd6vq1)a0g=RArFay{dCliibF6_Nwk?E2&B)kFp0v!*WPdX-$r;u-fKW%062(G@ZS(h$IwoBFScLP{D(BzAWBmJ; zFL)$ty2UVa$copsW=s9f;pKf7Jd!>-Ts?Qhw$}x7%F}OBBQbhJQjmRvWKcZ{F+>!WQmzRC_+pxsMFmp_d+4Y-j z{_BIK>_J4d^Aq?@6J4J`%*ZU^AbA2dQy+=u7&=oTssm-s0blCqc7HzU5}g$03iDRKnMdq~RYarq9!%KPHx?uPEyqe1bj zB)g&A28KK`HEgQwi6v=EN;Yljv1RI#EnAjM<(0#RD^N!5oy2z_-6V>^81FC*(De`Q zP$S~#5Dme+{bC>;f>Ue{eaQcR{^Ucy{{Q{qLnjh0^%@by6YpW;cJ-_`3Ao%mhBS~d z4|zD_ArCENmpg9-L%m|Trd(5QIJovu-x4*o< z`QUr{+=K6hQ4hZVzrN3`VCA$z{<3TcY&dF(*{)IU@=z&|41xdT9>Ok^c)N};0@1|E z3>-{TarRpy2ycY8!pmPCRa0?SQBgOF_8e7LA^cfUGfFmuMw0n-KDqqopX4%r&!>?R zbW44kR(M2UE~Y)Rn$CgHT~S#O*7-z9Z+n!#Dn8t>OK;Lg#_Wo=M2Bd1`2_pK>!W>q zqV@3t@8=cg$?b9~b|^Xs^NUEMEMkZ`$?pHdWGYss-W4*%Aa$3h>HHc=+9oM}pdRu< zw)JKG%ho#Uas6>C?J=@$ByFcjdh*_@G+9sHG8Vb z`2X$K$$KFCVK#^JGcYyQu>pEo204*He>?j0C&CSGaIZdd0;TO+UOcy%FBd5`mTeaO%`=vlAj38<-vs+JYgL=V4@rR_*83<6k1GA!#Hmn@j!e z^2(2IXMHo1{F}~jD)R4hnPkVW^sBq`9m8abU#M}JQ=1nKNYT>DIkT=!sZ#6J(zTfR zo;L5EnQ8J+TrxqCpD*_8X!>sds6B`@Ug}ilXZ=Q`m%gXJ zpsnNc!g9L)1E$r#Lz9KEkf1HlUR1sTGKrw!SDOv1VOc;zvok~jd573r$bVw89Wy!` z;3b7-#e@!{!N-?L)K>3-FIG-#su4pfz@62f(SL7kUpflV?0^*r8C>8Oh}e+$`pX0#eqBVM zVV#fYJaB@8Faj4iPIw?mi2?5-G%OQXG=y0bvo~gsoz%TJH>YUwdrz)vO`bk&aGfo4 zfZf9dyu~Fl$1|+@AUN-8Iu*Y>53Sx4tT6X!?le<^2|aG{rBRVdqZARnI(N zC!Iy%pb|!4YjV7gU`Y%L5^RaQxiw1gZB^+cf@m;+Z9?=nYhf+6!Bv~WjP~dk3cH9H z_`p0IuI{nGr5U^EbniJccOe0a?S|mqg0=1t{cm;?JvE>|vi-f4wSKOqb;2Ak8D`(RQ|7~78f3o{{G1>PP6@{OiH zIvUw5Yza+rHk3r?-$z{xNaHFo5I^OeaIh3~C}Cbla<0L+NWn z94O>&*|5_T{C#-TqZwV#7Tato=CCU^8k-w$B(2PbN)?Vj$pPAz98ec9Zi9w59;^~r zB&!-{(yu~SCT}#Y3-ES%7;P+!F3T0X0)}Q4*(2B*PPtRA&gJgCL_`gdO__Z5;wRM; z=+85sdr|oaDIDX~uYBib-lv`vj`phP`%LQs6j^(p3m&?`%z90bRT2=B}8X z*^dNl*B$`1Rzc>)fmvsc}SXYrZ?t^oW_Idtx?&pspBz(pq~kwbw2PKg}N9qcD>0{fnuBhJ~A+-%}*T{pkJ#6 zensmn%NK(DqhXn54_g6_Dzn&v?}3`{!w-X~qX zyF7pF`{!o#ZQfsV0BrcOLgR#8i>5AIe^Q1Dgdf&b37u$(`-L(lxJ` z`~b%=S}(9JNkJkUYeYEOywzM=fD(A?1cxh#lliy-h3J_F9L}f{>*2NM_q_aMv%Z49 z`Yio1g|ADYKbcK;iSYn^>%HIGssdhnXf5JA9TnW0$>9t5ScB|Agr5YEp%yL5y1^R8u%-RU_pJ27>j|BBhkc|3Yk z(cA6qNtU6;8?4squ#WHen^>7Rx~Hs7u2#FE=ETvRv3P79_Xd}7N%T{n0rbaYzAl;m zROwNlmYI^!&yOg&_am#WUZtZV14ad3(`zt#B2G;{V2_Ykj_A}p(t&iWIIHp|%pR>!o zaqAU&ny#bsmh9|(a2Mwj_(^c2$-j1TPO)?Yb9dYw*?9D`PogS%52~3D$auJUzQ(%I zHR%O#p28!cp(-iBvcm_d^;Y|8*0P3jEY8SXcty(W3Sh8eJducR2AV;yF`2>aMZl)z z_WZg2^^5fl4$YUMpX53GJG9!-{|KG;!bUPB;FFM$+>v9umBJy*oF<<~uBxWP&sT{M z8PFk)?XyARXZOwR^eUCoC+*@OY|x@y;*XZ8T$f`?AmrxE6+^r-9N2zGJRf| zMZ#Wn6Zoy}>0KlLG?Ad-3KSXJ#W@Hqm)%D)9Tc?a9zSG=v@NE7gmRq4qS7i>f9pxggUTwb$EW?*A zUw}2iFN^x+yjt1nrC&w71i{OB-H0*U&}0yz36s7v$Oeg^;`tRR0b(@n7^!OVF#6l{ zw?5OQ(oy2s9iQwqWa5O+hb&}~KwNN4%KlB3$v4>ozs)q|7AD2GZxm#`OMeqr3JCOS zm7>j4+XiA#!SM)J(j#unpk=+NLYVmFQA`G2;K73yVkFT=(ZAWr45Fgc zj2Rpc4=`w3SiwQuL2h<%pC6c9QG9NOzzBp1w<1??o;_|nV+x#h-3yhI8}3w#Y=Mk{ z@AEe@`VSCEpS(!0hog?t3rF`q%f~voLtJH9PKk>>FcvX1t88TMr4I&<9#%IW5Q9g^ zUI*<&N@ATnA|k@cBfLTa4PX*jg^NqDbiDg~f|(xyGP{mMQfB0gACXr$*_a95LHU!@ zR*=Xe$qYEe@sJ8v72i!&S6c~>GS%LmoQ9;jw;8xeDv-v=+0aS25ECacMtbHvagD;|<6bSXcuEov_T>a(@ALsl`pj9eVBzo2ymQ(?EQuN)TY?Y06^b_A z)q47AVz#$XRv%p)ojtUq=FHroo9k4Wi6kL0F<)I=Fl<7&wX~?HA)v}MDy`dqlJZyP zH@`Kx?CuUrK_8)?(NbI_)FfwG^?B+D=Ie7;K+?mWnZ$JP1Rqb!!9ZQS@`$$&my7*?DWG>|0)j6A&dkq#;=D(iJBfwVBG*7lEuk9GzGl;`JnDu2ZNqDiw5^Fym1 z@pD7cwDgs2_3y7W0o7#U&<4Ci4#JJJ@ zQiGE6BfAVK%`zA>ONVAf<|m=5{r`Idsyt^cqtA zo(Tb&EZ=ovrb@Bi9IRCtGc{R!Z2Ann+=u;` z)1>&3r)BuCADfTGM@q(^jqW!5uYulm{w7j-m+x3gG@lGuH-P4|e=h&Ll>U4fugF>U zk9Yf}rQ|HDdx@H^vax_AjK!t+ZC0ry@|HlIPOAhZ<+3h%&{f&BIM4xsP08(5hfLVmFScUWoUf9ON?<5}5Bh>L_>fEX!RcQH9NQp>rDYpm%b$M+W7&a*5ysHhmc=dBv z%Uge^ziuVICqJi}$k(%8FMBa0WJJY`C8HY2_&>gUfrPLA<1>5H0k}I`xv7u0_8HS~ zc+<3LSpP{xO@+JHZ)nwd=sZ+@TE2yqnCi5CXJQDV%&=l;FJM+86u^LxEiOBlo(f?L zz5r|lS-#2qHlLo_5zOyrt6uyR77RR$Y1#__-sHX)ZHcU|?~9;;0494#TRAoUlPFvC zIz|I*@l3N5i2wpUl3<*UG6;9L3p#CoIzJ?{eW%Sy1iqw5pZGNW<8|le-=epFVB5d- z(1_7j+nZc_4(pIiIu&b4^O*f3J%ag_*`Axy#jt&* zsJSw;#2x@;lL=7g$zR8@pD2Dr4qhz>SAFJOd|c*|N5)FR^J!o4HG zv?rHJ%X$!)P3TZrWasu|ItI>f-*PZKh)w6XivX4P>21fZRSUW=h;_~2rglFGqDAD0 z4Q=(kN9*j&F~0T?N`DxgH-XOYRzHl$9jEE-do&)3lm0kxZIZ-+>-Z?ltumM&g0<1L zUOGS5DHB6PMM`(g4g!~RqE|b@W)o!-@yO}00R%hYq6B`u1O8JDXf3LkPTO^ggwhn_ z@+r%9TaV-PCG8_dG9<8Sq%|xiU5#@{zY6O)jNU#=pV`0ui`%2}C(he;u>B}s@eS(i zw)d_bYRkwdVW+Y$=<);X09nbb&3EPjo_i;fgL zGo(A=6=;QS-mXdz0*z`B9UaHXU_b2YECPpYiFcBy@LRl*iw} zjB3<@^yFG0+&XDaWWj%M8Y(Jd?auIMh&?Pqn$(b@O0HX#+`FRJxJFAIDH@%$=IX9bZ_1Prx3<$$fV`eo z2h9lSTmAT6@;>$Z^xF9Uz7^iP_wx=p_HQOAZlaXc3KX+&4Xr+c+Rt0?3<_6nMg{6{ zS8&vo>&({=WQqVeW27R}G#OR|r5PhkET0JCmq0Z4(xB3%=U=3||9gbqSo7ZLfutyW z3aKSu*(axEHy+MSgIMpE&rpaR9RSLCxtK_W$K`%Bm z4fbSob>TG@`hX}1ro0mik;NPX6w6 z41mQUV^`#>=rMlJPAUq)_Xu2v?QkCa6?tR;i34|?J+oyf{i%BJ#Ey-7-=6mGrI#-j zcWrKX;%LyF#>s0^(@R#N{$Mu}2~N9{emHl{g>|Qg^)K7MX5{w4j|_Tg!K9{xn;pN{ z%L5}5fdt%x(k}qH$QeC6RJvBfy<5=58UKCWsnAb=Cqm1CJm=t zGWl`Rk^waXM+VT>vq|`kPk(%2>zp-f=yzv2=;sP@FmXWdsdasa-Wpd`IH2F4kKa1@ z^z!o|g7%p?OFo?T^1i54hMQ@)9az67*9{7hQO`qKa@shZH>k7JLuWY!)x&Ufxp+uQ ztE~Z~DDWO)8g6BBxjTXZ804hsbDVgoUP8Vka!9V2Z!G3}4BX5JD$x;NiC%9oN<8tO zw?UA%c)M;SR}cV`;o0GJmt4*;aS~C9*H|n%BDK?qH$H1_Sh^o6yLm{h`f%H?kCW~6 z-2$PWZ=KPPesf?_)7~9O7`i;`+E%jW>s~}d{|6XQlT!L5cF2I+L9V?gFo;?Z69t*k z#U&%Lmyn4cV^ZKYCIL1#%wH41?&EvX@R%ltANT#T%t=j8?_>8b6Nb@cuj7iyImB+# z?sY09N^gS>%e*g)fD$M3I-}0UMU5cKL#E^F%qAVc@CszKsFxx8U(` z%cEvVDw8-Oyo1cXl2(&8#hpUtDOE#qd`7?sVZ8HOR!@uN4NIm))yWm z6sA1sAi+&?(hAe#I@8La;oufOGhDIr;i4Ak?GN+>0TgIKEqxEC(jPaQ8UYk|7#IlP1rM-ql*DE-Ey-^UUP7e%ZaPkGo4eZ0%DEl2lLpjOPrT34?NjEwH0Jr;PrUGcgHn- zb^qsn^2vYz34|m-0wH09y&-@K0YyatmE}amE$&(OYTa85&T6%`j=HVY+PbRNR;yjw z*4DOm*VfV6_GxR)<$KQkBq2EZJikAF53i>JA^F^U&$;ij&)Eeh7bJ=hrP=gavYJzK z0di%1aHrrt!7xXL3zi23gw@NNz_14O0+wEtnu1wXU?4gD^T^Z|R%&Y^cy0n996FzM zzJJ=ryGMR*eEQzH5u4+(xD%NUn}HtVJ{dUcc)#g==1_9sJK{a%=a1HWKdp7%eL6=> z<_tbPudb#B*W7G251b4143U_Hdk5M!876_b z?tzXC&yF;uqobLnp`fUSynk@}kw6_*Og!cLRF^jn0ZzyNIP1N$yXbpw)9>h;YVpe4 z!h++p#UN`%2ju?2W-_bQsfBNU=-Afc%?-0Z9DI6ryQ1>6)}i!rs94@E9rV}&#Hn@s zi)6dB1s?}gG57UdI^j$ZZVexe0ADYp=bGv>U!JSA%Z}R83 zjZ$AYFQ1p81`}>c@}(MhHl*uu8~^&^xYU;(C186J(GK{_52UY){Gb;%^oqe5YHDb_ z&RNsZeGJI8#4hT$i!ASyBal@K0|qVH(Rb9`r$-DKAek1Em>(XOP<3Enk2e>0 z9NT;J+`%wNl8EN;Tg3~ci(s0O-^&sL>1?n*km&FbRvb>acjysLqIUSI$rY)Ne%rk} zS&n>%Q;O1XqPPUIE+8hj2PTk1w`!3YeF{cB50PL|NJFSbW0$GGhy}!FE}VcIY!(KE zp6O^y;HsStM6e~`TXf+uh2=|uqF-Mga{k-T~RftHGWDT z5g%;#R)yQ$6)!osJZNkXfiVqM&yWUvL%@r`#?vri;L@+HS=_ID`xm>=-68(@R6) z+*RQ|f?Z zVJ?#8yW9j1lMGs_nIKky%;fS;K89fQ_v@*S?_Kn&* zBQLbSKq|n|NE@u(M8$AZdU58Qv>RL65q!G9kNV4HP(aMR<4KzCG|l2^*$cIY9- z)qUKY;MUJee-LqZUuQPhk#lvxgwp4p4KI9sty0{#|DJo1XXxqwD8o5o75npD?=HRc zv1CoE-Tc(+!JYHFm8KUfgXc_o>#DhJ!SS6BhVXM+Ur$e&(Rc7m+lzmA;ZQfSzl*J7 zDf0$Gm6c>Q&_V@q6VT0rf>hpG0s|2n#44;i1joxl~yxZ;&V zNsA%pGtNdA(GMVbId2~+`LVEe!ruP&QA+{Vpnx*)=F9X5y+j&LlgLdsYfetw{l;~m z;y$=RGvVn$nEMc<=cF()*e-=AIlCwf-r$nB(2X6CI}i@Bk^FkT^Sixg%n6-N&p-e? zV?uA$MS4nd%h74b#6?f%Jnh)ewJ(nxTCt+!K`J~AD8*$%3|Rsdj6^BMR(p)$AVnMC zxtg?sitFD=SQ-G`$H2D2`ec=`z7&xCfd+B7G)3=k57+9U$~dlRorrgMg&6C)7wf(= zXd5@X*BIJx0<`BQEZ*#n4~A`d-f{o9$L#EAkrFRF`NmP{y79pyF1z>2dR|B}!Tl8g z{uk6!?JBKWu|_WAc{!vl$d%A81Om~?uxzGZq2EKDA&RmwUxaE9Jm(fe($?88zQPkf=_ui;CzkO;Vy+_~tj_dTn z{;qYWR&<()$OyFF3uhUOv{or(c4$kgR|ufUOc-{2E}(%-6YRd>M#3VJ_nm-&a6a^P zdU|~m0{-)X0Dt70`?1_whJI6XK&rBA3&|~*ZU|+OfQGq%%~K_}f$WihhAK`E^V3x! z`Vf)X9;o%h43yj8B!u1r80Ci5z){FB3W|yeHo0)FCcp|lDGMwVc%O^-s^W6Ll?&Tg z{Po!0qW5!yx9$7t&F9HKAOEyq<}t}_`=sUNg=3fZ?YyP^=WX*wkFC0VqJfOvKg@A* z*-*!Y-JhV=pn@pvGC+_pxPcIHHE4Y8DucEO$}oQLsOV}2Wz7ZGegxzjj~81HPTb{V zn+YvA8Js3%kTgORBMIe%#;zh}MFS@Z@=;ps5-rGlfE#F)gK%$t@0#*v!6`5KJ@xa8p7$)!XEMo~D)89*l3O<)baCA* zkfmG;#|eSS#P34&!9i-|dIFO8V81-2$nIkhkVMkt?~kD0t?b&vc$L`RO_+UQ!&~&kon%1gJB1AfD`|5?Lgz}We?J-HNHyH02(c9z;zv9z^~gQ{s@X>k>1x+xsb2j zx1t$psC^~kn@ty^2`2PU<)eoA4&25(Cbb|&80Mu32;h`!0 zumO=#rXzzR7X6T*Y{INC*6S@@yf)SG*3p*+{q*ttxgFXs&7p_#iQFcWzFZJ9^9EX`Pn0Z`)IwXxH#s>7wUbbGU#Z6stG6ym_B1=tF#cjx>_ywQ+^S>mzb1a zN{*yD?ofNDu79;kNQS`G;N45MB&CoZE&8TkFlU8^hTZ(8dU@fAq;y?)OVWv$-Wzqb zWiJ7qY)jdsu`vSg*x0qI_teAhbSXw-YG^4tQ=gvW^`Z=Iu0MJnhUD`l?CxrO;1c>dCsA&4L(50nM9{BR}_kOs!ohZL3Dm$`*hNFTm*joHvw6#Q#HX_hiqJz7L`j1~wgI=!{ z5niDTaB9Z@CWt0XH5P6H-bAN53{nc##hr7>qA4VAns6WA11a@1!myx?PtD<4HX+F0 z(Kp$X!RiC+3B01Ho5uyp>`7XEEZ~629_TXjgq&A5gQ202Wrd`5x02}To<_9y+=<_4@*l>#W3-@0HQ8Lj!ggC82LuOEGmh&KpE>xr~=zrB6qu7t$%-MMLH zHN#&Wv}@Cp%+LqBNligz`N^|;NvoH@c%6Eyam==ju@MA8}t^9kBL`HBzm<-q}Rr*g?~^@LajO( z0(wF!vxLRAO$Zr+TM&FTECDr;mw;2%=@W$4q*C(t)%$7^qpYhN{>HH-bO*7_`tWUf zj(*aIUgS=dRQ9;sqTYf4ZTdtSqs3pq4la&ovC(Gr;je(UmQq-Ph7q;uYG;@Oy6vI%FEJG2Xj0v_|71}iHqy!ajLfj5m z&Kbdf*wAdI@cuVvlQe)W+0(hyY^(px5hZ@2!u(_p6~i>I(XiW0$fwX{>f=WJ|5rx%l>vg-k0#?T|FM{gdOdH9c5#NNTP-` z7(}vUZ;QV&BFLWRt>qddOff^^37pAXUd+|zvM@nCYjzQv)QyKXE>+Ph^cB=I-1e}C z4kF(EME;bB?<;S*jb%^eJ7NATDwzpDfvzvGm z?jK8R5PW+78_E7BugU*P%KyQm^55zEUtBG4E{h-|Ych)xfd($p*6X~z{dD4{>;()B z0k#Up5@;MOYk@VaV&ygBF%w@IxMbD~pXQM2QaYTzy`SE;@7Y9eo9DV@;Sut447Z(r3}*4hd>q)YigZ;8!|Xusukq%qu2u<63eB@tWg2KZ>n*LvZKH<*wY+rLIQDV{w>s=r=gP5HK7#_N87+XTJ3Qa`MqSB7Q+P z5YK#M>@P?5)2}uYg-`W{+TjxpuNpZ6>97Di+8?mkrvDKyC1zF$XYwy6^4Qa0DJ73R z2bNJGJW2W{JPD@h*!*tS_H(TE3Pa&}TT z!6C3?AmCVs;p|}N{_-ZhzUCvc5PF}snZk+i9L~+6znwmJkKQ=->M|lZK*^%Zj&tk; zh)lecUZix#UeIlJ0Nt}C>xoj7%ny~UKgGe+Tag%^n~A3chKfW3Yf}TiLhLxOmebez zh`fC`_=0AxayTeZcOkb4{v)*ab+%8(Ovo%2&;u(8vTi+2OFU@EvUl(Kt|INMcwoNE z=&NhohxJ3joim+UaYv{F4y>YuV<1`UaagdT1wgm;>;{=dP@QC`l`7?OUQ?@7i-|CM z{}$B9e1L@SkcAC@1eJp1LLGupxQwV^&$m0gZjJx!0j8@=cjtmAJ>Wsibh z`!?kFr)qMmWq7ML2}zEX;;V;VgQ2;=-E^De2gyNLQzB$-`C0&0wBajd`dSe-kh=nT zlY*-g9TV7Eq^S!cCh?;z#qn)YxNy!Se-r@xhD|Taifz~j@hTa11N$KEX-JM*npKdR z>!1@)jemC0#M2|6rQ24`2oF;TeGu)}pbz4)>vZ<0$kOE6kZ%IG9;-;;hUZ@0K!07o z^<~7s)xcX-aBe|Z8|?*ImA+0a05t%a30SF_9^AA2 z;20Bp_H9JgB>0402<>5S7unuG&Wh^^WN^wf;sBwIADXN=XK{~!t}?tRSh^z-Hj7u; zB<%x`ayB@Je*V{&v@wCS2piP(XvW*5?KDD3-@hl&dv}TC%SHAcwH5uR{w;pqaSrwf zIbi$^_Dqy1n1!iyW<$c0m>7pbp(ya!VWbA1hzCrrF$qgjr3$bcf4W2eFg%APMC6Ai z*-9Ps8sR{;azA1YCd<{8M8T6lcR?=GKI`Qr@`h|?&9hAxkZq5p81NB*3t+ek=}Hk| zsLr_cfqGv~smbnM>2-&DYB&Ap%|iMP*|}hAX*Io6Gq-(J zDe0*B3cpoh8K5BH9p;a9tV^r+c>c-x+XwHSeBN|1WK3T3^Q6fObp z8-N3(kRdO*5EJ|;PSgZcG7%q=n{mDyDe5YqymlDc6v9lqr^9k&U)h$Wu@WRG$N@y&9LJj&Hpgr#=22k| zJODn#zvckL@!XW#^mhpr(Eg9YgcmY7~oC_S_8QFAi+k288)n( zgSl0Kxd8GR$$#JdEJR^H_!3fv{l56nR{ZXu&410`zH!0UR;2A*sNrf)N{QJ)mc3t2 zFQw)#d$8`vsa{0qSPr+;C6(0zpUXA%Qn6Z1^w3m@AcL`cDTrhjcX`NUA!C6V8sc-^ zNV~^L?c^P+$3IIVTU22SJgiu2w)P zrb$7@ph|#ZxOlvYAr-5+X+kTmiVOn{|IgcI&Nvuw`MWXz{=I#McI;pWRgT_x?e(oR z)^cbm;~d{&1EFiDZT>9Jne)Kcw3(Ym|h39<^&+`WP0l7H7 zFe#Up$;93PK3pvp-ZCeZFop@H6q^V<4)ZN^ochYqbV-C`O(R`386v8qc|z~@M|1A48u28^8M(Jblz!8{r8d5DWBCDtRoTY_6}ml~tF9;aQ!)xs+6=l7U5(O-jZJ z&`@1kM$cM7#~3`zdFRoxU>UQDdb$592`7=mmq*5|Yb*zNq`<2S#qO9e>!dS+eqYjd zOwGn|n|90gSZTS&tGsmSF-s+ucsahQYO`?-z27@ilh^u=NX$e(@#5-l#tjh59WVJ z$I^Qzj+35gmYLtLurDVwXU+fBewVI1Uw|j;@*f1E6p^g*4OGGxo88i6nxN!&9V^Sq zaKbIub*Rg0fV$I|Gw+m8t}m&*eK zd<1@k40?2qfbP=t5U7_!9hy1LNd{?~FZUfkY|;9tHl%G)!osT?hSOuCp4$PXr1Z4{5s76wugr-=PxSC9VawGRT@!k4A{QpSXUAHs`ZxNr%q0sd24ZD1$dH zc>Qg$H-gW&3o~AMN&LNlJ&wOS+0txzkf}vP2ACT7E5wRS=r`Az6k_NbqSs=U7IU&S zQOT8n4-yiVg8^SqNnz!%s_Ev+lB#}5i6eSgNTwpB+XwXSA7B0wA4N_iCATgrD~#z7 zlK=FG0h7XeW_7ndee}(bkL*dAl7W^8i->^lFHmHLShz|9y(~xr&vS+~fl{bzhDD^K zPymM?5)=4R2yr;g#sEkXYi7oR(f^-P5)(>%Ixbwfk={M@;jO73u9TNfZe3B-aY|7o zKbeeMM7P9V-Ef4yyW#tbFxKKl!-IF~UajjsWaMju!1M>?xdkym1;mxi5Ca4+gd)N& z3J#XU*#iv5H4%v1?sWe~TR_p!80sc4s-_1-=$^pf>zQ4!ap$&$)&&{auT3~audV&+?8_wH&ZW0mHZ=)~ z()JIk8Zh+b+HQStwbQ9lrh?VRiL9b*n<2(xjIxX3?J&(=q?P+aIj+CdY)B2Vdqe)4 z%e9XqUa*K0y#tV_1uPitOsEw$@s8Re6 zqX-~auv#Yb4zsHbVn{Z18S+gYF|6ow`Z%yAgfS=@O{l(PapwvPT9*6MLrM2;T=*<- zK`hvW*MClkB*EsTOJi1faeH!YRmC42JM=8n^26zN42+S{lj3(E~xt9o5KB6obTA+Dm zG24!88ardr^k-71OOeOCAOJ0I6$zoK1odneeK?Ma!_F z)sIK#Vr~znjL?s?W+{1iBr*p2jQx{Bh^$>n3FR_CNSae{Gq7}Udq{vnBmVJyDT zoX2Pn!|pdwAB{l|g#0KJlu&}qq!-%+i@n1Jut%G$`RXO&Vf~Mf>EbP{6UQT*9KZav zUkPX5_#o50=yjtmj{LqVEla=*oRHA3-_O@~(+^kOYg#U1DWcgl;10-}c|{Eg3uyVG zZj_p$bJ}gfA}qoh@%(g$bMsci;IF%cU$g%DkU_^MtcVN^?)vH4mxyumooid^`|A&m ze|y;X*S2(DAMeS577@%!)-n#1N64WywpMn;`Nx;@tfjRk`iY@1tE|5f|IHpSzUs9-&7leb>M#jkJ+$|bKK%#O z)m%M%jBZ(e@cVzdR5v_7F|(j_(+2$SwSALTkIiU;ESEI<6tZLSwt>#7@exJY)sPVH zqYbf(UDxa~!zyR7mQ3sfDS=6|EO?h>&4n6K>WKQ=n^*MX(&*LSKD@P_$X{CCTOG)) z?bOpJ*UhE;kP9E~KGE_i$2UL!{r$z4Ny@V&UAhM>s_FD#tS6UpqJe-3ez3}D$Pj{Q zY}z1;-Kh1oOQl{(_8^s)NbT$!#>_Dm9tB7Mk_c+Oj%A!dY8Tuwr;pMlF4O_)=F+$- zuY240s_>W&xwCXgJyR7zug;vE*|DUbDHT=ha!_Y(A@Qs3luK4 zAIuFVUGHD<+y@c01^sV(9cv`YLS(|_^I$6k0!x-Z zJ8KUv(j9A=J^QDv6Ly*T)-OG^=M7+)GZQ-Xj{r_7%I)`*DJ;1A*_jte>V~=+H(Pu{ zytX4-wC?!jq4p~i5CuR#g(2Mi3Bw7;1 z0Vzs9yO^b;BG4u$=hT2r4AX*Grv))|9dS!AX8TDa*ve6gfEWRB0+*ES&|(GCP~vmF zjt2cr{{d0vZ+>gctg!ki6MfaacMj;YxKwgYnwi%Oz{;Az6JWODxZ>8i0Ri+H{p~+DLL|2ywCR^Mpy#}4N#*6KzqkF~H!H@}v82^a zO5gjcbP}Q$0Z#Z^GDg%w)E0drex}5hyhXoB1j89yXj)ig_6$QoI}5bWM_@oB=C;tT z%@u%#SO8~n{s1THqCGMI-aX)CnHK%5pp^+xYT`t4R3vYe6@(soZS_yfR*tL9gOL!i zrnV7XQhKhbemgn)^s>s?#pOFMe@my{zeKNWTsMmwGcqnQ-5SkR_M5+H=$3=4V1&vB zqREZ3B!tAJ`W^BPE}7N#aCiOC%*oH$#@Hs8m(T-m-lVhMSwZCccah;!iC<_(Q({V7 z7&s(}s0}qrw*Zo~hR*dNF>4K}{^r&Of3w-&(3*$Lz*Yudtvxf@sXse=DquDiHj{}G z?k*^oPO*ezEC3uaY0{~F>YUsU6^WPy=+;kNw?-UlesAL3(9zmBYwPN$MpJ5hOr9b3 z#fdZL#U{LwZ43)f4bJL4vU-26qyXyCkA&3?r9qV5ONb1GOFnxhxmiZQK(sfDJVdL1qjP`WMH4CS!j9H4Zj&5&z1 zBq|zwv{61e1|J_ojyQq`TB~h#OGNWMgVg{A1MXVTsM$_E72AiEF6d9ga#@DG+J=C zYXg+xAl@Eo2*NApBs7!?gL2|QYpdE>Sj8+2omyszN*6{9pb}5K(UhnYJGJ+?|GY7) zbL9t}2{ew_6+{1i3(XCr+fnj|0hRYNmkP<;$}d0p`^53fOmzoL1}%z7wscsbE;S`3 zKFO|5QW(H{Ymmhof=qUha?Ol6kRvVy3eMP5gVLzPs5v1&dPutF7G3<u(N?F-dHL3Uq*TyQe5z-K-tdAP0;cx@gw-GsYjC4c8HEv{A;lKfxrFhBi{ zNf0>j>Ned@y;mu|wrbMms`e!PpIyfxlQRZG+9cA~r6)K;G!nB`(kV zO8L_z1A08QzK{5N$F`?F?%ieIi9LPiI~qT~eeL9nBy|07yMK*2KYMs>OT&cfUNMmm zF80|`Q{MBP^__abPF0QXK-VHpWE5Ed&9yR}T_J53zC4^L!WH1%H)tZ;0rElo1M+JS z%$YBMDSB{YCGOH+RFs_jgBc!K2y@6x+^zY~{z>mA@$L8as^30u*^dKzP8hP=SU^vG zm-c7quO0K-`AfN3BNiRYyxM#42S-=aUskP}aIEk4a}D%7pL6>%o;mkvVGC?jMRj=D=G^5`$9j>g4&+(Ok-L_f1^eR{etWG=Wy^h zcHF&n@ygL)Sr-+R1qal&-IbQ1k16io)~Po&{4~?0=YI?uv=%D9AVWP+5oQli!2xSg z$rn-!V7(Yd1)1mKWv7M@{u4Mt6c7l2;)X(^9&H#UX!dA;PVOBfqchw}G5_4e9`+@t zdOqX$71eq)K1;^6c~Iq{3UeYGNbcFd)gYW9J1{T-!tQ=LGkl4o3{thh?uF|DR(3{s zaAE^sxSEM&HxoxWDeID7z_vPYsEebaHww7kv>MxI7y2v-6(;E z)&9`VKK{HlYY_dM-ueU8S}r)RAgx7bTWfE1YdyL^tFwwG)`XTP%$cxqyX7W$Asu&G zcbea`Hfc!I)S{j(YhubX2W)xcv!lB+7o~GU!&}65k3~*HTTKrq;}7>3e36_Fggyem zo(x_Kx$W!#n3cv%N)`Y?HOpm>HD@){4aY(@(p)-i)C|Glp&@U$84b!?Z;?{^LGq=Q zf}f-PV7khK%SdAjkV-kAHFN;qS5OLP7Zqg5YzguZf3vr?WjjN-0<0USSi(U@=#0^U z(htmTA=niT_#IALPzH5sWHC{V1IvYR&ke{8R_#j!l>A}^HeeBAiaS|!m8HR%-fVUiTE+kc(-lE!A4kNjn|FS}TXc1Nra>3l6JGAJ zykh1O(tdG9aqo4NHRXU*XxZHd%dVBkW{c5vO74@)C9h3Ub;|CO&1J96>6FqZg&UPa zpmaYcB~mPlwTEeC3=xDjTxc@Y0HZQA%djMI475BHje}$YlZ-J0*ki8P4RT5Zzz`EXVt>Q1ab2q;lEU6KMyJP$?|P?L zy5u)M1$vCWQ%}5hPhGI&_AFoN(pMJD?9(rteo(j6nmUGC6qghqd8IZiI>g+&aC%0I zknBN451$9vZD~YH-uQdUxW4c2j_uOPdcj_pmX*#0wmi_G?YD?pr+^zyz~wz1HAfKzw(31|=I`$OW&*ct`r-lQW0rR&;qApK_UQ}%oc81S8K=95V+`~! zjjmNIW5^$=`^Hp`SU;-&6woD~18iLm_Ps@vWYbwpKAZHudOww2tB0>ZiQQxf4g|6> zhXkkrEFK_O^=R1OGTGrm7Es6_@Cz~wv;wF3B`i`{EixDc)C4Ayd7dmP z2r5Z4$0w-k%mR5Pb=b2D!wLo;tS92%zr33mLGStn_9!i_C~vcDQ(I^>GjF-u{f_E8 zGd|iBni8U-@^{QR|Ix8sNt0uH_~&R_7jr5+Wv>L7Qm^H!L)HQO~Zc#sD_4LlBMa0UcLkPeL zioNs8X>dlGoJ|xMlY!30t_>2C+Zj5QPMP|}s&iK)8qx*AhCwWNXtwGCin6j5cs20Py`m=zS(@u^q8U2u0(pBc$v(wHRwZec=8d>?Ko%x*1*8Lp0HFuJw6 z6U=ZmglX?z$7!wYW_O4v(|AK?`~?%UM$c;T`$e4G8WyoK(K{wOP=OuuLn}xN9O8<@ zTycgg8|I1}eg^KN98e<`b3RPav{DxsDDk)JRFMr5=3hhZMhy**0(BC>iIBz23Xqq~ z=tQaLtdhoETEw$e^hbK}cJ0ai+t$ySVWNi;93P*%@!I!qOit_2zRzG;RR_zpTj#dV zII*I2{({oUOU@s8eaCZO4eVA@n%%D3;J%T`Al=lkvc0gfIJDIK?M8JZbQuY@M;d&D zs!^w=!Bj_+8yuLDD?%KT>YR8X{EB&`vaH_|o4Ks2cbzY>YUr{$`;C|elj;<+di`H#={7vt4x&BSs(CTSJBa<^aSZ>k>?|l_AEeoVkD_9{; z#>U7j_}4{}2)iOg1Cd!3L}rD<1C~N2VtRwq{eo!VlqsMYMF=exGA+%W?BY>Pky#Rm zky(28K)A7aWHtf=v(GPb24;z6?bl~srdOSTSyJK=m?e!TVXcE;t=QGbKf-J_80|hr z$SOA&0zjXM@j#@f^T^Lcc0zCwR`p^_-_mR@GIO4IEif zGT@Nw8&cx>Ze{y^-CK98?Jib0zj09KH$crXTo3U)X#}hyMbygX8!l~U)@||^nOB%O z^U=mrwm^MY`OsXi8{;kETuG`1!T_r!QLXSD7sKnbkcu zV^**DWUeM04zsCSR$2-=Wz6bno;WOF{y@L>s?pG53QmBokdm^$>>IO)id(s9S?rf%Ok<@vkbqejZco)|Ke6$2P%B=z^k-ofmhGh#0lFW8~a+ z)vL4|5V<2aVK0;$7x^n zj$2sLX-OBa^iOA3KUmYMylhd0IeOy!uMbS_{7gb|$LSxnkduZPd*r#F%&5$dTKE`x zmBTEH;n2-=KA>M<>x#&{j&pj%j?WsHFtyH4HbU1$#>QBHB9DeMfH5Og80RJxARv;F zq(QXFMHwcJ*tuJ@S^|V}Qxg-c+2j(u=nSl6KrkdVYplsg3_nW*8d@1~wNXf2tMKXC zUq*S~eSXT$?Ni~bWJt85!=~hN`e@@-+mG$Y&;^Kt4 z4?Zd`p7l|#{J@m5XUMA2i-X&A+&3+PoDE($#vD0)Z%H^1_Ty~%%k$dJrN(IU#QE?C zy%v1Mu;V$f&zU8j>$Pv;p$A(SWwPRY{vC*;-BP8RF4V^;z1Q&HUI3)_+ zMZ*tHj*1w!Fu15AcPV(@M1A74y&d+Z-I&H!HTl4ryy{uVKT}H{RFJw*PEHvU<_(sZa04E7Ow*^|>$@%AL8)^0RL z>O(^O{Oz%kf;s`EzR>CxLKOMwj(4y@1&myP#NQc)? z4QYg+Xh5RCvvL(Zr52|v{VA>B(tQGVkMDVEEd8-O-7ny+RaNE5iSo(kQ#oGs?vP>U z#L=1YRRdJM@sf^ox|cpv5+8cK?r6{Q&iRTOX2 zic+KOG0K##%&o*4TIC+MN#QJWnY*XHFW?Vz%IQhi$=^VdKoUYIi*#?NN*}Z+T*A%|m zEw4?x*{$;v!@}C>3@HiYZP})}4$;xDa7VnKGE-vXzGifQ^}oaDkYo!A4+*s=TH;g@ z_GqO->78QInKeo~FYMqf?f{7Z8Xl&&J$~_U<}S)WS0?A_!$#SL`FEP{V5@k%7|x&m zx`v+I#ZLeF$bskNBe->|9$J6Q?mUH(D^~geNgU}gwFplCx9k|lb#I@X=bipLNj7NV zIih0F!Hp32wPl&R_f#|OdDmK7X{n}enD_K;V)25S+gYB-oEq=;5NVL zmVsQy5n&y-?51B|x<%x_gnHR}^qrIt>f=lD;17J~ko1|oPda`!2Bf{vt-Ud({fg3- z5?OXy0kB`DpLVQ5(IT%$?4Zr`_d_S&+WRNz)*?CEFH>vmVx5rGlKoL!|JVn;%2M>P zfpdl}D#~iTWF*oR`yB29x?(+zqs{=1n?3vqtS)-W9e$U^jpOf$MOYteutX?*Gezbx0and-*c@ z#&Utp#y+}!H`^_WA;H533%khWt|F(EI4<-qc;a?OcQJy;peuL`_5j}{itI%|BNbMoEdWS?Ep$YMOnlZli4b{bFm8onIe{~SGmm+ej! z9>#U6cL%XJI>$l>uS_0n{4FOTC^C(|#S|{fGtz5_g1zxPS}N1X zXz)>TqM?n$A==m=$`zG}%5AYFwpR88Ke@u5k(8R65M_#vj!jS%7Z%y|Rv4>50#zD~ zJ}fK<`sKg@z$kQ}Ci_1o3gK^X*n&V|{0%6nG6B6^Oo)uBgWp;3`Z-U?VzI*gWFi~s z?1UI$R9LgKk(IB$lP?>_IN-NIyr%!^J8^#h!IK)wen|HIb#(v5F+?-8?wq_IuX!-- zp;IdRdQD7ea3mMb(1&^j%5}=NU$4=}72>gxdulKCb68w!9xhiKsvkl;CvF`_(#5T2xfD~Y-f5~CS!MgeEe zbEAgj#)v`Z*iXb3NF+A^GX##jTYO0lvno)dvE^sCu*(vGC%t(Y z<3{8=WV$psdEBQbGYX98$#e{L82&tg{lv|c61bYke!y=NdSCFZW;}SuPEYNAEa%-s z#`~=+{?+wNS&0}JPaj)g{LP$4Ho)Cvk}u)kxefoUr4l+pE77(F&(vbTrUbBFTH3T*t&OHr${UzdFcj)#I>9-HR4{LEni@Y~R1E zmrlHa{-w*O3%}`K1f!7+=iZff07a}BF2xqqnznk=e|F|3B&X&MM`;K5>UY>_x+uY> zg(i7PX(Y&G35`$C02A0XN^t;~=a&VJK6@5&9+1|}1U~4D0=Oc`dI&(%uFYf`GFa^y+<-F z(~-`fKo~~JT?L#x9JY+3neiq=P-tjEyb`e0?kj8uTGmTBNSS7NvYs5v0QD^X z25KQ)dS(-JT0A5SV_+w0g3b~Jf}ddvd?y>f%acFp&rW0nT$CqU=`?` zA3egACS~#trnQ#UuTD(4UGHf%+UFyipO#>Uq5+x3HnLs7o z+PUOPOgtd1OLikAVaNOx*l{$*-wkR}v{EOEGMb;jn6PCuO_>h;h^pe;jGJ8im1aDM zYALSUd&U#^F2};9)D*f_8k_Ez>gG5Odc7I>J%ASxfEcZ8;hC|~b|&?V#H{jDiF}E# zuL8Qnra{J0ATM?6paQ%jWtgS zo1^nn^IrCx$jBU33N#@Ei<$WhAlW}hbv+H|kUTqZccENVj5^M{>+P=09a zn#Xv@8hW*MT|H$^#-lDVmO0GUlngm`8c}j|loFBU$qv1{s3JWtpj)R<6dKtZvy~JK#Q9-`mu8q~;5b`vL zw!-e5=3EopqhNOHiGuGKBpoDeJWkSqzYDwpIjhgQoCm*7516*$+piL@H4|`(+k=NQ zuaUsjv0qQIl)0S+jvdw211inb;on@qCA9hs&?^>U zCef-;W|C_lhgr<~V$XSCG+|SWa>C}ER*Z*FOwg#-DT61}_GRtlOX%rk z?B;?lbwTwN_=n`BVf(lMUhUSQ9%RuYR`1qK&)15ht+5WLXAE?ywqTj(SjapO;=S9D z0yNE0g}PtumrkEYoGk;?0gjXfGg~It7K%GdB^epXF_E#cNX~?0l|c_KzaU|I>FFP# zs`!Wz?%@Rinmy6`_mD`E1 zCO?HM!eO!px#QX}2MVQd4aA^Os(?&^VNAfU0-w5VPc%Ex5sfJ#&J;4|Yo0!Kv|9OJ zR)3H$lL~Q;Hg#RUBJz*+-KTL0BwF*zq{<#w>c`PvSGofoUK(z|*H2r@f+CGVwBx+- z@~iZZr4vYAMV>X%(z9*J)aPrsL(JW7YT>5?UkeeX!H!>HcN40UQxi#AS~$8{LY00h zLD!6nh<;et#0v>qWzZwUaKNGPL{-y?GQg=!#RQ>=-ah^n*~rlSk7%0X871MCO3`s* z_3kPBEM626;keOE#~izlYwb2m;ni=#c)_cA-t}AX=-#AJlJ5Lr=pq91;h|%l0um?yLXQgY56MgcFv3a*Ibj+_x=9kDlXRyeDXs7K;>&Gm{ZX>z z&NH2%w28Db#)=Qoh~wqrVKj!0*l_vYE96yjfsD#XDQmN1k|yRRn-7Kltm*t}rqdfm znMzZr*$mpPJw7T122p63GXQ-6k66e~j9?J|FIKYaCNr@K65lPzPJy{28XuLn%pL_f zsAf}86rdmYBn26D9ZK4r1Jhu{fW;F1IN!e~&_Rt|x@2Y?-BuHo>k|vQ<1ddDP-~)d z zEN%qZpezI&0qaJ|!f`-0xm*04UzTskx56{&N;)c@O#}3bXtJnAQ z-*+*^s5*E)*gyP5mwZna;hl>QC!xw%yl&0S9sp6dpl_0Yk9rmu`8_G`Qc(GeP4>-= zVMCZ_+{6Fl_auA9ki*RA#~L%9HjEIV`UZUA5vcn`XzZdOr3rOEUmiRp-ku(kv#d=e z;6;;T?or(jfr9^LW$6Ax5&_{`rZ!XmzR2=k06psySEQsyngl=(OqMqbiDvm`a4&&e z?gMgpJ9rZ_p?VDbrr=LZ$spNT_Jky5VT(L_tT|e%3(}yX`jBVQDV{-u{i}b`Q-%Qs zIzt*(@T)QpBWaS;@Eh6oNBoUmAlU3ou>IQA74<0t(H$D0KggVp|D2|$vjw>gc=(75 zG9$q)=4f9Q{Q*HfWmVF$*H@$rHadJOm1%Sz-ctzpAl`e^-I8!Pk0{L0GT99zK-&=F=kM_41B{VO}h-TJui;6?ruLuqA2{cEr2e}iwvur;!EPJmxI*C_iG)|ds} zEy!&)lMuT`q>w2a;=@!*FW)q~h#jGOow!og)drhDLAiyKu%2r+Sp%TEm~#Wn)Dd_= z`gs$b>C?i2I+rQzA%INh26J5n(jSIupoS%Kffj*N#+5G=kPQ~k@Nx`` z3TFfn_(9$g_GHC9CEFqC(Gb~?9vr0%Gs~e14M2>LecSBxVZ8mrT(E+>sPCOJowFTRU;$@DA%0v+5JbT-uy|8)vg&^q`L(i>P5)mc5mGDcyvD&BtvRFEP!=~?>g%O671 zo`6H||4dJ_odimcs)dZq2G->FfhbVvB6&z zvJT%0tAwf6*t91dv(WN5Ay*XAL!HI809PiNB{%5VJ?pxr^(gQAVRimtsCs^T@B3r= zs<`;fcdO>ua#C|G$r(jfV(PbX-inh&(J7(#z{9eJmWr?QLEyy>gMOsCbwNQ2J+vfSPo>niLbx?(u@U5=zmUJ*=KFPvtq$o z`qR|(wad5F^=a5(J-F}8b?&VFJp&)~{FJ#DMwSy%V*1E|$L@{n-=VBM5#=1lDvP~z z5FZWgC!t#|NE9E1%u6X3`E3--f+R;tTg*&BXk>}wP8@_?5f~L_Qd`BNUrBzYnts;J zu_B4P53S$USkmc>q^uOyf;{AM|Jpf%At-$gs^)Z*PBYU63qtoxi}I zaQdvpo)dErPr;2Ol}4DkOjb4n84dWFz_0vMgBSHXy3E99ZST4D*xbA8KEM9~8Ts9g zG4!c!<$Wgg>C|%)|8!pMCkxtEUOBc34k7dbk&)xK5+4lfHDLAd0VB2m|2E!%^B)MB z7o7iL8NUI_&V*w}HV|it)L2a?h33?~$hv!uQC9I!5g*a^Bk7<&xVa>Za9jU&B+#qi zh3*2o`xE5$J}UWSdD;H1r7GR9pvl^G)=P?^YP1UvVKy?oeFM@OM> z7EW5K_V~Wbv4b0@e6#i4-}Y|!a49s=Uh~;lk~_F-{~7%&Moc@?wRP3l>Wps3u-|t(}dvcGGT4>w*27Q*&MWOyg6k`7F(~VyoT1(_}>Ghr6 zrf(YCYuGBlX)B;tHNX|jkhzbz{UhMZcEA^zLLpiu!rwU2gOe&?)I1>cDcFky_99jI z#^TS1fTHnmqofKy3I2QsUM~d-OBG5JzJDlCYCBL$s!;ufKS#pfL#`nF?4N}{Yu&F0 zoWu8j2k$qt&sTqkH+B!87tg1QWYAsH^r}cqI@tV1DQ7A`Dvyg1~Mkn_3(QZ3^nooC(CG7$`L}XFynVSgDXa&#k z1I@!INffU4L6|pAm;@; zD?UKnC(B5Qm9@eb_aBG#d+uNoT^vU$Qs|yUvXoE1_TI;zxjywx_*5^E;Z+f|(ml*^ za+!wU2g<#WR48T;XYsR`0=b4RODCO^>Hco?jhozlagU!qp+n#kh^SNJ_xx186tkpW z73oOv%RxbEg)f}KL7BIj9R?mg6Poy$tjRBv?Sk^j2w{bJlc0l2xo*GFpI#vyKB+!l zki2^Bv8&UD=ETIDPA2zf)V&sR|LeDiWus2}NAAZb=TGxK^O56pT)1#X5+8O(jN3cf z{Jxamg+8)!iT7i;-K`Ou_!xSoC!O7sp8l5PRg;<3Ftz<4E#uQ^9cd6gm#c)&1=)9q z^TLycV5AA~7CJw^ag*f1OMuTi8ow7O!MDDmz?Z$e#A2XM#{*0sPfLcs*9q;cvrrS4 z@(ZTG0QmC$V}s`s>!MWpASCj>rEU^8-ZAy(&z(C7gwOI3X>4A+mlT98q_#S5D+aIN zn&O}b81n(&g%S)i^QSuiJ<)e%kW4K zfn|i9h)vurM+?}?Q8J%Tf3QzjgY+qQ2ToY`llW=<0=&HZ^#NYQ-?b2&Yk>L>97PsD zhKxi&7HVdM3>OA@0O_C=5tGDD-T>AiPC0ttiwA)$mKz4t0jDN;g{V!;NA($%wp?bJihcBt5~;psK+ zJP)#O{-2q5lTh@2_x&45nY@{I=6PnGUT7<6Mz;V72O?kHc(?RU08 zMV_zYIpZyqwZIlc53F#LF!~z0T0Fn+<2jF#=yP8aUVL&~>&VUZ6WWH~*}&cYta$Fe zneS{lM{@W7^v?LX^Iu=kHERK4PB`S9$%GQ@Of56f+ovJ5Cov2GujVB0M_oQF&5PbX zx;IKD1<+>6Fhw4#7GL^`ta<%g@fWc-sAN>z^gX0md{pop+4tHzoLamzY{)XUw+U=- zw2w#dQ!*>|W>AMwipZ<1av8M&_+)K#1$I-8`CEJ3cjwRIx}^olzqQX3;v2)i*r5EC ztxEK<4m-8L1{ZPMNIAqw7~iZx6xch6?*od@maE5QhXX5nk z;uKShc>XJL@TCv-KR`-rOycs~vF*1FsrjN7afUdxcduD}&?&bJYvfwQztuP76i{ks z?)@{rU#Nyu7k)-24+;A-2s{aL`5D7m_DPRizT%(iOv_ zb#l-elDRBL{G0ie6Rx4LT!MFZLPB-roH^WN?`iQLKT@cn0giAPZ_z<-@*`Rw0YvdJ zcKIA;r1GLj32r(!SKPCOl%x^?+EsKeagp)3XpaTt6xh=z&f!`x*JkA1SuhvXr!;|j zy+R!l;O|G69}u>cetN<~?xX~T@|*xA^earyzCm*bQ9KfiE)3yj@m=xWYQ&NFE7gHo zQcZG$)T($ANpiSt=2qR<81G8FzM>%^WKa-y%3IZxxSV?mbb1x`^9I%sKr4pm{bdS4 zZPxg4zBNeb2Vn(OQG%-A@|i$Y(6Ec^xgs7KY0%0eBK|1eK|cJPbWT<9|je&BA2SFi1RK z_abS?Fz`C}TUdOixSLGi-V`r%B-m?6E9EjLFdx7Qjvaj5Pl3~NQt2l^6R15-C#LN} zfR|`+Yd{R~3*;E5^z@{Ja=#Oesr=sPZ@=Bdo&Wk_5Srej5F|S>lOD7+GtR@dLVHr$l`fqd|SCu9g0jED)r@VhIYsD^D2xLU5u_Xw{MQ zi`)vD+_w%;tv>4La6~f0rH^pgtR5z;u=Vs=46@8F`4(|r&As;)gMJ+)aj&L6{LoNx z==$Y(Q)lcMzF^8A&&C|B7G&%^$v&XfQbCE^blclgXDroniy_97-tT>!R4a=r)~V$F zsLsdZgD51CPvWXL$!PmSNeP&vGK(_(EP9+MmmPXn;GW8RQG` zP|bTa;#Y{Te5LmZd9bj9QOjsq?3pN=Gf)T#2a1dRi~)WMLC~uKm|7ou!b^PR-&na3 zx6(~DHYUhs*_2kf+t*5yr{+`Q5*WAobn&UKXVWReI<@412?y%MXL-?MZBA+3I{5jv zEsY#`!XvS+srSt~GJV}MB;&x~?pa%A?u!*WqMeK1B+YYQoD#y#$KYWbdgX&%#5c? zD`K})QlZ_j9x;;z6Jl6l3d(b&ip1bNZj=?OsULnhcEXsPqM@U$o5XW_5()p!n)4Iy zSWcEK6F*ou;yZU$@odd`Wl4Ta=7ibaY1|txJYBJ(xofpWu+Hh)^^^_T;bVZDppbJe ze>)JQkd<}VeWUmEk1AzbWEW(80urt+In` zoN+TYe8>mi>70^+o>@xy_ zD9s^cUUxP>FQ!jR>!r|;*87p{fV2-Wp6boMaRu2QL+4;N4E9E8*Oz=4!20AGHg`08 z=SB2hu!Hu|@hzZ>X7tP|eoAJ5U|_RqAQ)7iC4O=;(?)DGm0#zlsm8a2*O@Fz9&)Cn zM{tDvJwvcGpI!#AE5JVJ&v4$JL+ z(k2{%PX{7_&%;9JTQ~5RvP-f}-eH)LV$I6lBTCKx&%sa zNjl?H$7WcS=+#HE2l~gavHeTqpURF)`v*icLnqsU^>(k33kIVfa9-QUS zQx=vtYA-vklk`8x*-UVOfGu4^>h|_&gPylj-i8L;@^Z?{9-mhD{m0^ba>vKtU&d+} zA7D35qTe6L9%Jy6#wn#{2YUL=Ru^U^q#Nu=>Ivh`QTw~%uK_(^I?~X__=`njFdBa??F|l^_JQ6ETHu@$0esP(it2ALQ6-0VC=6)H;jZP|n5o+uaP1n+Ex33n(r#feSu>NIeH`D*Pe!`rq&rX;< z^PQGgUzJwNIF5pH9N+3GpHTQyK0$hq0FHXVQ6tlxR`Sp_0Qe%7R{+4ncz{lkFkf&% zWYQM#`BViGIRffXWof_QxpsjYnmsc;^%3t;XaSd@S|4y+T$FvVsU?}tG0<7<~=fh5t%4< zz4F|W2PFO>bBJX4>^M>_*8i8(`u;`+(v~-YFqAC zZ}~06k|gSqX07XLAAQ%5ytpJ$pGfST6CNj_XCC?M;uk;o;9}zsi^k8I`plG;Rgo7z z$o$>BP1jbAJGE%Xe}HR7YnL*b$#f3TT1jJ~G}6w-B}sit9Vj!Cvovf}lA5>3t}?zs zDd;#hE=iDEn6$}m0vna2k}Wb2r@r&W#wE_NWhkZk3@&UG_IoC)yw^W>`3)N5#DQ6^ z=Srcz6$(5XmDau0MdgI9-hT=I1oq+mrvBUN6TueTnd(z!v&KZJ_DQ`THFNl!Y7F#Q zeU5o%LZ_EWvb4aG!0n1n$txPx+OfPtJbzkzC51ncBEAxT?#%1oy|F<3vSmn7Nv2o` z+w$e#@7-|JM+M=1qWt+F_68X$ldh`IziOjYTL}YT8}Phh7!O?YRA!7hf7uIbZw-wX5N5D$ZhcCfG(( zV7MlArxXg404pdgOlq}B1-qjK%(42oiCMasBVV%40@PGxlm7YaYz{PBV(a27Z*+CG zo~A465!1+*SkO|LzG+_z`@bJ0tgbve+KSjzN!@LhdVA0k8|6k6xtcC+~>=zzOi3>H%p_ zf&`WJaC+%ofVr7FHl0`bn5B{(cTG zCX1W6h`*9S@9`5z_7njI*5x9{g?TS?f!^=9dh)FpK|U9)26t2_M_hCK zai01RVQ;k^vT-&W^=wjio`If6^>w5N%Rr?>DNqiMTwGa+NcNR;rop>e2o$pNM-T71 z?RN2RSN^msA^)DH&e@;d8MArS;$x*}Gg3~Sdiqs9fAVe%uUcxh6Yo)69Rej`%vy=|V$9>W!0yFk9XJ;jynJ@2~{CG70K%kIQSvMYTYhuJdv zWK_^MR0*RLB#3g4K9Y7)X{9n3HIDx}9s3U4;TFPmBe9ZJaf{^IFW=+$H^`H|RZG7= z%Bc1Y5+Z)@<0?2`5$yLjNO!IE9Hs!PBOHX9QO`tcYK#$ebA$J09T+kaz3n>lgqc*%p=oT**_AFq;W(A1N zsUrjArsoNqpY@=x$1s~!7WS0PNJTwPEeHg>l;Mk#R@N^7E+y)brrClxPre8yeEXXC z;)u=n-gS?zh7?x%XJ@C*O&W_(mV<-u+L%#7TEr(aB6Aa6A>?K0tSVv4qANeGR&ai* zfsha^oKZ?2|G*9u+5h<$TXxJTN-6OfrVdIa8KtDNiI>=HdRg#UJ)KT-{d{!7WOmdf zjzp;u8tKYkzB=iqSx+6AA;Q<(H+9bw-d{j>>j9U0uvVo+cV(cv8chHMjM@_b4W+vQ zj03U|0>HeF)KaCVkNa_R8J!hRi%6qe*w#;eC3;JiUzV61vPns<9RB%_& zWSC{DPjZ}$68V#w$+9kbeJH1+kwCc2>@7M@BJ)xtFvUDEk|O%5y7kY@lt_JIQH;5+ zl!v4D3XL10FP*e)R2(JyL2+63qAZby5M9S>e9H`c$+F&1pp>*_H{xYKEY_eEMtMv0Jls*a0DoJo^Cih^kG)B;D^+Zq;lnYK* zN-$|BM@mpLX6z)YCb2!0++h-XB>|53KQ6w8s5xR85a7gjeGzlL-yp+u5GbWXmT^*{ z7Z4LtcfzO!!>)rgsU4%`v|6>lpW0%lVx$y^Lxa&qGmjpl=k&!eq2%Q(iKOFh@`%<{qn_pfZq{H=Y!pR!}gqU#>B98lm z)mNVk2~n}g6+}X*fCpBv-50q+8>7=mq|7X-$h-&LurUM`k)JD`9~M#EnDLOf>Gg#h z$@uA?{(*}X+jAB-3_n74B)5ovCvlHO@U{(|J029{h_=28HRJIiDZMslh(BQiQRiONotmozZ@9C!(!cTx5roOELs#U?;E(07S6O^wf zj!D?pdGw$6z4-NGB=%3|KNepv&*|u%HYmSi(-i)PSH#8Qmv?HjTi7^l91Z}Cn)So0xO6$#G^9IAjQRAiq_f$(hf(?-Ja1$058nFlbzn4=+S zx?$0Op5-s}%1Bh!Rel*uVyM0f&Ixrw*oqkgWlqGm_5Q6`XEGV~X=O62(ob=>lIAj` z6(N!j8Ti>aR6rxKP)f}jJ-BErJqvddwjTRTJjmtc^fYF1+~W(Uj5&U;sQynAFI*O? zw~M_Gh*t&iD$eY#4F{VWT2~N<+j9>4aRP>u@OGEX^AwUXUpVQnt9CqzRhS$OBsH+? zhA1T@$i4m)vIv$0T}4(k786fb^FJjx2$TL_2@XR0e@$@UdjA3_&63kT_eL6>#H(cb z{R$%jVEhySIyDYKo~A7Q*6fBS9!-7}x%3=f&M|k>Uz6q%(pueIdR@QeWlo z6Q3@R7Zb@-8v&72cB=Nl?up(CAt5xs!G!zoIgCgA_3UIABb!b@NyM+QNYql6#U%+(D7pqlP4&TRgz0Mlz*2p9)vwebO7aZ_g)qr zWG6lnotTjS=;HOf!;y$22W8@ZwRD4#ykn#I#0l$*@{7taL{l>rxXFM`*_O$pSBg~m z88W5t;OYCPEZN-qz$M(YISr$T<;vPur;6{7tQb9R?hmuZ*KfEzZB)T+>x3a&pO5uC zGI#O$sc#)4aZ}UoZ98?T?Y<@DjT4&YHkEjPsao!g+%ycGSf_!~R00=k}$)*{m6(&B_lxhmhGV6B+3Y32`WAbQvVWcK5W~?@=5Q|1|D! z9P-MZ+1#_)*Os~Yecq|rLWA&ik3+orH2)z{QWy;dRojm|&Ox&1Vv~E2dr+9EA|*Ra z-CZF|=?;^$abF8Zpc(hB4;sLz!fLbG0S1WB*gnN93T8lj@PP%_&&?1n^dX$DlB?vL zE<7zNA~zw36z6p(4J(Zqde^xb(;r<>WDE+^5N&`ZBr!iSwJtrRvGSpa^4w@!YW>vB ztu6O1sZ%I~26b={-Wy{#2E^n6ma!AVl-ZV|<|#!99qrAvjTqzs(Hf?JVJa8g9c{?#)=N94g>hLl zF{3d$$gFgK5T3wSfqOGO2N0h?-ciC{e%(<>cL_f=tki`DG!70e7_;`+)VU`X7S35` zbOZuG%-N?30b2<`}D~clpch`2Q^m4L`mJc4dYw(j$f1SX2?<1E|d)h;|wPIc>KaKD3 zZoIOV+kS=KH2716XK`okvfIuotqMh;V3R-D`+2cPYp9mVQ7=j^CqaBL$05v`gak)m zSRWi7%moMAELtnkTCG~b2ZZseodNWs7r{=K49}M-hZePo_u!ix_6g;kN5}hq0OF&S zawY!pg?yGx$HSVdEaF&bEB7&Ry2MX{5nCdD);xIqtWi<#<==7iPaDOjr+no8F!%%4 z2V+R3FlE8X1xpv4S|HBn^E#H6Khk+c*O;YzQS8~0X`>uNRX`RI*DH(XMz$~rB2SWCVc)V zZsEEJve+%IOA+5nxzl}T1paL%_slx8qC#V;8MkoN+T02AR~-lx_}iv&`MaO}?z?Aq zKg-?gZdx`hHD~CGF~x2pcaIo$`z)hFKV&4Z(fb-$;9#uTEkoUzAeYNZh|R4C53~hp z=}M_zG5LZg`2tqR+j*8yz&ato8V^bj{svf5cbN(8ug${a#rdaXGBV)z4()GIN zqL$<*#kZa+-?VaSWV-lPY|1HUuq%t@`@}aiaYe(js?W|_d;hEdsa~8ha_y)bea|L- zk+G@!s|Wt`>J`%P*}?!sAXp*aA^t-C0wM+cS-dy3Y=onRha1)o56)8_>Y$gQS5%#B zuxvQ|s$&t!J9&%IY4jj{*@i@FKFj0!^RAYbT_fLp_ucllz1o%* zE|Ps|X^|iMVc4!+!@S?TL#l`2zn-&izx{SQ`{CNQ#*A0e8qZh93?g;hGV#aS*SOj` z@<_~)>XG|Yf?TaK#l*&#T7~z1XxV)&;m_UpbNOv8Em!dkseXrVYH9ImFxO8lKkUX> z_n+A?+4Rn}4bp?`_u`pNo5(fs&9^x2t=I5PX#pAP7vL|hB}-z(V;H#4r1uLk#Ecj< z0*V~z?GYd4KLJ+^q1AG%-FkvnY*6_V3zPT|o&6 zga1$d#zD>E<+-33s0G4Sfo@mD7Wpof-$9LrJ1A4(gU6y|{J=U4C?t(2ZMqN#*uL*F z-MEs2sp3`fGx4QAZSbtO?C@-g|N1%KN^+|#!jU(wUf{1>>3rkyqihjrv}05bc*;i# z8BSt`41JCO8)b5Lm_^%-+8~s%;F5UoPRQO=sB{%1@d=svt6jg zO|1yY5K}4r9o+kaJR22#iexdx7LQ9)l^UCnz$eM#Wmaq{znl49uqk@;S;3H$RMtyP z;`}gvQZ|o0piB%kR{Mr2q$&B5qP_Yb5k^K$&nfFD2s3F8h&^`;ekyrNcyNX_ZD4qN z_oX))=ihB`+5P=~yl(i=3H*2Hx?j>Aj)P1i zC`QO)khLOH2ZV1^Q$_(L7$~}4PBWP@!3$_3U?!;vDETFvG26}Rq4)p&(1thGm3BUO zY02-K4zC&N%&CgXYb}lsQpfO5+v}T$$8G-m@d<<0KQ;9jDIpQ!)MFiQek=ZGUuAo4 zkR!9IzAj=^1zkxKyge@~)WAVtF%890SprCSH#NK=s?m37Za5(V79?ljr3~K9I~$q{ z7oD6tW$(C@toG%bcUC@@w`kV*y7-*@_|kZ53I9^n$w{leer$Zkl!H^IU;gB+(>pwm zdsgl|eC$lyh)KC^)6>Tdq24xHmHi={g$P-a4E49#OWmBR9UjYwn7|fY^ZdN#`sT(wmG9 z18MNCuWNJ`r-oS_Zo?G$z8>Z6kB)OkRZgm?nmMe%WfC|(!u!5^NU*y)n9I2KbC5PT zCO9D2sFZOcI+qJ4AZyqmmqrx_*!6=W$Dp0po*;|Cps?r@x)r$c%!Uk?!swzKRxMpX zx@zjHqN~1c*%0wgc<1FVy<_jN^7T{8hiyIEX&dZ(gw$6Hgctlm14xedp6E_@bZMGB zFgnp1k(ZSz$gVv&Zu{62d+Fr5_B%%<3IadQyDhRID5%EG&A4_(qtS)Ng;?!ol{uz} zVm(Eip)>*7xzq-h%SYML_yoH>Hi3^d8MYyBQMy}@Td?qGpUz~qLzK=$30wHpz*1>4 zD$Pbk)(g#1!f!1euomJ_=^bA;p2=swIu6yjFA=o~4!+9lt2?Q5ee zDokmrbdv9=55d#>okGLxJ05BSFiJQ`WWg*X} z72-ZqbrpIFt>IdClHLXvG zO(0QI07dOn8_{@7j)dor%r9NLu+#n` zAvtC4lFVew&XMn|d`Ts*+O(y+Y59qnp5gai-ZXw|Tby_L=_fKh2~DM`+%Ju5I#7?) zPaa;F7Osn{FS7fYR5|IPo~pR&Cy#$qJIZ4&pR;fHnjcO~PHCF-B{ytHbgHXtG){W& zlf8f8_sB&^W2nRt%xw=d2b!#WfOflyA}FmWs3;I$Qc}^lmhOYLX~Jb>Rb6c07f=>x zp$oSU7;0|JEUc3kt*2UbG9bBwu_^d?`kl|B?sMXyNXfNhRdDjF=JQ!iiJ! z$LFpFJoiTp<#RrL5B408I`FxVd!N5{5o`Mamgs%(ez2MY9CDcCa_VlYIia?&7y}ma zAz3L?QmI==`rsWwWK)v(SP~hUC~i&S9{ z*a(v;f_@D*kwEWPZv)~X*#D7lfaUh+QH^lrP-{(aoBr!IoEY#CTSp9@Bajq~HH>?4@>I~}K z5c$p;KB6-^I%8)-2$%wG${{(dFm)2n9#xYe(l8b(C@H~Wflx^Tl8W7ofKjFewSZYW zK!@?L5FcLG((cJ=ND8nd)})uA_?K%_tN+ zSrfD)gja3X>q)1LvO%_C3P`)0Qe)r}n8endpkmC1RF*cRq98Zd5jQ0%$2C3k#0E$0 z(6+P(28>GAt{RI5HI~L%0>pm=n4V6o%MA0`m^eg!ea9UHyv@*DV52w7WFQY}cK}j& zK|z^3z(|2vqGu4IB{ko9%fKTIONS@buQ@&;Ij%b0US0kkeomHtu1dF8m2(fq)N~bg z9+;7T$r@MaPVw;H(t)uDreh$sz@3T!bWYYuR&gHRdV-7n&A#Qx{MGD0QTgOeT;5yW ze#^jH8N-X5*&WL(qXQG10m(6UXS5bY;^&Ge`g2kYzcxIpKCyCkQ^KQ~;J7e{o%=96 zyFRIMRwEsV4U44FPk-kgMcD}o9qlQZSwIC3->GK8q)pjpTI1fw?9QRhNzLm!Jau=x zv`9b}L`GdoUMYVmzF}s?)W;T=aR@jg{8DaC|9oU%K6Z|+p1uh^+~BZ`7@H?4DtAQkYek;m*N+Q>?RW3kk7>1@p#j3I#nk^w?1J zQN6<_K1ufh_Yek1YJ@Z^^2A@ly7s+u6YFmDo?Ie64NhITglkv=E*O8uC;Nw9&!NeD z?=!f(FLC))wlF|4S^?=j1w2@rWU+T!LP-qm1S_Mu7_6RD7~&x-Kz3vHS%~W_|G!_p zU?dn!5$oc%?GU0zjGOFPzFOg@7UtO+mY!OcI6Tzj7Zetzt($0Hs`U4yx`#IuYNv=V zkW%>%-oYtNd69Rl(W8gC$@}%x^V^4+bpKFj{1l7t;L;@g>ilCHjZo#lE z2p7bsW>Gq)9H2(*n$j&&Jp?QU6)g#sTJZ$LDE?3Bj?C2Lpxk+*^W2qV^Oin4G(Vf~sJE<7uVZ~nVdC6J)3;YCq7u7H>*@oQ7C zL6tIY*Tm5~XEg?@o|{5StkL4vxYXBv!tELbZ|&FE zyA@J5TPBw6Ae(etB6ouku&@5@4*W9{oNa z-*bg5G`gc5n(*`paTfMJ1X*s>Zci;a(K2)k3^D}@2hg?cKqy?*+mz-A3M8zHUMk$K zG_ z32NZvVKwgq=_4dERs1BpZRI1=Z-wh)#PHMkM{WY{l`E^y&dIm|y4OyK_i($fhcIp! z;(&bdmQHr#ZiqTYp8h@^f6bE>DsKGxXLhjG2OmdS9b@P4)lcH@FOYuq8;(9=Ww*o@U>UFgndv8#6a?u!7Zr>{oiAoR032E zhRmG?8{jBdsx1Bia?kEWL-p=xLo+&W7Ihn~v|1QF<`Nm9N(0!6gHjA8R=eE&G=%vD z`h6OaIz$OcjvN{m2>oO<1ATY_kOq| z{k91sU4=VF(U5l7dSot}6PgTz<;{#dq(w z$dx()Y$qd{2A+GzHk+V1V9GS+TKmbtR`Ez|{j`dXyQk;J*56h- z;n1|4Yfo|>Vc=`0ymRis#gz%eSGG{>znd|@3xAZPkzXL1|c3yKJ$`BW)HSk(f zAZ0lHXqBV`A6=3zFO_tuY6de&9}#uX)KCdeco=Dp{hIBiiTxYS}jbvt2mDIvVu!eFW7HfR{XY4RW{3SMpnTNwO*s* za7R^21rgjMIwxk#Ua5_2Z0krJz#F@q^LVAerzE9~9+ah-*mLn#e4#*eb5cj!;IPnw zj5xp4#+-;5lTsVAZ@8BMYVZ4cXGDlHF+IC&W;VI}@~ub%&R`5&0Gw&TQJ{VK^W*>w zD~iBC1<(74F1?4KxDvHxRv>0gp$4sfOz|HM5Z3+Z2}=G!#`k+LmGG zKL#-kxegi3Vxi0eE}XDgz|LY<$RhPoy8{g=-5M*x<0U*WEI0<}C6l%!O3AZT-3)di zP~0^@6mNp_I-Oll){#-y4&Dmleu_767bunU-f2s)ayh>OOUBC>EGaK@$j}2%Z_*wJ z2@%u>RH}#r7B19Z5IBF6g6Ei}iV--<%1{kR;${f%r$#Fp8%1UH>mZDV&e&d-vx{=B zCQ?r#$awL&jTxVb4~iQr#FOIlTzfyPCmbh>fP06%dvr93)W-nw>3}?onWo%|%867^{BOW#3%}{y|4#@Iuk3JL z^_Ko$u^`@knza1tsTOB2Oi&pK9-}bce83qP6dP*^enB1)dH`!{LVcOj|nX=&C=(DHN@oHhSn*4LWOkpdz$)jAQA*s z$*4o)5Fln#2>^PfB!(lJqCeyX`ev2AV#t{6)vs=-%pAXI__QOH<#i`!?)uB&;VGRv zUiI$HnKpK41UJj-&WUtp$5?H#*^Y{#q|Fc!WEipQmFXiljY-XnBB|ky5r@CtJnQ1~ z_slKPn9=a!Y*?DhYIUWB*;Ae78r&U%*zeUoZtpI()g+EcqTf<%uktu|KW5O&b)hc%i+5gx2F1=0{qC&H*N${I`z>( zM?@-~KhuAq#tWCAItNe*O{uR^qqmJw#`7F*P-t&cgrg;A94983tDRPl&hj@0SKz5S_EH^2@`-5;doM(r;kC11m=IvVv ze1*`)kgpz!3c9LjK7W+=_n28fklJ)W#W z`<$7UflVCbaT6B|wB&cLo!TUT{) zp9R(=5{>v}w>T_pPQ`1)F~n6>kZLf-YrG90t6fDw?ekX7>j<{bSifWa3}zAOhZ$DR z`^$_x;9Aak@pAr4?V2_+5pVbDbERZc7{0|c7QI5f-Vu!62A(%e$4#_ z0GZEP@}mB4fc(qagtazOX*-s1toHu~Poe$o+irVXyzjSR8Y)XK4$%iznXJ};5WqHw z!Zt)7Ak$g^T~^bTg4TB`Xnd`7DsKd_Z%fdKrPFx}sDJg8-T?FK4l9wpfLo)0?BoYa zh8o^3LCO1~{^&yJ;iOCiq2;JJI%ytf&gwa`Q#|<~Dcj1&c|R7fa!)7odhZxu@S)xx z_#L=!;dG{u@Nk1&=GV>2Ecegk6D_avc2jAY&0X7ci$7cL=P%C`pFTnI@8-+IWjFh* zt(kcRp(Hekukh0N3VQ2!FeFHUuy=9(o!E>F^%!po7 z>keVI+?ue+PKxbo64va!Ws@e&K4I(In>M}eO}%-8)K`zNTE6!K_`y~%eUs*IL>3!^ z^a-6B5*DU#ZwnA2eOd{n&%PJ~;)ElMneotb-c!g$F-~Lg$Q=?7;wjm7B=L$N8^f2s zAbRiH^4Y$o-KlHBSDh#19;#dJ@&4!?LE`GBl$I`-&~T+>{ z?GJo;yZo=qzdSM?8s%MzzYbZ^ngn%)+nF+A`Jl$-tx0sLDOR;r_=;IG+ zWe$hJ)g536?WWCaCB8DSZpr${md!L|i^W5zPUV17VrI*xUJ>ER1-7=$FR!Mth0ENt z0!QEV(h904uJ&feRpln?#g)xxVk&cz3}hL?4aq&j4lS;w5r(Ss!w)X5hAuc(B`&aM z*2Jksj^`Te8P#zD4LOANI|KHQCcrupomI-HHW9NeOel#^t7U21jOHBbEWN;3VGh3F zcKF;2h%NJ(O_`$~d7VCgX`jJ^_T2^0X_inyf!GEhxAM6ZBn^hFOO49G;>wpy+4^TjN7}XtQ$O%=cWC>`pl8%_|n|3JK zzHip;2R6w3ky4ifP3TASaG)ztEW{PR0^0&{euq}d4Fo9 zqnFA1X&Q?rq=FghL!w3`izsB#gnflS3ORXn?f$<%_*%$UiI*MX(~i}Nt1puu7N3}t zEgqRUZN-?K^)ssx)js9i_TekuK6vnLA--r@_q67*VhMt5v63O^3APF=j6)0&>{L}Ah*qy*4^-)f-9!#JvBUWx&Ol9IU;5uvdvs%q+8 zr>DhqLOg

    Wd$R~+UPqyZ^mqqj9zo4s(KKS;$fStbqd(lMxl2F%~ zZVOZfAQE)?sTGyn=^HUI0p0B0046eIwNzq^&+AS#xb%p8@ek4N4iB%~t%Uf4TqMRz zZbV1_nyogc6u0J~hUx!;7x^3gc$pxcn_|moEp~F;Pki(CSLZ56|NlY`a*F;HTRtMy z7->O8^bSlMIVQAhO%ZjD3|uFsol%{Ddg1#*E@*`SpYDc;A}Pwm zM)8e*{b4e~OE+CDNB!axf7u({E}rXXKCrM_m#0jl8&8kxtf-z^6D^k)`e}`ERaspO z`44PAJ>DtZ#qt!bAiMsyjg+pVSW4dXPZ@T5M`k$*jto!D@>hTFuZ^w%ED~+vXK~dL z5$SOeYVtli1wAkGgBI^=?7OJY{AP&LPT8iE8_ZhCZ|$K~ z&?Or$6e}f_MNuAJ4soBwB`~YifQ6SDu`{zW<=@tBdUY8}8#Hw67dsQhD-BbJEqi@y zL)w@-PJFOz{l^D}iAQ4Urj|ABTTmTaH??&Bb9s4uiF@*& zq-ODrn4y@~38#G$v*E!Wxk~Ep~>HyqmEm4*%0LH{xlFgvJu|TO8R? z9-iWPDxtb9scre#p-JLX?W783eDji!a76 z`W18!C!?Z%1KmBZj=Kd6uZrb=6iRPB0|a#jWx{9jCvYQ!k)ci0NOXuWDYxmE6$w`3 zWTua0MWHU7q*&yu7w;PmXSyGdMNO zpb%$prK_CBw&WEwc6|12*0}YJ(;i>j7P#=}{OSa&A2gmOi0w}S6Lz`+J;HbGa-$`r zTh0tXeJcQ&>whgw6h3HUJxz}G6%S0VS<#-EJ!VNM;lw+?3mlB#nuJ)-&`|F8LzlP2 zyQ?M?4qn(+Y!hdaJE!}{=GP}jMyH_80fGNoCcJ{(yJXH{qtkUDEFvr%AI2z?y3;rS z0#=rds$2u_Wu`P%DVusWpsCUe?J(QY_Y_TQOiV~gxxFI0VMFDrb)Fp8i1D{&lEY(2 z=9t&hUoRA2FC?y?@5)~|e|Cn;T~bOEnThjeR_tm_A3Fvm44xIseilC>E?CL_EPgA@ z5rQG7g%=w*&d;(t!l0Dx^0V-}sOk@> z#W(Z4x5vb`j~-U)PD~8U$)~HoRd(XV*ke ze6l$*Ipmj6mrd=+Z%Hp%v*qAOs;ffUQbXFJHF)#^yh_jUs70^rcYshs7xjL?R)fAn za58&{&5DK!%;CUY7WW5Fe(dMvq%NI!9usrTfd+6v4_0x%`P@)=4D$f=~-EU zD3*yGzXtm_f_WslIW9Yxcck(~QOq_T;Gi}(N-I2c-=GxCz?|fZ41qeyyYLBw!`D~> znwhjFv$gMA)id6mEOL^QB3Sw?>rfD~h))lfLMHk7?lE!k^|_Iw8@UL#cxTh{mc&U< z_Uy=JJv+@_RZ|%%JZd!B;)`Rm3r>qC zm3gBVRjm8tmRf}m&>!p!P$1Q9fi-#{wUM=h(J`0%`9Uf~ZK+WRhc^A2?d09oeygrFrCsNbzXZyrD^>4}Woc@|39) z<8q=ahfJ!>nOL7Vd*(wSq~)plCNa{wnNU!Fp&G%f1u$Z3)&#BA zl1lAcp?^?5y!iN>EVOsY9+tmw%&tK*sv`N+Dd%>yieC$Vo|B(HC#rC2_Y4=rE3quT zdJMG9BUF!utu6{a7+A=HKYk2H(`#Q6xm5U8Yu>9!gT+$1}!Ekrd-&x>B8KcDRIB4JafG-Uk7d2 zC+r8X5kBI89Dw$t_K8o^=su|4!nSgQeF7o-{ad&J#=18{-mr;JTUQ6JAsnep{4E$4 z&Y3c0j_~ZeH-fm&R^fv&`~wumul3erZ3 z#{OTx%nTKZF46Pfz>K?k2|9lrPPJBsd~Jc#n*6C>n`#c!4iDHe9}MGG2&fZZCEcX# zjEX39p@HNm8Pbyk?Q&MnpLqX}w0Q3D)h@~xU%^S-0&0zFe8qm+5L5(Kqt7Cp(gOy} zQ>TtJA)kwqT#55lg25WB1C_1qd7auIE_&bh508#9lY4uJh*F27_cH9LX6Oca;O)A2 z|4yCG!5_#p2Oe5xMduE$-_e}cQ4u|L+8WQo ztnu|pW_PaJSv#mHCa3G+!tr-c$Sv(@EX3#$@ zDT8uCvf@JpeOMq-MVT^3E-YfnGiV{BH&RtD-D7W^8_;~p8QKh+n)qW^yTwI zmJd&CSh~MqUU<29vS(IndD-Mo>&ab}(K+sb_~?{k9ryiDlaD{0FnDTl`@U&;JJ6f- zO*cs{B3)!rXmUYhxU0Gv>$D?2bvyH0Bv8#hU{_?MY!}4A@b2Ky*gbymT`+G}bkmC2!-qRTy7vD3ser|)iY2~4Y(Z>VFZ8|o-ye=m@y*rJw z7Y-ei;7lpe@q?~ZwQgunjjQX*>)bIet>@)gPp+x5{}TPZkl$A0bk-g$M23EC|pgj3^tG6BJX~kv$r{M|*!18-+3<1kuTp zdLI%eVkZl^JNQufY2;5^i~V4()I``~AQ}1cST0}}H*Er0Ef|56HXyiw*|05SddTxZ z7Eg1&BW3vfs?uqV36;e~PcF>E%CM z>oTW?T)g;?=bqKUysS&8P7g~Tw|&g|e?K!*B`2SI%M=QvrgV;sq!F4Wlh>32`h$DR z_#Esji25D1d{CgZQ_j;eG8a7F3zXzWL+WrMri7X*p_}Pgd>b~!N3#Xan{3j2O^Pp5 z*IZx}*8LM+ubep+?l;sie~)?POpc2%XCq^vw@ft%`f-gcsW`Yau)E5T-Lb;l<(X`R}Txv{lYf*eGsV=q~N>5g)l>ap4HASx^Mx7 zy|88)hvCeE+62_}t&oPUd6YK3$e3trzr86kD`Z9seETAD87P=c)5aI{>IS;=`yk`i)nuVAo zO|(18Kh>08SQas8LP3y#j)y}IX75fXgUZO5o0!uh;%l6-pC#GERa(0}#4pCB^z#?K zSL!q>cg3ho=->$fe{|j4!Le~gb&k~X zSX04@m)DDmbh4`Mw({^O7Yd9eSY09dxG;;`Zj2{il92TL&801OjLnFt8k3bfwPT1Q zZDdQMd)nhm%YLyXS0%?cB#M9K_F6O36Z|7$%;9l1S1qsyPbsYaRF6xL1^j=Uy$O6< z#kD`KxmSyA+16^wyDdw$yvgz+Tb3=a@s`c8oj9wrI*H@#3)#s=2q8d#Bsd9M8rIOT zg`E-#6hbMbX<5qaqb*P#v}Gx!+XG7MtN-^L$*~gxeg7Z&@XdI1HFxIBnKNh3oH&UQUEv2Uysn&Lf+O!+Y79KZhODY1=y4H?i!e71HTzKRr3`+Yaf& zKIpVV-F5u%zG|iE#y_0s+}x2n^X8uqJD~I2gg8Tx;j|}>TDb-ijfLbg8=jD;R=nIF zt{CsJV~~zmv{`SIp5J}vjEt~9`N+O=Qjx9v_ou`M7j8Uj{<83m_dnl-;6rd3AK7b0 zNS}{yAKY@mW;68HCzL$-Z|Hv;q()qnyi)?Cq*qq;QD;!6s0PSoZTM|;u|ni+bWu58rNg^!6cftmU1zYe2-0!ilH{6__Qm7J zrT+7uw6wr6UmTH{F#Zbcjpv6>YZBovhx1vgnTRMU!S1Zm#B1J%1-4RUuh(b$bom1* zLUWimKG_r#k>|AcOg45H)Gp$6n}tl%q|2mBn7ZV6TXDNz-02-$>S)-1+4!iGlKjr* z>9@VTeesVEPH(&R=T~Grzh-ImtU8C@5%417QjvJh0hhSMPj0hUHjc|r%JGh==>PHJ zwfA3E-SVimEHXr{`Mkg?U+tqQg8yT{~uHW>RWN+{RMS5qV62rfGjS> zB^uHm|Ic-oZvFpT_vrtZs$))i6s!F@j7g0u?g`1PJ_IKXmYL*7ZE<{pc-yZlKmPa7 z=ddL%R^LQ=hy#N72N*B1D*91b1t!F4X$PJbv(fd9B8acRN3^>A3S8?WKFUcwP^iw9 zvr@DN;=`vH!iq`cWW1lXeh4lKn{a*?lh(h(HW9jsQd2Ffi;9cO{RUidYr5$=^P;F2 zb3t20+xCU6X5}AY9xv5YtXRKe+`KC~vSRgOpD|VM$%<7JI@q{wN8>c{-#O#5a+^z2 zs}}F?Iv1;3^Vh}&4URGx(TaO3Q0pIJ{rpqt7eT7E&oNMC^cvhLu}7`!Efg7R)RTO` z9|J!;ov?a`_0}k@YIy2q6)LP;RBAOjx%u9r_!3{K;mRG+G2W;cC>Yb*gRyTY&xJ0~ zoGw%_{*jbx%*jmrjW$N7S+&*KQS=5>r?93m=v5DlXiE`IuV8LtWqnBphazw3p39 zNPu6AmJ8B{8Sb_vjf3?p6~I${m>I~Po7HQ4$`iPQBH3eT>V)1EHT0qG|5xL=Y}O!r;@2Ytoa=00&B67 zGV9W7R5fL}HTYNxRdEBBk#Kazv%?|Dpgxj)5eq8BfTpwl5&HQp!znnr;IJ+DVwi=) z)2%!ZysECa?#kfJvikCxpf9(xplkQ6V*LS};h4Oy*IzmR%89{^?ha9{c(u*V$=)1W ziYJg!DbF>PrTtG@QT$M;F(qzg(w8wYc@vg56_iW&%aXTac?~wR^KsyE{ZMUsN^MJg ziaRMeCn=VwRHAIw?gEt@WUa}N^@#?vY%mMe0geU>khHeb^8=q|b0<#u~D7T=DYsa}@vDs9cNNev?3RNCopificsNh(*T{tXf$~ zj+{fIMHW@-dsb9oLD2rg9ZIOPVbW$d)^eT7uKF` zuBkcI*MHZB@n%thv#wI+BjLRNhL?>bd8my(B*#fzSVQpk+S!wF>L8Jj9nlNJSeCF`qZb!50R`%7{5U z9C!>O7Y6*WiS9fDmpcphr7gSprS(N!O+I5FYk6Jq)Yb~)2hNYh+<6zc`(G#Z&OW|j z40-Q=ot%>fpUY<#FB#?BpG^LG%1o*m;*YdI_tQnqmJs?0`9|DpS&B(52XW~*U%d|h z$_QGf(yj!j7QkDxfqVxv#q(<|@SUhl!p9WEf}~`=DZCho>`joX4_S6;21$r)B9Y4( z1&F!WMmh9YVNRH7Z zr=>)#J-Ny+HI_`4+d7uya&F_^PHAA34g{qBCmc_JMs*aS{ zR4oG;*+yssFfNnC{5`44WZ($15P~yCq_mm_<#}Ty>(Oq6$VAg37BrodFm~0roJ3z| z<@C*^E_>&~WyO~rU*yRdyZpM7y*ou+Uuj>(^cxpfCRQ&z^7=JZ8`t*biym8RZW+2e z+oI3yXlbaI*4G_5{)1++6lA7uO>iX}suu0*Xgz-KJ-6&FmwJ?xsF>n;H_iu9>7buQNFvpGS%5Z3^zRr~ZAgK& zE#=&fv&S@}vE?ajIw0i`=8W?*HjbEtLy|#BN8}({l3T(eh-{FkZe*rc|66$`F@NsT z4GqigSzGN}ctek#p zJ16J}Ojwsz>b8~6**9(6-sNLsHE{*?GlK2g7PJ)EQVS|lcAguPR9Nkl9;+XlQqft_ z(t-_z&R|JPp_NyJe^Gx58I=Kl%=~(LMnak)ew9afjujQDlif$`Mv-}xFM}Za8ntqE zfPD8H{*mc4eDy+jTE+D1ka6!-xSbpfN=HLJU6S55wcOLwvU5RIVaJ+g(cjm)@%Cv8 zPSk0mg{XgfXt3dmz(V($=Gk-FJ5!c!NX{?s%&*R9T-;hde|(8nV_h<4{H7^|6-AkD z^|{cGOI+fEywb+n;^LPY$0WK_43XZ7LvLlmQvvg-$}zvTHn#BgL`%i(WF(GE2qcn5 zdWHQCGvViho`GZeu--+M9mpa68~r3crrxNUzjObA#(Td!KFQm2?T`L+jq(fS=iF5u z?gmfS>ZT13uJL=iH&5{Qbrhq2q`!{piRm}LzIp4%uidw4%+G%w+`OnQcK2{EEPdi{ zdpfpGDGYZ`q)*77KNY*dh}xi9RU%4`r6C6IQM0Y!Xw><+1AV~*V6+wFJnz|A(hggx z!heX>{e5HiJiB(!e;w}ZeeB%P)j!%Zj(X#-OE>iQOyAX=zhh(ng7!|y9wB%6(mR$P z{QShM%(iut^QJTxYnL>RDXAQ@W?=HxEkt~b-S8N>1-rr60V&eYkBV{yruQT2 z?fwK`u{(Mcn-lk|lfPMf(J+a1`6u}^7nTb0$f^m^I8ebZf_4-q6dB^PjyW9aM1#m5 z=Kt^*{}%HTHz804Yn&M85q2j%8dJeVT<>o$u}4EYtB|DFtSWDq(Nh|)2;7D-Z~?=c zbBZcmnR)LigVB~~vm-S@8{zcgZ0U=0A(F(!U_am$$%u+Km zy5_H_T6A(xk6j((QkIBGw-hYibnT>rpWHh)dbevqOkMxL^PgSYv~~F`*UY==Z+ziX)BX3{fI+3#YxqJ8ZRu~e~;?Et7ix$pD zrkQ(gSb!K$a_DvJs||wxi(nsVPzCDKU3I?Na#8NX3?w=6N%J1bH`)V;ac(*s!>a%i z!V$#-jz|>fmh8(qzfKokZ-3@7`d%s9|WR8HufzLeh*T>W>X(8yTNsRZ|a;o z{(fryU2Tg1XUJ(W$%+P%?hT@&SD z6PML*yi=nYI_8}?uXJ_u4D>B56?DcDmg#iNiHT}kx*Tt?h=f!FZdHKQTBhR@bifh+ zakJ^vJ(>-mb_+YAMw=1q1j_|K2aLucHUaNdgag+6acEtmc+RDqdLu{K_|%68;O}|B z^}ruQ%YHS^e-D}rmROxy?ZLst=Bu}!n5`U|FV@v6uf6R(;Z>&(EtYN>?9EEgccd7w zQ^Pfloc@F#QN2CZZbK~AIFn?-eL|5Vjp6f*k&5EHoe7mhyld1G)x@br?4NKgX~!Om z8=c=R4W@`P*V+4(-C7LF<7^F&5*KC(Uwv|F?m(6?KH3{ow$^x-w=FFkr$r_9b@z+d*3M@RK{3@+xLZiog-2Y_eVsP zt+O|z7Eh`#HH%i4^2h|`h00B?O~n^%jMeU&nOtg>-qoA4YNwR+o>-*ZB($y*u0M=y zjjdZBgJYE<^fkO)Zo~Z1NaI!|8ZuoCuEs29BR+cnO@(UPO^B`+R-3qz!@PrfLP)aa z#9^({Aw|OqlN$#X_%avL1wnAyM2qND_H6Ygy&!A0nwA|=8Y8yT#8E&qfMJY9bm#h#~BT-Qe@&1TuwK zb)wugvnsH;w@w#pjDptU$0D6>P)a4OB?Wf2r1+$GweC>jd65>L6^CtZWU}ENvEvLp ztBqLK;kLng7~wdm-@mi`(}Edlap$3 zWTbot!`T7lb~pt}~qhqet|Rft_n_$!-blLxyvxq$;J*TE#nx6b7m5F_`pr!N&FH}Rqnx!?Tex_58x(8b&0u@R7Fi9UG8cnX=Tev(4wUR!^0 z$XtoMz%@0XdnRNrER*SWyQVnDP>c_5gUdKXvk8aXz?r+VM(oXEvcrMsktGuk4~VE? zYvskpNR4LjzIFCe^RVGDwWhk<+9q0d2et=`gWCcvl4-~|+6pP9N@Cd9sEfD6imss} zrsCB9NiB?59v5F+WO)oBEUbnsj|Q^x#hYVQS{WM*QRI|IlLfo53(Un3q&O4^qBz-& ze4E%OJRA!FD)_IIXZEXyURKsir=|CY4kOxu^yoKG4~Ez~?{Umd^Y8|p%J8IG9MV$E zlwSxR`0NJh7WG1ukDFgr4fWP}_SN>CcG+Mz>z}s?n>tG1g2T`Y2z!~>W>?$Q zk}=M#rPd+nEDPNNgfKRqon2ZAz%Bvp>?24knGq1152g-_6Y(H)&n=GsnC`*&b9`S` z-?~57C|}lmyl$~HAy)Y^R@2>#|85)lK%^`GBV`1Gh;=Ee)=BHs8`S>|t)mhaq_X-H zO-`O|QpMbgRTb!MOG#c{&>3T~G^vtAlFGXVyn!gZ04y$MLx-crlEsV-OHfDIeoa?l z4X^9Sj7if$x}*#50O~3#A~QAnHNn$&L+Q-#t?RlxDgLgC z9dpHB%lmI#yy>N@5r0tpReC%nxS%z+r7T@MPa~@yv&EZus|)rKL%PN&$2iT2X56kU zQyb_%jC?R)*mW4P2`|Q+mw=6SbQ7|9?~k-zh=$do?n#5&9+jMLk}^cpK1oCyvP}00 zC+g&01EY>Mr6fslD`nVbxVPnKcjMeN`B#J0@pYwRm;R_zPWooC+|}G{a+rdBg>)A$ z?V?JLp?1923Jt|eTOW8Uh8J(?(*_;sEf0o5F{kic8EhlwQdws#NK+edsiAB&8zNE2 zhDDeIRR)VW!A9XmQF#^`Ut!naky9uR1Y5hW=Attva@8J{CCEq#v zsEInpGcJAb8qKZWf8s$- z9}QB)cvFMcdSzv2OF6)3c%vY)XNPDu!;%8Q4H1!o7r1unKkida_znyNyF_?Ej!dEc ztng-iX|c7yT50d7SPbvKu2*-qZ=ZoR6;&yB<@QoX>{j~DNZJtN%7}TfC?2jmpB~}=o6Pys|B^KV$i#PNaip33O$h_Gb$m9Vh1Ygo62`y|=o>0UTm3(y`m z_GE6%7~k3H%9}N*T-^EoH8ov(@1Hqoci)6W+0nIV^Vo4)rg@WU7vK8UbxZCKR$blh zUo@>XdGL8_U0U0kDOE0Gr7w3vOI@nko}MN4C6~DEx7;D-Nbe*#lj0JK$Ck*sE%Spj zZ|L=9)y=5zOdFF|-h0DL-wih(-Z0i}OT*=G>BeJGu|*T+_0DmQpHbYsp;g~9rE};W zQ)W?GUHyhVkQOtZDPTwQI zX?TYM4Ymu5AMrwUA~CLYelSI=3Fxe;ImzPgX}4)KKBY*AVnvVxi5GB;vBXu9WzXl;6f%w5AN@@0u7*azVN&+Ln{vrMxJ$E__L6PI0GT zUHTw2!W8so9{RJQK0Pxk%^V$tPuvd84VoWlWDQQ6CYBz}#;pR0!x}ft%CHL1QV44y zngaP=fduS@4{w8oI~8+OgsC-=?gJkWUnL-2WgmLbHm%LoJ$-6UNk+%)e*fG9{f&m( z?VF_;cYJV7_zHoUSIsCqe~G}xjsjV2+3P5fV@&bS7}FEui#k^}?A`U}hx%}Bz!}8; z&C4!HtDH=lZ4$<6E80~KIqI&rrXDLS)EujI;A0OQEiuL(u@AQf4LKibA>5Gj(|Lq9 zsblO;wnGyy(sVw&+%B!qw1%%nFnc@eMz!U#dzY1t?Tmh0R?EUS_o~j6Wrtr_Lv2#t z3b!ZriBpk#5j48Y2A?A?$(isMYE#o?w@%Y^cQ{-zwsd!D-SW;7dH%gyn$f}_--=Mt zNqc{h8;c|@ylycnLmv$N9(RD#Eqh~B-Kws7{qY2mEH&X~jQ&V{s^#i>lfA9FUTTRN1qEx$KF3A61!pnMKv7(49cY(#%Pu=y|qx~@3MW6I9In+b$(Jf22SN>e1 zIrpR~(V&a5WhEx1MOiXvzAZ(hra|l_j#XvV8xtg{L_fBwsVQfyDq|prc?C)z>3kp% zc%B6lttjEG&ce(I_f2l(1s)j|-oi${T^HsbXoS$wrDx(|Q%ka}>G=~1YTf4Yo-NI0 zuN)nvz3A$qapt(>qAW{h&RBO%UV?AtrY23ScB=@=t+LhONp^T*FOSXl*JZXYZE<~J z&da^{`XVt)wq_M2J9FZPr_*$x9Yz`HOhm~|Nk5J zPi%ygpMvkV;d?JeP&K4{LUCoKEh&HtV`7u=k?n|!BS*+GED9p>VANes;Vm^*8^dJM zjZlf@oju#T7dq3ldAGuBo@2j}WCCFQ~~Ace#Rj z{*lX@=9z;Nr+Zs=^|#~lBjr6yaQrk+>#n5}%suC$N6E&F`PFrW&sOCrf6kms62b`0 z_tzLP-MG!Iv_54*=0N9yDBOb*+i7elf)9Jp;7iC!m~%8dnM2(QZ;fCoN9+WWdZd`Z ziGFwvhZzOo)Udq}_FBLq=sVr6FmA$PgeLX~)A)7Q>hy7%6|R-BIqyC>aYd^mu;kE; zMoEss$&QLi`&Lf0;E>%Y)%lVx?ai~Q(zN+&_ukwYT+ouEG$eVP38~IvUo5P927g_h z{Y2%XKgw>LRnfJ5YN5{P&dH1}4wO$_Uhy9s-Lo5}`|_r?cwEg3m0D|#-AO6jRF3wPceXbcTsJf{(saz7-$3S)#gHU! zb-k-Pcc8&oVQ@q@8Pu^4j}>FW4lu;0l=wum|v5v^elo}I?3oJ$MX>;L1SfuTn)magGr5ksfO@2} zu<*6lMw=;4*J9B~4=VR=YHZWS z>_l|yBjV*1dkf{bGF7_KVTwade_2-d3)*SG;79C5lKSDg;#9=>`r2_h1bL63sy121 z{O4A$`5-Pm*%YpCfp^ibk93Txv#wmZLYtV9W;e*vKUe7k`*7$;-KP9+T4Q5fO1Rqk zEbFGn?W1aLts7jI;;C*JlM$B~r~IK(+Nk{PuI$=Gl4@48VGr6sCn!AiwzwFN)tQ`W z#kFTKE;~-9W)H;2peaAa;^e1cdp2$H@TpE+#7xY`JWz2*_+DNt>B)>i?ScyKbHiS< z=Z3{$fAZRX&y*LA6#1e=u2|&At(@slPGl_D_wdTP6-8}IR|A5Q3+3q)b=%`>eiU{p zx0;teU%aJFykM#Hwr!hJVYkj4Jb>$L+jMa{Wl>yYeQ_G2sth*CPFi1RjuaW&kL4k> zLrii2fxsGYJgX(*_!?eg(dvR--NL%Y`SrypQw*;zA}g$m9ONTw3pa+J_U>;lF4mk3 zw7jrm#B+YrBZ2%$ljl^2R~8E{bf6c%p*6+LKakb4FR`d-3RX9dc-2pAaaX#Gw4_k( zxWKhuIZDfk+IkVcdK-)wSaID2SNArSu~SrYRkii5Si_9z?INg)tEuT22pC(Al^17b z+T2HqjSaAj$HmPWh^EQ8%zJ(n3Ias}Pl)rTaqj7npu!cnVU?}6yww~zrAh12aQ{aZ zW0nuC}$F#V?$WRXe9HT-VTlV5YnAm{7kcnTtB> zT~nt|%PtAtx3ulD>9uBc<0~8LmwLvYOZS)Lbu^X5F1UJ1j&!RmCS?{hENILU$A$7t zl8Y`yR<}J}b4%w{pFX%SGi}#jEaWEbo7`76=}O!xrin_gFVAA_Ijc0iv>~f|PGUmO z;7@Z(osF}r5(|S%k`lxTD_HC*T=u3cj>QeiOw&JWKLnTgRZXf6)lA6m%<7|Mwn@jP z)*sV&a;GM1rs9)6ZXnmzIgpO^LPFS)V|e2_fUQv@jN`<17T@?@>>EPgV;Vr zM12>z#%{T-i)fo#+MF99ZD53Y1+8VN8RcX1#a;>sshzcuq|9&x!E)S(f%9%Lg*u80 zmw}LpZbVBQGjbOKlZ%xlc-LJ#9CgFWab%GnURaH|@_;b9;;^7ucVA`8bK6D+p~Y!x ziZ>E(Olc0xY|M`_Oh5G2HJ7>+VfX@s#_B-R$k>ylzsqfFDQ=>_XJg&GC-!%L>nen> zt>Z4;G#+_vs>#q2(_`W$)=y}tu8h(L0!;%Ih!UBOGdX6PUOy?^={_!(^!I_jJE-RQw-Ev2{-COV^kAhB9Q)Zg5$N zQsPblVVv$HsXR;-t7X{>;`<3xF!RyCVdV|GMVyF=0nM(CijPuyXW0TGD)2qcOqbLB-qH@IQm1>o!HU#T!le-+3rgXJhZ!4 zG%O0vZFHvedD>^6Yg%!vtZ#!=yrJY7>SwKQ?t*Kpr1HSmWIS%%%g5{hdv&VusK;X} zJ7zJM67mLQ_ATMXD{U@obXsR-Bt9Lxslw8W6)PRspvhYcjfpA(og82%wK@hj>cOKwS~Y+jK?C0y z6V?E6_L;O^I{e_5elfdwY+9dk<{dh%H1D7+G%aJVRP1WibN6Ku&2d^&{V-%#F6{?p z#KP=|`v?-W1NZ{sKB7~y12rAB3iHxvojNSg;U};#DLbyFbfRZYo~hnhJ-4+q{#$1^ zu|@6Z@Z@x+oF9Y&+g zZK%UEJ52El+jIfp5j*AEOT^J_LrmOJYe3B{qkCk|j@*_1sgc|{=e`jm13Qq9q6&T65F{?gKbIhd2$7YB(M8-0k$wqCAy6LL&h`rAt-vme9(v2QF7Jt2132i6YVWM%|8~TIhL%hqSD#dA8ThuXY zc5AvdJw86&DyxzVCWEIHl7*NV>b92*bQJ1H!^1f&MK63k_#~6`aSQl8a+U;RTK$`q`azR$cMCQ9KgLA_BWww1m~|siwZC%V+#t*sfO6>^ViIo|a_U)@=cH-*1Xl$a@Zk2V~;mczRrO%bV3onYfZrAW`*>gr$R%%rEb{M#| zNTJ8T$nG*QuN#C2;IwUfkDtMWv4OI?LkIjz+dOP|mAr0e2V z#Cu9hEuV-r$_;adzRW0Z%}w*iduSIqyjPipy~@cn9-Y{Z$ZVcu3_wTI4P;{Lt2B+z;FgRz>_|+!@)!O_$Ui86&X-{==T-w{|?^#TDsg z&AEtdnUYr4l9!EtrSXTt8=Bv@hZ(*C@q*3IW>M>|^(4~87Lk8xG`T|W>8y}bL>G*v zx;jwBR+``hVT{S3j4{DL(HFRX(Zx&}^eraiQO2qZ3@&V*qU9j$5~J-{I)P1KQq$Pv z37r;ZwGqNx(jqkyWPu5zyfm^E9ItF2O_-c|Z;E(ggfJJ{6h?(xh};c%iq9RDRZyIU zX640;2_saq!1YaP+S^Agm5c$G%Wu$^oWH3Jk!^Vs_}kpggu&5aKT8$zNsX9Tu&=6q zR(LhalNUZWPe;*q2_qy&xOv5$YQpWx?_rB-{K5bgQh<1P zCxBn?yL1?a$sQyrG#Qfl>H%n-o zJ}D|y9i42j4VX;P+)A`D5`#BlZ^hu|2nui>#!*7LG7vT-9Q0H_E)LA~NFkd(XI!0f^-#Mw`A+?e$|P$j`CgGL zJBB{}Xy(=ljs*0=(a>o%f*`7a+ z?gHAD$KgN>E^^ul@7Q0|0dj1zb4Dq5!1zUh$}Owsrl)EQ>BiTT>%`A~C+1Cw!8Iqb zxyGM~KIPcO#FwO=G{-RQ6WjJIUzFstDt`kreWUy%xyEX%wh8m#>lc$=C@sn~^=oKf z62?q?qCu;Qv#3S9L7zhVm%}^t0ClJDb#n5BRh6V6 zMa0_6lTe?bR{7!4^#Paj`$y<&0YPhW41PySs<5inNvQ}_jcTxHhxMwg4%ch3Yx1S& zOKkrCK;KK%`u|AaiyQQ90^=-K9(bE5oQ)G}#*8Etln9q0#gH&yOqF;NW-8OT9U(Gp zL^5B)%VTt#E+Druvv}H!*%eC*5=)9Q$Cpc)-$VI-1gBS}g1wuA(q$KPfe6imX7gLr zFO@Wz)Krt%U^j(hYC^6cawy+H4o7Sb)kF#)&K+}|=-@Vzzf~ssR_wgxeCW)D?ygtF zgf_L1)zPWe9n$qfi8F9wE^@EbF8Q0G16l1!Nn_nZG?)EAQsiefZ$s%UP+6Z!ce`v+ zrg*rQoIP9m9{vYe*wMyc7MZR6Wsu)IA?civ`Ap}mm8EgzbDDEw?v$kZqAQ9|S{r9? z-1V&-^_>~P8P%DtC`(jX`Lz`3e+|M{R*lYpX188EEXQeH#tIH`tWwqLOoz%EpQ-Zx z{w&dg_5x)(P>vmZOcY_F@Np7Mu9!pMn(nM>5AC6TQ zyW`578L7T;MRA=U&XINAe7k&ge7VEj;!77IMY$)Cn`~@}FLzRga;11y1ah;WzYEok zsL}JNk)3K}kB`T}KM{+3FOei%BjJPxC3S@#6#`>WKZz$koR{Fz_C`5Nf{yYJ>n&ND zg;CDp>I~@?@sv6}#a&mJ2v;QKr<#mpcP-NNu6@#exnHAFWx>J_9dETdq;xgd6Opja zmU_dRu};6%nMLP%D*Uwj7LG(uJ{3A%;-d!A=N}q7Rve0P;6!IiW_G5nIjL`cRF=AU zjCtIL(rumd4!DbM&azu9@kce<@#E8Sj~h)TQv^fOh-ZuJrUPn`cwq89njTSIcXhk2yjb~(Nqyzl zJ=e`E$*P~TlmfD_unXYf&z)y<~2QQ-(4h&>NiG5W2A{QdF&U(|nFuY6H+=4<8jS1;8l zU!VrR5n1O}s1GUcp`?Da7WQq%f zLqZe#LWy9vU*S;eln<^?tx8kMmABs!j%)12$>KHPmyYGOWexocL47x7)uu_Y=!ui? zTz{0_1uF$&1;CU#G(i5sfhA|8w_4mMU5M*W9d&K&Fa-@JdlLrMOH$Vp$ge#hF`N#AwFnLwTY z8bv2?YGBQ^mYY;jYAGn24;IO;gJ~9nnc~KUS5;tiFb}E*Zw4ogXw0$nZ&>m{nIX|f zm$M;GMgp9F;FPG{B2txuH_Esi69%w2Lo{wwTrKte@Lk8mNt2ufb5>p1S=8;UG~_2X z_Ln79*EQDHq)1QikTtM-$uaS`SaGV@EWJEbEnbPq$Vfvp?XElNHbQPUuUFq(C@ zp?}QSJI$`QCf+WqjIv3mlT5Ph_845FJ={YWooE6LaP$!@CCo?Ur-P1yXbeZb)wENO zJUQX)o>y^Oj3^O*S#j^W#uy=s&4XpOVdjI3S3{yW^NlNrYKz_H}oK~u=cl* ziiJ4y=dQPDRc=`-Fr=13SGVJ$o|+?i+pspnW(DS(FkQpEg0Vk($%!h4wcyB6-r*R- zniL|iCQ6;X{Q5_i;=&#{L45h`n_wDOc6w!fLJXAQ!KIhFt%udlxHQA~opZ`#qZN;O z&xO~(6wkV9nlUp@n3c`Lw}G6$wnqw`0{tl>ZZ@I@!Saw4JHMnva|i+Ned3TyHk-AF zqWKU3no9B!3(K%)E=fpyz%vwyitZ+06L@*V7szqmS&CFAokh_%iMIlZw?(p74&Iek zo!0p1ii-XUtTlXbl1z#nc^n+A2`mo%iM`8+4AfVls{I!R-RM7*)R0_ zpPlvCtc9;G>bX8m9beV8xO(0_o0|XOs_86r<7$nCuPh{Qv6tY(xfi`xjoq(FIJcFY zm)_c_IX1BopTxGKeq-=hnZcC+pFfCNSm7`WG z-7_(eS+M+xYs4qn-DTuLH<&tS(X5sw0jct0S2}I9CZo1Aea z9Qasm@LCR^;|y<|V+DfI#-6=&)5JxhTZUHvF*W(I*mZ7nz9R*__U|6WrgiNyz>Wv*q z)OplBpP1t3svnzhS6#ca5p{feR1&DjHz(B| za5z-b!3^1YFwWvTSWo~VhHDT=*n+1>7r`7(B>L7A0yUNlO%g@61#j`>LM{ljnWKJ1 zdFCtS*WWXR$XizAUh%;_b2h!F{PZR7vgM2Ns;58Hz2d1o<4R^+K0aA}?RQQdQp+`G z_r9R~*Dsdp3<>cf*_qX_?dgqU*S6=;Ork8-t_Nj(D%=X?8%R!8Nrw{+mVp>s;bE7H zG?RE5YZC-!eZP#DrhrbkUf&lC_}#K`#v;^L$O ze7&XGoOuvtAks+CH>@R6BHTM+U6EMhyL*H~LycA@aS&~V^SgT>VOZIeg39+%TxA5s z4}s!2RA;>*XCO9KI*dAN4eEsS!#D;Qq4~G!jQSEg(`H}Tn#(Kb2(iCVUYapVb)6(? zrtJRtHEkD@c;|J)O08I@Tqf6FcGpFO?b|@{2q-p`3v|_Eji^^2h>{Uu=zxmiApU}+ zC+XXWzJmIYQm2`%d^F`x{~G$~Kb6zMt3LC;&nlb6UiHp%J8^L|MRkfpRHvVy#o^M9 zL_;;zA5r0?_Qj=9kEnx)*z|{!$}z-Bc}M=;$-9+n#d_H>_`X^-_&)WyPuZ+_3w29W zA+C{RJ&47V-5jewfa4c*js&q(X&BPV8mewtripe&BhjM5D_DnED4I5Z^qN>36;*Zi zdQ|?OE42?C|Isdm77MSeRNhH%%vSzR0jnfkdeZI%LwC@7`4L5) z5{uIlm((b9^9cfcEaoU?c50`5z-kpX*&@e-y)WSE2uG8&;i%)Vs4$;I_;*8M&+hvc z&z(?JR@=VFDqJIx&W1i)adLf)Lzq%#&(+KiM?DkDE7+0#8Cq$fx0(&oVUtN14Eg~a z+CYEN5F+Xhk0Z$uHsjDaD&oyB7p|DD?48x-E2z5M`6(}?z>Q$LIAulRKa%cLw=4Sv z?S6-rDH~%`(33&T+P?aiom_3)Y6U0 zR0navEJfVIwQyLVewd-xM#O*ka%Gr!Fq21L{~dGIEi`Ey2!WZAh zEOyWT;7{+*l^25=N{4QVmf@lT~UNhdUDu8AlS}^qqdhppQ!!p6$L( z4Rk!uc+7c7Tgp_Cexb+)7N;cZ9you`^-SfHf;)F8O2^Qoj-l+Q3CHasbc2hI|ID%VO=#1wHBjyPMDCh_dx`%)8hwGioG=uOQ((VI!IEV*&Y z88_J5vkvA&8O~x=%@w43MGOgA^ z@j!$+^!oY!xkL;yD}a12mRGIfc{CKe=hc&tkHJYVP_(055LbS zRmKsmOb!meWG2KhPSpSNQYeqv;p#grm#97*(y0DI2ervB|9W7hqSOvesvTM-;`8%k zqH0BDHST2=H;MYeP^?XVR#H_p-z`d>&+Eun-!L>NvX$RSY9YCn)H)k;M6&WXt2f?a z7FP{*3UNkQ9L3`9r?hDaWW$1%vROlSw>Zg*LVeI7+YTBm&ht_m>IsQN65E$nPBdkZ zgrEK=CFH9YSh#nCx92nYeqbz!>Uq^ktKmWVN! z)}m?+%f}B+K6LBBLubbLiZa|qbNaW8mp*=x66lG&!WlU{q?Xl5vwxxAHm8+M|TZlV?|zAv7xPf)8zcIyB_JM zPqZYHmIcVk~I`H`~f6}AYYnA4o-S^^bIaU@AzNO6& zk6H7qLxXa%GT!Kl75|H|Bs#RRoEqJM8IyLnQ|k3{etv3dw98Oj98JY@3wmX^g%)ch8;?kd!NUBCYEOQ}LTkNaVtb5E(idE8oJu^aW${Kx~K!f8#a{9@E>SlP@^8e-MP zIBd?N3nEnDE?{K^gP_b}kzZ79Za6Z%rYy^oU73}?^7om~M9m&LwsMX2u5^EcRIJ=C zdNDtURBe`86CK1kRU7)&pwXxV_RvQ6Ey9YE5*M}$<9b~3d~%94SN+Z@?yc$Fwk^15 z&sal#UG1cK+AQg^dzJSWO`EiFQm&YLrn$Na>cXHlLnF|86dg1bwzFu94$?$p6{vn0 z*PjjI=s>|{=*UJfy@~WLr+UV#_q}@V+D74WR(k}n(luGd`R6&M$j zwON`6K)n*^a4|+hMzI=u4=~}u&|Fr=D3PX|o#w1YXSH7~VZgqIAi;W5Z0Y#=D#zJWUu9kUyqf214*gbbR@Ze`>};;w)I5HR zf7;F6@1#_w`8T(X+gwrD)zMYhvSaVf^E$8DwqYy6nJ&!#IoUGlR_Ct~vw=9B?6ajf zYe@Ozlj+5pe&kkX+BeojVw*n-JuCzBOd;BbTZ)QqN=D>z_Ld$Pl!&WEGM zL2bccWY@(abXzUQe890DT^R{y3{fX6`q*-C%a|o?w$YK#BNuk#vh=}ajxzIK{1tP> zb(tlmFMR$5k4f{V`EdU2&+_ciA<)B@bmPYK(%jyF7-MJ{>T=JiP+l}Nh`(*QGgEnK z=v7g%`F3gx+Nkb98=+J3tm&b)6tFiMY{LOidi%SN!h=+K^Op%L zh340`b>j^U3zA;@N%LI$i=oi)$dt5kI4X_4itsc3#>NKZ!I0LZnF^VlkM1r5a`4060S>mRExdLd@vC`U%o07~kK!X>k8(FYsY(j)9_fXtr`I%J9T3&hzQs4M z9Gh<{U3qHT?jLWiGUYY(?Z2$J+7TP;tSKq2b;iZH8lBKS@5*5Jl(V4Mdc6A&41$9?%6)|%Qah`-m?CY_0?7D9$a_% z>20-`PgLEZk2US^?3$=rrP{7)t#|2uxPAM|A12M2J-e&3b9$j_;>5y*E>~d^KBlT4 zj!E3`Lz9*)WnnWJbrS7N!-VMA z1!<{5KLNMuXz<~T+OR*$NRrJWv{w;v>A@5Bm0EXYtGnAUwx`^R`)b?9%nBsw&0=ZW znn`)ynO96UXFJoPGwR*WYE!%`L6+>EF@;lZ2)Z59dS<$&Trsmq9=jn)C>e$NPVD|z z&G|X0nl4#NN=hlrG$ng#UCPOqG|>iYQg&i&eucOPVQyl?!Ggw#S@j!dRb*67@D%#G z$qAwP>Sc`@Ts)VSoSFsiVLMJdHs_i0y-!VpHOh-O0J$ z1RS~1XSy>hTHV=|*=7-!=(E`~aw@8E)uV(#gI-d-`WKaO-17o%6^nik(xDqS#A#Gh zLyrSLVmwDEQYc@fF=lYiI!>?W^xL7CDveZ&bPSge!zIM1reWTR;c{YBR89<+6T{`i z2r4H=P&qMz%E67&C?|%?(W@qkSd|{j=2+Z!<_a|eJ)sU@OXyl)D`OkuIL0o~ zB;!*+qbLi#4SXx~p~@)vkv8#@COqjtnw~VNoU}yrc2CH9} zY8rn#BlIhzXL7m+^>iV^C6&;}xCD`NT&n$`gG+Uga~@_q#rQZV<3fv^z$ZEV6sMoz z8lL8Nz0Oa*!T2WQTU_R^8Q*67BiH9se*QDA!&h9NK}Lm8Br;}FyM%+&S)6uq+QrB; z5xG>F$Y*Tj{7%NnjNOdAL@}|F)2kUbaA_Mky@_!PLo8Fvy5#V$@?LA4dTskUMt z=Um6%?&tLNoW6n6H*)#_rw{V44&hhX=)o_6`HZEEK1P4&F!C!ye*p$SpKSEnWyaSz{|&}B z8Q1l9peUQa5<`t(0p=Kn>l9- z<5tGY8MiSWj0z$1ZH{Q=bSL9v#%{(Q zs)?AxIFFHdGDi?k<}hEmRR%}^x5~tr6}lT~SLhue@rfH8@)EEr^c!F`r-PxRNY|i- zZq)*QvX}7y_|UC-fXjK1a~@(m&Cj2KlyIZR318v-R~i3E~PCv-_ z5aTP1uM&zLdIr=ZoX6NpZxK7GWN{ti^^7+H^FYZCpox+AFb|Ym4D^6M5xoO6&*K{A zVXWPU^jLmo0YB5rcp2xcXWW22fIRS$2e@B#H}F8H1o!}#{~$mA5aXE;?&1P%318uy zR~bL#H-1A13Zo{VFrk*-F48%_nR9yREodp>JjPzCv$%|(*~8E5WxSexE7c%B9~|-u zFu>^`BuT!ihttn6p5~m-D2+bFlju{z4UD@v{}9jvx?Kx2F}fhTJWMeUs6^i`;GAB@ ze$H9SxQuZ*;|fONZ4aol4|tr@4{(_e@^2qvJOk=^Kr4FVE1dHxA?QP>reA?dl-6>( znbR$tCYpG_d-Uy9oU@nHS0i17In)C*VYV&8OiJl2^k5NW(NSPNqery_=~7Pn7>Q$x zz@_wL4gabMbSr`$LS@qYQUvKlIF7N4aSG$K&}+z_jNir0v)-bMRT*r7BdaX#c9#XbQwSntQoLK}ZN6*t- zR;1d>NHbcIY8xZ*Z4qX6qQG%}%fp;L#rOz6^9Se~)`P(-b-(>tFzw0x8 z@+;2yntwaU=^;)loDNYM`WRspqnYqu!nl?3a>i|p z+qr}tj5`^3F_LcS1qTuZj&sgQe*S)pQ!i#-%0I>U2!n^uQA(3u>J=_3Q{*s`Ug~AN)GL}f-O8nPGEQdfX6z;205?*}s~I9#U6gwUdDY~+I9ToetzW6vU|8dA3ueET7g^pH}_5%hd7 z;{#mIgPeYd@idot2D4`=B>z6(E1dr-BWWO|=n<5LSpelg{u7cOQp$QrDeEDng7lD5 z(ahhH9#RTA(69Dz&R)iY$SG49lzl)GqboEH>3qn{GPGy~(2r4E2K|I$SX76e0S3|1 zGPLC(U=!$5hB0^_u$8fmk+g*}j6}-sVw?h*U&gE8GEjit(#zP-B`jrJ#<-ku1>;J_ zRb0Yq#x;y<8P_pxX57NKmGN@MZHxz$=kTuMT+RdB#s~Sm4>3N%&z$BKo#Ag^R<`2# zSNPjk8NcRdh8RPHkl2JWeT!Kb6hJRfTFdDu{#MTz$C$*}%+Iv&GfX8&Y$~Unv4fFm zg%vmDPi5?-UVt2?9Bw-_I`jqlk=}R}m$sMFS9AIre)2kg=6c2(fj;J2A8XF=H9_zD zm{)zwt3KvcAM>gY{d+gQC0_NxV$}mAj`cCe`dDZ7sfc5JD&kn5ia6G%Is;zyF~|Ct zV|^;(Sf7eG*2lc+V_x+!ulkr*eax#q=2ai_st+31VLVS<>VwYwfvOz3iUdqo%>k11 zz+EMbi0zJaY3LK6kCAw_9QA(-*uv>n#pb_?TH#>*MEF_Kg-SCLdNSCLdNSCLdNhdiemKFoNE@ezLhG{5(C z&Uu6JO~y~T{$Ft$zvem*a(amCtZ+I+Y49Oo6r-M=6me8fth4Y&Xbxy8s7=pgF}Big zMH{Cl@RRL~9gLm)Z5Nj_nbT7^-OcH#obDx>LmE^0tGN8toLQt-w$qI0W?91`c-M6KLXPk;q{NS3wpI5ymT0t&*;IN;s-BLj*rog zQRBzzj7lKs=f~*y5*Wnl2~j>mT3|~k9@xs*#yB=~06F70-4TNHRCO|Tan58;PvLYo zr>AmFrgNG!6F+D|HJQaV@8R@pZp#9GlI(AOa4glckFlR?vXpTd<8sCous-=!D>=PN z`5Nif{N6Q;YZ=!uUdEK6b(|mCasaqdMRnN3wc5BWcsb)X#_jyf4#u5~yBPOl zwE9&Cls^Lxay^f8O-^zf??>9KQqWV zL!6^r1+bN|jd2_!&He$%3c@bV znat@aobKi{?L-8yilJu~@Y{PC7lz(N4(_i5_VZhoGA?6W&bWecCF3eCb2Z}{#O9pt(l=eOS(nui>+ zB?eRvFl`^?Ry@S`Fh6;U@ewYctcwBF^PF=AYn%Z3j%fG_KmRJ@>-_B-jBhf2$dspD zn}F&o?u)PaS7cub@cv6cHOToxoUd>?L}`p}LYYd&=ti%BLny7~bQFK9XQcgzfJmVB zVssNGaZU=S(-_He72y4yfS}PG5Hz|2BAdT;Gd6SiEnI#p)dX`il{|s5ow0+llfPvS z!HA|OnL{w5DLs{+>7l;Eh$fuJ*h`#=5luDZ-iIbh<&*v#V7pm>cbx))#&STAMja5O zO9upL(E-8zi!n=dxQgq!m(y2s`Wh;Y?Q8+wv8uw@*^F6}?6g%pc5tIR`UO#3U^}Y9 z*f|NLaZ!bFaUZY+y$4J)8Dz*_-@vK(`o?nNY&HU{a#;uH(Gj3xf8&MUw`dZ*|e#@PZS5?fk&25kic8+hX|lLhLF;=3RzljRtA-qI1d{e%4QcsDU_PSXir%jshzD`K^ZtccYr zvLaTi$ck94A}eAwID~K&m$sU54dYtIb&MOi&YL;Cg>ft6<&4`H5AwUnT3D@mfLr=7 z=bU1EgrA`uz-krQUaDbxAv(Oy-@d{4CgWF(gNzCxba=u{q6zwuu$6N<87DJ#GxkuK z=qbW^jJ-r#Xz5hKYQ_y*!ak&f7@JrlVQe~pX;`5Ip&Jv@*bHK9jsxbPMM3lwA?*kR z(NmQ6G19yi_*R!eIUs8fgt+yWu*J~z5V>IrHsoMmt!0S(Wf22m7KGR%UsR4hH)+9Iz}4xL5zAr zvJ3}#rVC=GqxWv+XSOhIWxSkm8{>9~-SG&$7C{dh4xv>Zz)ys-9QPFs}4G){=3|cvI)GKa4{&gd0u2NxtY)GN&C^+GhG! zj_oJhCu5Nqhn5I;n|_bnD>L4W<8(plaL|~;=9ckp9OGT$hmHT(_+y4g5=O&>v1W`z z!%&}Sn1n~=EzmIe>u2RD@{GJS<6U@m@?q3Vnsbb4k{R{JG3xPLN4;^#@MVNA^sm1y zV-FdJUdj{G)5oEmlF!%VWI0vd;$M{a(prnJ#);}`)Gzf7)>wmTXxW&UH!9IMN?;=9(;ljixo z;%S+wrX0!tCCT zFJ#?ca=T9)NA}UOZ7pX zWgCsRjmEQ+NY2z`_;uNwl-A66X75SA2L8V1QhwiaDHE{m@500Cb=2g9(v2g(gtr;K z9UJ2W-e>@3M{EK*In0jO1axvZPi9AK0;6i!lk`Xv?eE7lM}7OiPqsn>u{oVIMF(sXuVCu;!4ig zQg{}&l(0EZ$6A%}qyDuDZz$Dc2fLwk61Z;(T)43m?RO*E?;2P!&EitZvkFPMQE9o+In0e(`ED$2=48l?tiJQxF2h?4 zM}BT}CUYY*nP&+1$q#(uhsn7(KV>T}kbh{*YOk!Vo5^26jP5l<7olKp79iC=5bw1fTpNy<- zCp?k0-eme?KfJ+k@|jGpO#CElK9iB6gtK=x84Gp;Or1}r&J&(ZJ5Q#b!*81Bee!-e zSI(33W%kr2BaO*(p?p9tl1t=LxlAsXE98&NVZCqhqA`c%$8sb@pOe4)iIdUWi8)1% zmcAo8Hu00?ROvgSR}()|E|8Xx8QmV_J#{|SI-hEt-=ehNqO{-QUvKfRxA@m-{B<__ zPAAD|hG}SqeQ*-BH;wdf!Po$&Vei@x?_hp1O)W7^Eip|kF-{6U7`rJ8Q3rc=_8MNfd@D`ap;u%W#jM7Zb#m_*_uY-~E8OV8_HCx_peCC`pkon}F z6IL^*nJ_1;W>7O>PFT&LX2Qt)3}imcKJpASaG3r28ED{esm#9o3^Z_pa%TU1Mkzb*GdL~{?ISbnBQxkDi8)1P zw|xe>i+4wNg`9|iUy{};eJ5!q%j~ny;GAR_{V;>R6Z*cal@eZTK98g%=(jL?(!(%2*E4C0Fgw>X zX^SvB*E4C0FlC!*Tgfyi}$a zS@fXokr-NPmL;F19L}QT!^Gr--YiO zqO|$#LivDPB$vpga+zE%SI9`tEXTE3j%%|hdGg8lHOuj9mQpcGshFiy%u*_5F&FJe z`s>jue~1R#Odp6%<2J|c+nm?k#{2FgCi9Kkc;EM6W^}jNQn&HGzb2d+-EF*SQr;); zmviMjIbSX?hpg9b<4wZ{nl|%o(TIr56pq!hC5qC43HPxQ;!h+j;svm|d#dd3t!0oF;FT-$dqbrzXSu zuKzh%|L*mr13Ar8|o`@Gdmk zJebqbcQJon0>8>E?k;B0UxPV;d>1ob{>qFu%sJt^nDHk3a8fewO`0~t?XpAWWN&ln zB6LDCHiR(GYQ~0;a86}6``l(u`0OH_r#JKTbudqF_UX+&z1gQX`}Ag?-ptcU>C>Be zdcrwl++5^zadVNU&*AAmg*jC_hv$YlPdkUzahOx7b4odtI)^oEm{X~9ikwQFQ{+_Y z99Ea%eAz0Wgm?2U6H9kfo{8Ap$Dk$d{t7EDg}FGJ{&e{A548-SD3o{%PneVu>?{ zrKVhJ%B7}UT1v{LrKDVH%B7}UW=d8k#4j`DGE*)y}Sdsnx2rT6JYt^?X9r z8m=NC&+ylrPpDeYRqMHGJy)&gs`Xs8o~zb#)q1Xax}a)3SFPu#E$!2m_GwG|bme{vRW^#L&NpK|T|%!e>a+U3$iQ z5YO;e!ro|D$NSz%U(MOnb?i&j!LJ%K4*SnK>LP!=gWkQ49-P0vml)oW^t@wuu`!p( ztkc)=j){NRaGPwG9WrZ&bwxK;wb%vDf_eJ$yiu4_cF+4>&-3&;!g;Ufefsmh-Sa;E zd7u8g&w8Hz$gh0g=jo3L=Ooqh^v5tY@cbuFEVi;PUhnOX^~{jZC!E_K>%IN)0_B-k zdV%uHgwY8vs1sgLC%m9ec!8($SDqe5BfX$bctM@;f;!;^b;1kkgcsBaFQ^kXnEwXz z-(db5%pc1f8e@a`Z!rH2=D)%GH<#o1Mnf;a3gk z-1sIee2Gu1ZQ@iO={c1bPLMebzKQd1iFpEUX54=go+ihPa32p#?@jP4NXTaN&peo& z%FSq@@FwhFn@clUb8RjyJ@#K==dsCfy*d1Y@rO-w)NppzHZ!w=%&fxW@)T+y%s$#? z=HB5Kk{%lr`4?q5!8AU%n3g=5U57JePL6HHUYB20Ouy3fPsr}XV1Ij-6+%Ysmz>+Y zMC(i?eA&olFz@&h@AwwHp4?vI9mAXCG@0GBmw3~iu=Ch^FteAJu(BrpuxXAO{@8p* zLf({ocvGImn}#PE^I7?Yr1wo<@=af&#gir{S6|{y^V?hHO!+O-=N(@{9+EP9T38ziFeA6!5w97W_@=d#J(=OYz%Qx-vO}ltgO3OG)4!m!2 zuspnP!l~^pY_`0GE!$I!+Angu#dqI=K7W$%M0Cp* zYha5lyTz8>LJcJ4tvqE5^{@n{9=1>q`{DmZJ#4X+x1f=(C7e@jTd0$yOp9-!P7?mu z{6|9TVGH#@NvMZ#RDNY`Y@s&z6}7>ytc@+!#ujQLDQ_?bOJ%!np&pVx6266c$gk4+ zTd0Sm&z-w1j6vj2Z7eChOby%wFX9Zq%glDdtL0cU{L9|sc)66_ftQ*2>4>~!_7}x9BlHMYxM0!0R z(p%(YNOoAyg0T#5b6nfzxVFu4ZJQc$o8#IxpSaC&Z5vM{Jx>f{*WKp0w#{*E8#;dn zF&WpkIj(JUTziE&e-@k0Wu+A`cO_ooxsC95M;?RMqOV@z>GR<4u|N1qX&jRF3i7!R zW*6WUto=5nrl)sO+<^~Hje?H7x_xaX+zIC5(-RC^8&$sULt^0iIKHI2|*2!;klcJBe z=2^aVpKsmATPHrZ8~T{Bhk5Hh-a08;W!}1vx28P4bsud?p1gI^v>Bhb?xTH^CU4zG zD<_<{?xU^GFYVw>=E2NQIFrI(*$HRGvBUYp4(AU$C>wvJY+>dnJE-%7vu4@h{9y-A zOgL+n9nK$iIDhyH@}F4x3w|}Rw9{wp^jSN7)=rthuMv;;IHV4FmssQ zJUz@DX18;g-RO<{HFKEV=!Ar`qS<54d(3%{Iqxy&J?6Z}ocEaX9&_Gf&U?&xk2&u# z=RM}U$DH?=^Imh_YtDPkd9OL|HRrwNyw{xfn)6IpnT!KXRTt za}T8-+ud_8_fS~>nNRMa^n2Hsm5?#H{n1~_?T>!u&v(My`{-xXPB`~I`mx9*pWOTC zM_WvWxuZl2_^aIY=r852M}H}IJ^D+z>(O7zU5|dWZpxOs9{rrWO+LBn(eLQr@3`OZ zU5|e6di2v1$%p#<4$K|oerh%03k;7*p5FE7_YQKucRl*O>(TEVpr4*g{`A~1cRl)% zKO#D(~mH39pu&GG~=@TkKAl-C=A+Bimv2cHd*wm6$y1 zJ;t%5$zJVy%p!XVw(v&g}d4 zm-p!}+X-hi{XXX|5}zBg?{l7E9gIcseNHSSCO2f?*RJ?JZ@q+Y?#8~)nS?Os{NJaq z5vH$&(GTz2*WS0Uy>DN8pT3sAMnAkyUrRW5V{4S~%P{9sYLxIMm{TY<`dXM%C^h<8 z!a0Rfb8b_!-fGPH&LJkJP-=`XVa^iNSl1)d%>5G1DU_P0P-@Hr6O&UYHO8HUa|)$a z$|;nZr%-C1LaBKQrRFJ=8hta*%_)=`7RWHCP-q!<;#(VT}xP=A_1*f-q-JYTPLZbK0clX_Hzhr%h_5 zoHnU>+N4ISr4Dn>q(-ZSIcHKsdxSY>QY+=0Nv)IcK3uyt;h_y#(W;>vTxRkoG_^sIbl-cjAdvm(<4&moG_`; zFA~lPlNuTmkrRf=9LDVlMkQ`dI;xM7iTEQVSwHg=DyMZ{V2>Gr2%@)I+&AM1NM;t`bB<~ zn_L6*i!e922Iv=IZgLIKFY?>m0GUiU zcenL=ML9^>zV=AH3P0|KGatEAy&%$r4Om?ewec~A5z<4&eD8HZHL(<|B$+Z zyj?g-W>@h;cbPxbk~zpIu%k4{T!rzT(I@PYAB5;|{)!F{v*sFPOi6t1!XL(}`Q_5# zBIhxVpr!j^ZucB<#604NdBhR(h@;pMN6aIRm`A+bbAK(V6_c-E)+B7$_Y@KKo(TP)Cu^Fej;wBA>qVVE7#qtsiN z9nz!JTbLcvqtsiN9nzynX_!6Sqey9(-Rh(6kRC-!6V7h+QFlm>BBcpuhx91Ym~eJT zhZ)6w3bPY2%=pEO%AJT|#+1awQ^znP!uc?MHip&V!)WY;<7ZEks-P!|Y`Yqtn9dWemHQF^mQ~pKv^E45Puq$jLDJDtr=qe@tnwf&1zGFC-!;s9o-ivuh{YH(pNGunA-;nkvqXsR zAjmF15X3tW#5)k=Y%s(-5M%}p*>{6@{(*zZfw~H5S;*=VGT(-*F(LD9 z$f^zc7MX7o#^(>b#rWwGZ$HGaCWW*+q}?IwQ^*_}ep@2jggJu&ACjzI2{W68?D|2x z{Xk>}vYv&^Zy~E%$SfDK9|!5VkX<>5w;$FIssDQGzux+dQIGT{2mCle{5Zk1PQ9&Dj|?Xs zZ%zuuBeB5hi4o7UT=^|oofZCY=e*4w7_wrRa>T5p@y+otulX}xWFLe>|>30Yr2 z))x>P0%UywSzkcb7m)P@{GMc$L6}trWR(F~Wx$t54nxi`K-L&4rKQPvU>vAJ%M=Lf$W|@c26K)cOYJOAYON1r(wMA z5XS2c+#z?$LDL)#i|LYm7Q%Slfq314c-?_`-6=ks^Ky{Wq4;teQ#ui*R3}ra<6+8k zGUXWs@A9wBG9@{g-LRzJAa}@}GG#cK(HNpLNQ1W$PwXKOdkDlH0>)6^^i+ClVz7rm>>&_)2*e%&v4=qH zArN~A#2x~%hd}Hh5PJy39s;q4K5PJy39s;q4K>&_)2*e%&v4=qH zArN~A#2$i++_Zj!t)FjcUPm~s-(c%E*!m5&euJ&wVCy&7`VF>zgRS3S>o?f?4Yq!R zt>0klH`w|Owtj=H-(c%E*!m5&euJ&wVCy&7`VF>zgRS3S>o?f?4Yq!Rt>0klH`w|O zwtj=H-(c%E*!m5&euJ&wVCy&7`VF>zgRS3S>o?f?4Yqy*E7na#gRS3S>o?f?4Yq!R zt>0klH`w|OwthqLRob^f8E8-j8kB(sWuQSBXejP8=lf+^zrogTu=N{k{RUgV!PalE z^&4#c23x0klH`w|Owtj=H-(c%E*!m5&ext45XzMrH`i-`J zqpja)>o?l^jkbQHt>0+tH`@A*wtl0n-)QSM+WL*Qext45XzMrH`i-`Jqpja)>o?l^ zjkbQHt>0+tH`@A*wtl0n-)QSM+WOgznOtOdB23?JwDlWp{YG2A(bjLY^&4&dMq9tp z)^D`+8*TkYTffoPZ?yFrZT&`DztPrjwDlWp{YG2A(bjLY^&4&dMq9tp)^D`+8*TkY zTffoP$GK`sTcq_H?fZ?kext45XzMrH`i-`Jqpja)>o?l^jkbQHt>0+tH`@A*wtl0n z-)QSM+WL*Qext45XzMrH`e!%_oZ%>Nmf^DupUt@c{o-uK{V=o8v#}=}h8g|OX7t|& z@qPm{2RNHKK+-fzyx$Oh!SDu|asO<_{i`6}Z{QB&cgl?WXVWg^7OOtY-1ux~0%toD zINO=P*+pgoXBS^hZn5pd%nHt?PV!rJB_O*J5Fa?jXx?Zxn4C(1vToIfuPKh-#WQ`12BSTJf z!^}C)$r>4EHE~YX$dI$#kTo*oEH~sVH{>igB01Mh_zOv&)7_BM-H_AWkkj4JTEd=_l#}IDY5ic&Nj#^!;k?va z&Ui!Ly};KTVNQBOPI|+~WL6pH6rA*iob-mA^oE@DF3zd@eSUSW?R74?^cRHjYygcMZgM z4a9d1#CHwEcTI6FEfwOs2I9L0o|5t~k0PG}-!+hvz>xdD5Pvlge>D()H4uL_5Pvlg ze>D()H4uL_5Pvlge>D()H4uL_5Pvlge>Ly{b55T+7p<6h{MEqpuO|Cfll`m7{?%mv zYO=kW>|agxuO|Cfll`m7{?$}U|7x;-HN_r9IP%kE|7x;-HQB$K>|agxuO|Cfll`m7 z{?%mvYO;Sd*}t0XUrqL}Ci_>D{j16T)nxx_vVS$%znbh{P4=%Q`&X0wi&F;ltS0+c zQz`wcsg(ZJWdCZie>Kr+DRX*OlRc}+p4CKqB_=(qiIxh_O%9|DKQF&PUud#_HQB$K z>|agxuO|Cf6YZGaT0i!$Ci_>D{j16T)nxx_DjqbqZ^`tpCi_+`(nvy_Q_I#xtkrJhG?UIpjLo$1n~<5@e2gGD-H1r1n~<5@e2g;3k2~C1n~<5@e2g;3k2~C1n~d^@e2g; z3k1_r=V8e|0Pzb1@e2g;3k2~C1n~<5@e2g;3k2~C1n~<5@e2g;3j{gM2k{F8IRyss z3k2EQg7^i3_yvOa1%mhmg7^i3_yvOa1%mhmg7^i3|J_=}FA!n;0>MH5ieDhYcm#rY z1cG=3f_MZf_-29R)E{9y0zuCHK|BIMJOV*H0zo_iK|BIMJOV*H0zo_iK|BJ%bNy|T z{Jg{$5b^i|g7^Z0_yU5Q9)$P;g7^Z0${W2bx#0^4;tL4k3kWK2Xv>6^H?(EK_yU6X z0)qGgf?t>T0wRnrAc!v@h%X?BFCeJQ6c424+2=|cyZ}MG071L}L1h3tL(<>{2;v0@ z;spqDrV-)=2y(I!;spre1qk8=2y(s);spre1qk8=2y)g7;spre1qk8=s5p;(v8jyl z+)IL)J2BqVL(f-ZpRdL~pI$jk4EK^C_mUv@k|6hzAor3WH`*XK+8{UDAUE0|H`-uE z|MTfP`7QU7Aor3W_mUv@k|6hzAor3W_mUv@k|6hzAa^<-yZn%QNsyZwkn?LWy7zo_ z@A>N9^VPlQt3}J|v9fxstR5??$I5E3vKp+c2IG_f^-xxW@m(`&wX6m!tHH`@ureBK znD}V0vKp+c1}m$<%4)E(8mz1aE33iEYOt~ztgHqrtHH`@u(BGgtOhHq!OCi|vKp+c z1}m$<%B%>c^4w^!vKp+c1}m$<%4)E(8mz1aE33iEYOt~ztgHqrtHH`@u(BGgtOhHq zyUOaWvbw9R?kcOh%IdDNx~r`2DyzH7>aMc7tE}!StGmkTuCltTtnMnSyUOaWvbw9R z?kcOh%IdDNx~r`2Dyy~1>Z`K)s;s^$tFOxHtFrp4tiCF%ugdDHvihp5zACG)%Id2! zJMC$^=&Q2&s>}$E1xkHYR$rCXS7r58S$$Pz4Mm-+ugdDHvihp5zACG)%Id4K`l_tH zDyy%`>Z`K)s;s^$voD|AqOZzD^i^4XRaRe>)mLTpRat#iR$rCXS7r58S$$PjUzOEY zW%X5AeN|RpmDN{e^;KDYRaRe>)mLS9TB!l`Rat#iR$rCXS7r58S$$PjUzOEYW%X5A zeN|RpmDN{e^;KDYRaRe>)mLTpRat#iR$rCXS7r58S$$PjUzOEYW%X5AeN|RpmDN{e z^;KDYb%FZo0`=7eYN`v=R2R_u{)x59O>&yNRYp@?pcc9S`A?dK@&UO>E|E*+GPzu? zkkLFBAd~rRbj}6HOv2GT7pQqIQ1e`%=D7fQ;IGI-I9g`KbOCLbn8|Xgw4Ah8;%CYQ z(h^cj|5S`YQ|*EHWP|u*gZN}C#vqf#BaIw83W=O19I95a@q=;PI9}%+~Qk)JK^MZiMd@uPv1;9d0s+4<*(*^i8)_Fe@RU8 zzr_46G5<@ZQehV?K6ivCUuonfxhQ;?m;J&8=^woA3@} zcFI@f&*kfu;SGPa+n7Cu_ZohaxzMG>UmD(L{9jSemlkgs^R_YX7=AZl?p}STh$sIw z@HF=6E~DQ)1ILW~65`1j#(sq_H0m5rSEl(r$?Y>@#+&9Y(>Kc(1AK+C@>*ImPvrX!kncMb@jV#E zW*Fat3CD7HE%r=Gf=)|J?0eUu*%FQ|@mlm-!rvwQRZix7vG{874fuQ1#*;96juWuq z&x1MnFu|So3CtC9D)$nZlMfS^D<&qp?Gv!xC!C$T3G{+>Fee`-l(KU-LF@elW_NE8 z&dG-f=)HX~tMUn2>?ctFQwitf!vyL-;hcPkho5eklMfTLw@<)!lyFWyOkfT}4!nDq zlMfTHg;E}^>l3huCY+tM30T)d-vXUYsnDvt2 zX%n!hhp|{rC}OLe;4b-uBD>@hmL)x!rCYdlNf*>b? zASZ$#CxRd+f*>b?itDMjF!gpl^^h>9fFL)TA*X;Kr+^@*fMDw6dh6tR-|Gg(vZ=)l z$iP#O(>0LOHN_3I0x{Ho$mtr$=^DuC8ko~HH@mNWGdWBqoPF(^S!J9Lv#))#``S0N z!+s*+>}%ibzV^-TYv0V?dg8OMeKRM~^4IKZ-|W8j&Fr=i&$vmRjGJNhwQqLk{btI; z6B#QLpMC9{+4aa@v#))#d+|5BuYI%o+F!F@e9e9_$udu}%#$qhB+ER>GEcJ1lPvQj z%RI?4PqNIDEb}DGJjpUovdoh#^CZhW$udu}%#$qhB+ER>GEcJ1lPvQj%RI?4PqNID zEb}DGJlQf&w#-v3^AyWG#WGK^%u_7$6w5rtGEcG0Q!Mio%RI$0PqEBXEb|o0JjF6k zvCLB}^AyWG#WGK^%u_7$6w5rtGEcG0Q!Mio%RI$0PqEBXE%Q{%d zMc5-h2$3%SigbmXHiVBEzXrx@(3gv8Ic-QelFxMWiGLn$5tz?(v;vd}f%>4D*?RobMtgxy>-Q8EB`(B+nVm?yqmj8C33&2y%C z-W5Mo)KSKfX2+3c<`w%0XB=sE9BFnOX?7fGb{uJT9BFnOX?7ezTak0K<4CjPNVDTe zv*SoJYs}=CairOCq}g$#*>R-VairOCq}g$#*>R-VairOCq}g$#*>R-VairOCq}g$# z*>Pl!I1@Ynq@!|#X z;sx>I1@YnqWB<9Al~?k_#|Xs72*k$-#K#E4#|Xs72*k$-#K#E4ix=c3KE%@q#ETci zixgz?`6@!th~JJwtYLe5nEQr3T2C z8eq;BwJ_$UB%I@ge18Y>{T-MSM=gxMA>ZGDId{~;+$Qytb4M-AZBjouchrLRNN#+8 z2lD+Lm~#j%o`p#8gVe&<9p(&Di{}tpJcrQYyoh@S=9x1{EsXD}tDHe<@f<>n z=MY-Z*tDtV5L(bww4F1h7W7rZnJKk+4xz3A4wxO-i~C%;!zR zoUB;D=sz1~<+#8$THwiw1=xY}*Q}uy*hUL%qXo9n0^4YTZM4AFSwLTVmXtYJv4Fm| z8Rlfg0$X8$^}oP6Utn!7u%273!&d9C)jDjo4qL6mR_n0UI&8HLTdl)Z>#)^2Y_$$s zkq2%h(xVT<)M2Z2*lHcNT8FKkN^P|cTdl)Z>#)^2Y_$$st;1I9u+=(jwGLaY!&d9C z)jDjo4qL6mh1TIh>u{lUxX?OWXdN!J4i{R73$4S2*5N|yaG`a$&^lab9WJyE7g~o4 zt;2=Z;X>?>>I$UTSKEQ~xy?CIQ%%1ontW5LZM9yz4a_4#xJ0^D$K1%&8DzX>6 zh&vtO7ui!-gw;39_`ZlU5|_cO4Hwbh!%jxqMeNmH$NnxiM<91CVb+ol(j#7jv70?e zoj(h+hx;J&G2(M`1afl(a&rV`jrJgVCVx%-54sk6&{f!j&MPX&!#rlLv71%2n^m-% zRgjIT#AN5U;=TzMH?&;EeUpm&CKWAv`94a1o1Nc^`z96lO)9j@C}OhnTXEl{;=W16 zeUl1fV&b#&TXEl{;=W16eUl2KWd53+-%2SvzZLgQDvp&EY9l4d&ToY}NjN*d6=XFj zvu{#y-=xAAn(}Aow}L!`+4-#?4`FtGE678_+4-$7dgi&=#j7xShS~Y8xNlN%-=xCY zAy3SnZ^eC+iu)!N_f0D9n^fF4skm=aao?okzDdP>lZrOUiu)!N_f0BDW6F>{--`Pt z75ZAtR9QgPp;;=V}*iArwS=dCak%d@i2TXEl{;=W16eUpm&CKY-&In!%+3;KA% z+2^geZ&GpJq*7#`x8lA@rN};Sh4naj(nk`Xecnouecp=uCKdNhDn<59D(;(9+&8JX zZ&E=^BxUw_D~!>}C;PmWBKy1*`evAY-U?%P{+fN>3L|*JN|*a4757al?weHHH>tR9 zQgPp;;=W16eUpm&CKdNhD(;(9+&8JXZ&E3;&s%Zdq~g9w#eI_s>p}X3`z96lO)B(9 z>K2`r@@Jp7f@VuN`@9wA04ZVic`K|O^V{t6R#-nKoPFMk`z957al+Z>tVzin|I}?7qoj`rSVfll_Rr^s+GfCX1cDFGl_olU<3$$bXo9lf}q+ zn0=GQ$a$E3lf}q+nB9TJ$YjFVH(89#B%FPd#qOIdcJ{v5+52MmO%@{$q@nf0?3*m6 z?Gnzu$zs|rw4CmnEOy^yF|CkzOGqvKQ}Jyy)gG9AlW(IHe*m*@@@-_2c%(7RzR9<# z^Dz4+OBg{m!|as*59G08I3UgRt4iB-Wt1BMLH+o>+=ppp&E|~Xv$UGl1&xg$OA@h95JRdU8 zhs^Uk=J_4-d>Gxn1o_Jil!wVP9?-J0^DvtEImj1AAYT}PH^`eLU%nuQFJC~uFar6) z2;>VR@IHCJ0Ra&b^a^h!7z9&MM?}V47VCyC?AlEWKL*2LLU!vLgNuyB+Lno zN2v2WC8shTp>Cgp_$h^ljrmxPgw!X`qTa&K%2VWM|C)0qk5E7P>ts1qT2AUGf1N2U zEwz!D@4-iT-!DV_Awc{gK>Q&<{2{yA2oQe=5Pt{|e+UqN2oQe=5Pt{|e+UqN2=McHZu}v@^wvl1t&h@M^Avm_ zKztxTB>|aC4){QT_&|X8K!8dDGlztg1ZEBi;{yTW0|D}FDTogQhz|tFS2iF%5TI?% z%pqahnmI%M`k*Dm2Lj>r_eZfFBpy!)aH+%}0^#KnuLy)!T7LW?5ay0N#2*609|FW5 zLh)$b_~gud;2ute)-%38R>Eg5j1BfNde8!hKLj|D-uIY#<1zKdW7r9gC*~&Or^#rK z$4aw|Utl;o}o=FOcR%!`n(H5ylS##6vGUZ2ZS^Bvg|; zrY3nzP4XD6pZL-8{FH}t8DTWuV``Ph)GCkBf{C&Gv|7S5rRAp;60_Lfevk0uCB94n z`7#B}n&@%nQBT2)o{wu^eO&wMVHG5S6zv&jt8RbtFFYp zn!jehZzYz8nK1jRD@(Dgu5@2@C02;95zfBqO6{d9S^d31IBVgRto!!C*e6%Iqq@=^ z)s^n3u5?FrC2OK?{+b=tm8JL0Cp)SuS>5Ef*->4IMhcIGXp%7dsw=e?uEa)>aIA$Z z-B(@dzUoS?g)6ldu0)6Aui0H)iIxbnySkEH2;R}1#Fg~@#AJ7MrFO!V^z_6mmCNNr zGP|oQUAeEs`ax+~FHqVd`>HEh3*=YXS6%5^ekE4HgtM=@65B}9XJ7RRWajkZ33sfX zaL4Ki+A%SA%CF1p4?cnBIUZ(z@Cj<-M3@_|Pq<_CggaK>WmfrQ@m*$>PZm$oJH8KN zg?o}w7*A4+yoX^dY)>L-SHalRo{(|5{@=rwc+tCi=~%JXXFdA0JqT6tcrJg-)sS1Zq}mFLyU^J?XJ zweq}Ld0wqNuU4K{E6=Ny=he#dYUO#g^1NDkUadT@R-RWY&#RT^)ynf~<$1O8yjpo) ztvs(*o>wc+tCi=~%JXXFdA0JqT6ykJo;#H14&}K+dG1i2JCx@R<+($7?oggPl;;lR zxkGvGP@X%K=MLq$LwW8{o;#H14&}K+dG1i2JCx@R<+($7?oggPl;;lRxkGvGP@X%K z=MLq$LwW8{o;#H14&}K+dG1i2JCx@R<+($7?oggPl;;lRxkGvGP@X%K=MLq$LwW8{ zo;#H14&}K+dG1i2JCx@R<+($7?oggPl;;lRxkGvGP@X%K=MLq$LwW8{o;#H14&}K+ zdG1i2JCx@R<+($7?oggPl;;lRxkGvGP@X%K=MLq$LwW90o;#K2PUX2%dG1u6JC)~7 z<+)RN?o^&TmFG_7xl?)WRGvGP=T7ChQ+e)Go;#K2PUX2%dG1u6JC)~7<+)RN?o^&T zmFG_7xl?)WRGvGP=T7ChQ+e)Go;#K2PUX2%dG1u6JC)~7<+)RNuJXQL#x@#TLB5`F z6O65(s;!_}imjlkt)Qx{psKBaFDx+9Rgw8~U~C0dYAMVLv8t`0N?j!!TS2uHTS1k2 zOH6D9RcbHc*b1uJ3aZ))s@e*w+6t=L3aZ))s@e*w+6t=L3aa#!dHgoEf+{^FCCU1+ zN?U|kKUQgrFt&m!eT4mBZ3R`@B{8uTRB4wmwt_0{62?|g)mBi|R#4SeP}NpY)mBiY zALWU$6;$m3=fT(ts`Nohjx6P` zu@zL2r7*UFs;_e2HR0F|sz_|Yu^UwB(P8WcRqX~k45M=ja+t6B`I>^|hLu@Y3{I}yfKP(>%qgRvD2A6vm1WHpSfU=6Yw##XQf=}I`Zf;DK8WiYmaHAqY1 zV=GvLR6sS!8a2rpHOU$^$r{=^e~qnRjkba{v|3_ffn1|jS)*22LwhAAv(q)SQE2(8 z`GjLDSVN5+E}nL6`!s9MCkf{?@6)V3&xbk9`!s7$!o_9O>eJjB*a34p;OSzsF?ix9 z+|5exX-=en4Zb`w2lg87k@N7+mX4RFjod-_^R(=V9k~H+lAHZiH)qbD<@|a6`e*)XI}-A2@iSK0&vH*8PuZC#7Oxuqxy(IGNAX!_dbYB^SZg*IA8%?!Y6dHOnRFB@QPiLRr+hq)QLj@}*4k@w0L zf0g^8>lnqt+z(yHC>G{^=sHHRuqt!Ya~(AnZjvwitXQbl(YwRl#_y4P<(od`FJ*3F z}CJAmiWcdCmqy`{Vk2?T))W+>C)=A-DDD#sQd9f9uhWVNU(6M=ORo z^|wCW`ypR3hI}m!^0hd~*Ww^wF^24~LcU@QmrA~3Oqj12L%w1RV*^~z{PqgSSBzn# zYrPh~^=QjGi}gjm&byw{k_JimQn8W#as@n%b9Wo*H3{>5b9fPbXCqP(rp7iR8wrn< zsXe~kBl(gJVZKKXC;Hde&o}bENq>{!X@+k#Jd2jy$o%ImcpE)#BYkQ$yuxDo9dUM;Ud zk8MP+Cg!=)Ot?PvPmj*8wjgyIi=MOvlDrRYGv%Ml?Xr(EJR9xT8_}`J=T&n^AKzH~ z-0&O5?~!}uU&?**E%}ao7j9CEZc>kJQfqBeYi&|%ZBlD(QVVTT3vE&hZBh$uQVVTT z3vE&hZBh$uQVVTT3vIHro76&^)IyuoLVv1c{wXn(r>HDe~Q=T`>2~HZx=Y zCCt4uzP?0H-;7?`4s-8pGpCHg+&kOMDYc}@y|c~CuEX3r+ssTg%)PVC%p9(Oxg)lj zd1>Nv?`*T9>SphYZFX$k?0vD#>Xyxpu$#Siw%KuZv*T=6{6!aC@fQupARAq!OOUrN zN_!WKUz#rUOc&*RhVVE_*hM)v!0VU;?8f;TQJAyY`6f}q@&3_;#t3H_f0s{b zmN_5TMNbKH$Eu5-63&x3L*7MC31f5aLc@d)$VGCAjODqDc~=|~7YVik}u zKBeIcK6itB(fF5rBRosfiY{ukhwwJza|^GF z8A4L-#w$oyvB#Kw@@?X`AcyS z_v)rK!yDv{XuNJ(Gci-qc-^cM!)eA$H+-w%8HQ&vGwDW8Ce3X~X}5Z^n-gvc-+>f$ zbHeS1@GeW+EHfwRW=@iFe$$fNC-0YYHbwM}d&I%a)*^T}TIe!Ni zmpb9ME!7g!FO|#Wa(}zRoF6jHcjUwJ5gFem-AL3)uxdGfWcu90?e-pSH?z~U%L~5I z2D#Cco8*f=E51#-y{p@;Z~^!ilbXrB-EPjj^}*cR?M5cU9p<)E?l!kQa&L%4 zeIH&fbE}s-n#qm%aKgFO+pWgyMtT#@tzPDs%G^L7{84d*s!w{zxh@Ah`1&yyy1d%KI=?d>iyXYQs)B!}GX?WRX0oV&f< zNHwkI-QI5I%!$w4-tHoId%KI=?d>jdx3{~<-QI5R_HLyYe3??l9gKTVdwzCzEX`%Tl|C-0YYJ6%R>R2ZR@Zl1UEgg*R`aZ^@3yLex4ORD>iTXgvYKaQmA4gHP0FnD zwj!&9UFG$-vg;`|pwD}lul@my2frTVa~I5MpB`qa4KSyDdbHs6D49LZPJ58d?Zjtx z+Jj^!oY`p)a+q*tr#-Co!pu&4(6QZcj^Ui)=|Q80nUVG|&W4$h_BbQ$aYow1IGfyB zFrf|dzIc^rMFk72AoK4Rb4GyLa%nGuzxxIP2M0 zsDanun@B<*`S-*41n4XNLhdF_UtPQh{ERZJgICI{Fef26m_X?Ps ziLcs!Uq!-+p@e(jmGWviR&JB8u`mBBB}tk+a-V!#z6)QYHlBgonccm{bFYQFsGrwp zyTrt9_8KKm_$~Pk{5j=ZQ0(&QyL|dC+Gr0kdHOEuBz%px+l6fGhbhA@WMdzUN5@^% zLt;{rU9|q5;&pR--P~R`x7W?>b#r^&9A5WVubci2Tlo!J`Hj+bjFoS&r|=e>WcW72 zIp6XIbHBfacQ8|Zqx4PxdY`;s&Xx1zeEB08PZV#kj=KlO6U7^>;}Xs-syEOfd17Bk z9qxni_V5NZ)>FKJB=0MBTf*Iza5t;MXNXB|yUlI4x$XA1yZP<@Vz`YOU#(K>HhhBs-E9>OWZo9KtcNAlk^pEoVfo3!s{Vj}Zz>OCX_34Y0r1Pi}uN_ZR(W zt^I`m_u{?MZ;dp;)0o-5#|Uy#aiElwW(S-z9MBqk02@L#FZOpf&h_*5CuI*1yhQV+}r_HTZy~J)kxC0Hw`uv+_EiHTZzm-~(Dw4loZ) ze5}C-v<4rb-lh`H?!W=+E#d4A9ME2OKx^;;t-%Mh1|QHGd_ZgP0jjoH0JKrpm zv9$ArG8s$z05U%nen|ZcAoEiR#qYs~&Luu%ENda$7t)_5!VgM6gddi^1wTUbe2C{hg_i?a)olp70Mx3D2H639MWcfNSpZ~EP?se z12Q)AL#~StX){0My7&<7@)+^4nIB^JA&kxZ5EjBPHuFQALw*KU4QJ(YNSpZ~dU5_5 zoB1L1c}kl#%OTn*jLrNIeL374(q8w$4@(Q-uMB_0YW)x`5+0RlwL`R8PjSdr`-pzM zruc|{9j=$L?tY|o_oLzf`tYOTLt6YJHN!{65v25^VwjfwNc}LV{dQ3M?V$GCLG8DL z+WqqNx9!EC(mSaAc2N86p!VBA+OeO%#(q0UJBG2}4r;$0q%{+c{dQ3M?V#h`AXd8{ z5)=FFAgz|a#(q1f{dQ3M?V$GCL0T>GvEL4Aza7+mJE;A35KCR+W4|4wb;8(h2esc0 zYQG)SemkiBc2N86p!VBAEDw2l?6-qx+5s5*?V$GCLG8DLSj9<09o_&xU{oEXCU?Mp zqz(ts42em74pN`p#bM6Oe-UOc>@a;{0A9w~@5A(kgtPWJT>4L@$?n);YAnp|*kS4_ z%>MH!YDP#FLjD&~TDLYI(gxM)O>`vKXcghYUv0or2n&dEblD}rZ>@al_X20w( zbrM!(Y%+(D)x>O)**iPzEafornQ+!iH|*bi1teQ*pr87uQ2xHA=)cB$DTaIIi)c6%2ID}3}yTqP6gv^JrClAr$VeH96`pO>Co;;*Ic}RQm5LzoW6I+nOg-w|?4IOEh2^EqM;N7aN!)r3dYgh$=yI;ti-NJ98e^&Nl4Wn(s62D)N2CFm|?lr7_{LGW*@bj%dTk>UP2z z(T0)LgfpTIBbft!5HtdKt>})^Zd3=lb*x801#fBZlh8@L*9mR$n#fBZlhLN=7 z7CYN8k`~6!HjJc&v9k>$Q3=P+HjG4tv9k>$QDN+C!`j(~wX@}Gl8M`lhz%N{PaU)2BPyJV`$y+k(oNaR4DV? zdVgE*Z|nVSy}zyZxAp$E-rv^y+Y{_Kr}>oAe9CD)XRS_%3)|=_HtUIg9lDFy%kXU!6ty zM-jeH-Y@6Md2+t|k=#7;Q&PS(@-5gUx5!VPoARG!`OmWaXIcKUEdN=S|18UYR$a=^ zx0y;`gkKri06Aj-Ir{{er9kEa)I_3{SEo*gka8J;%sYr?l8QJ*W# zDxD4&7~d)v$_L~kxy1BKORL? zKLQ(Ndiv*luXB{8bCe~%j)e5`btEK~uOlJ7d>x7Kxr|4@fD@^od09Kz!LjeAz*K*+G2SL44UkeAz*K*+G2S!5^6eUhL}5 zr8Ng&G{CvEX2R+F=hF8Rj#QjW3x=PkqNN7vzC=s)LskSZeeFwG z5kOW?kZ)B(zEur5hY9&sHN+1dyiei>k1&4lAb#*5e()fxC&=j+$mtiz=@-cA39@>E ztezmNC&=j+xI*INjxehv$hWHNuJBE-@J+9>XI*8_y2_q)l|Ab!d)8G-_*F{vRg8v9 z>aJ3%uc;e5!vC#-vG)D3*289U-dwktoHy5TrfB3T$n80ZZ%oKa6XIPNHcM8HgjqR4 zPX0hn{yssbclCl_{YZJU77HA6RyMmSlyPag6q1AIcU`GI(8fDUbpsMxAyv(r=4Ec z&$;)ITd0s*sC9pDn!it)<5Lf7AoB{yoCGo_fy_yc|9Mivq}*l7UH)~Kf91^VNdNJ> za+(WnGK}|c!kiR^coBzq5r=sHhMbzNKOuQS@~l6dJiiaQ*$T&u^g~XdK~A8--y7Kn z@h=DYav#LM9Bh`{ekJ^ZVSJ+z=Ij~dJ}m4r{~gBfl=zn;9{+Onr&Ir=r{+Wa%R&6h zLHx_XOXLLqif1`u@GJ+pR|}tzRbreuKzcXiYkd%(au82(5KnQCmV$VStG|sjzl2G{ zjr7t~h<{^;81&CDv zqC+4$1foMAqc+5<0I@1StO^jT0%SCYjOLKh95R|iMstW&0b*5vjO>t+9Wt^*Ms~=^ z4yzKY0%5EQ5UT=Y#E0yCK&%RIkK7x^ssOPnKVBYIY z-{?$Bex@Zq(~_TQ$_DoBArlmd8Qk^;KOme#>H4l;bQSk_|0iGtu zjI1Pl*~lI6E2U}hx{)8ki6hrQ&iTL_Bqw|bPm`SIAv|+rHtan19k|}yUXlMW@(eMD zM;?Pm4Szgx58;uJTN}h9|0`g<9F<>jk0bG)m0!rOxRvtgZ;bCZ<$l8l{ObqC{7Mcbo^@P!!pM4fa^e}g!?Wc%^0(zB@=JLx zw`t(0$3|{AL0^TCUJ23akiH3-&qL<(koi2MCqm})5N!|9_7H6k(e@B+57G7zJrC*K zklqdH-H_f5nGZwe!;ty>33@ez=yr%!hiGz$4lk8Tr#d&18@4If{+{Dk)n zpF#YX6VLoKOnFZHs^K$<|NM!qpN1*_iJ#;-n)vdGy~dBub5Hz#4WC2&=RR}#r(w$Z znad3~5r6t;J}Fxh=`Z@seB-}B{Mn!RLVI0O=^tbd>J--82T6IqIW5KC%D`|8v|c$8Cczmd-ow zN5{Q<-1_7G^ti43*T2c(f01@APrn-da8>EcgeFmw&D7`u>U2Tr9?SM$2t810mER!d zn}p_>+QO?UL@$deN->0ql^6aNi`H!CQO-mQ4d62SwgYw*s)#V$6?RW z`|sC7zn*;5hY74JV@MEOIPsEV*k0ERR6kOFQ*3b>nljT z#M({%-ynn!aANP_uk-oaBEtVso=LIb)8F6C6Y@6rfG74|O7hS7=hyS7^DBJg)FYnY ztf_s=zCqI8M&94zU6bn){{1am^^-dKq%QxtjOUReE#GRcdDqmzC%xh> zfBVn%I)Q%qHRR?z-|qqb{m*}CwRY$5lxE`i3MggFcRTT^PE5Wid^+}!n> zC#8gW`~OiJpOpQ7&iVg;9sPggy?uOCS(Pq)zN<(lh!Hb%Izk9^r1M$O>4=CiB$cm9 z<%2X$M~rDYou>0qNh+1ks)Pg)F(M)|h=>e>Oa_rbCL+US7>408TwaEY41<_K8j;Rm zOh+angNPXn_gPP+5b5r5=6!$j{&RDF``IgNuf6u#Yp=b}sa@xs`ki*MU&a!@Zi?1g zV5QhC{t3sYc@y|SpFXKE zvzw@cge3?%{432M*ZiD4sjFR|WMhb8IMQ>!j1;r*$5&(FzH_De&(z9;Rl#{tKucxSYli;U-$mbh%jV+j znpH}17C_K>kPOIKqHl$zHWtp2YJF+=O!ShwqyJ-8vb!26hvHaZ#ypCD$ zPP^V+E+5|UpjUEc6fKW?{hd1gBk5A~}#+zzz#PL2PWT93z? z_)JFfEm$pa`))q_59N(nMuzb*Bil$f78;qx$Bjbcqe`q14Nj)91iS_BwDLbuXW8Uc z%v+E8{N7hF?=2g=#`r^{@NQCtGLGtetQE2NMYYiRz5bnj!3e**WFf}xbhGHE~hKX!@Eeuh?sZ#Q*nK3$G+kR6x+jx z_-09kP&m?Vd|JY_v!ZC(imExa<%+JoY`lukLsiCKD!MUXK2TKix0a^pmTtYSsMadW z2fD@D0s0%(H$d;Sz61K8^&{-3T(z!(^Cmt^Xts~qKCbAt4BIkAwY_9}1@ubWEztjJ zyAAr6_Cj27yX_^4ZZEZ82mKTK&p?kvh;;^R6B{)p7FIc7TaK0k+j6x$+SUSWGdf|R z-|&O(GI~L;HP!(?Z+r##HDd?x8^)iYbhohw_-DqSfzxmFgZ^{lTcGzD`$7MOflmwQ zBU)tdRNEq0uEFM)VQsnXQ?RzeRzb_hK>xz_3tC8sr{$m4BLl6 z|4e$seuOC-@ja{ln&0P9roZ8Pyy#5by-Eu*w*4X0;eiPBR6+0ls}#PE=ytJah7bbjagQxz#@ih4PDd_l* z^Y`PP#Uv#S_uM#f&A1GsT+Q=dx3W&zh`oxPNf0E8k=Ar*XJmH7RCTX_Wj{3QidY#Z6OiE!lXctl`%GV;3_?nCT2WmQ-m-!FX^g!EDl&-;0cu}RM1 z<_+K+Yu@a?TXV8`8|+*M9IrXkye*)BvlDo}c~8KqxzxNb5MFbo`CuRtGKXR3=H{LG z88z3Nj|FDb+-yD>m{~L0+!L5vbG!M>OMNx>n$N>;51KCl;kRWKwOaEPe`T$``MQ5? z?bPO*{=VAj&7=OkwE^D(|LNK_#2~$%^hV+q-$L{ey$dX^-46OPdMt>ILf09-^%z0MSY4QJqkp7sns1ALcU_ckdmy|n#RZVw|uSs z!P-_@b&3|=$-Nd>R(szU@DJ6+`S$zE>gM?dK&SYQ1kxoY1FJatp1L&Oag;8C2QJoS z3SE0ayiv2wcgjClmn(j#bIYj7tO@ueJ_DU~WxlhBfo;AEh|EWGC(t8N8dz0V4r?o6 z;R5Ka^j-G1*H!zjN{=wV+G`FYh9`Sh!&t4W^WE^Tt@HYZA=&P`5m<-#8TMC#f6L!j z*X47O~tqjx0E5?G|-ihS%5g4Xeoy!LoIH|*R@o_ z+aoR2fqivjEp?#pBA$n8(p$WNgLUIA?f#*9rKQ_nU2nCl^&hPdZ|Mshu8(Zl6gXBt zqh)L0Wc^H;1@&`Vw)*Sp6G%H+c7UHQGeuUaz!_N$0_STNwCv7rtY6%+*FPq!R^XDX z4`qw$vsw-Wu1IvjSMYz}x~yO?$JU%|ITW}lbYLgx(fWMOk+bO0I3hvj%LSojWqY}l zYshUxyF_N6_`klmJ7e499bfH`=v|%O=xE=XUsZdm zeFw&I!Z#K4aQklm#m2?$d;N8dS?vdceqOy;{Jc6#R{PcYvc|4<)U~%CLc}g=KMF6Q zcdLt~cdM7x<$}Mrc00T$=Ykbz3+rn4-P+dn6R^2YY!0p}b%)wd!+u2a@;wsCJ!|TF zT1L92dIGHvx{k}a38Mx(U%bh_tdRM*dS&fI`#Hb6F<;Iajm6%P)yrh8(TWH3D$<_X zc*NU|#$__E8&`PmuJ$#q^qpGWS(6XCr)C4_buyO`Cz$)IH#DvSf3xu2IN!lP+c>-T zLI3#bo%Ge7Mo;_2)%zNK?SuYnjh$F6%W99eU-J(&_OuWAs~gv~k6^yz9J)HcQS3RG zUEV$h{^s_(I0J(JQjFLJ{h*icq@9N)hF2e>Z%@`XwvYS0joWaRX~%hU#_BVTJE7;i z#PjM)je9^}@iaEiL{AaPtFJfi!;jxM8V`0@pb_D#Z<0USco_6Hp}Y4s9_tAAcQ>Bw zi1goWJkv1)^m(D>Y`*%ooHtkBlQUZ0gT_l3ugbIbB+VB8aW zG?^(~rL|heO#dc~`?Y{lx3^<1&H@{Kr2(b!W=8@vjCMG1w#BUJvCFLKnM!&(>FCDW z9qB!>SljRS#N!$xt0zfT=AH$O_c|8)cQ-!h$O?ovX&w3g@g}>_wHc64lGP6~H#>^+ ztD2^EEW;TbF#|tH%q)aY@_RB!JB9yJHEEZ`WKXHYBw7)AIpgzu<0{1JW}*EQUue2`fDy_fXx*~wcX&~u#C$@D@S5kIe-i)p_p7_>%UF);ETMu?^ zlo7|8aH*p+5bjynda`SaC!_UD*LIJy^?aAh<7&O+Kk6xMz0$P{wq5V)_bhL{*|pzO z(K^~S;Hhf8?LXnEX}$O2T=68X9(kRH(O>aWwWqbYxa&y6ct=mq`X*<`x}J?qu8s{o zTbfEcHur3ATHdj(XIE22$IhPqrmBuTJ^Pz#I`;JpG&Ob{>^aiZ+Htt&cvGO`SkI}Z zH615=&f>ZSt7Q|e;(9JLF77ykE17|g^SB;M!uhlhtLQMU#}>AP^<1u9gLCURt{y!- zSDQ9=Tew58)ppcwN-uBdtKTDuVIVOedU<9c9U({{}9%BEe-SMuX!E$tab9B%8m z)zshopl7&gzpu3CR&8rbOwS$6k>%az>eD-J`p23EI!4ipBOSNVi{l;ldiooW$+@*@ zea8cwPZK&de|giXPJ7S&x-?#$_G3+MZ`$5D71uLfS@UuICf9gdI&i&R>+GBk8_u@O zlPi|aXw2UWzJ8p$D>~(xZJ;wAJuQ`UZqtR%B+ym7GQ5Cu_jqm1Bwc|SdKp(Hl}%SW z7vL&|*8p`$%F3%c%j zjspcENz+xzpCzJ+IDa!&RT>ep{eB#WT^iraP^{Xj|XCsQzBt#_r69u(mCT z)oE?pyK{+dS%af!Gk$w##4H5YyK0A8&|j+uvQ@Ft2T(yRspr?MOgrNQ36; zhDB}1fkM|cWH#^V_7dCC>r>s`4Y_S+yVo|jomaa18p_%(boa?h+r6owyzO%L)=8{v zyV|{@p}OrxcY8x!+i>@8SvkA+Hh9}A{HGh*+irCqXy|Uc(|xF6ZQK3)jE26piNLys zP3;DBZfy_iJ}P6>&6(JJx?xBAwC;10xVt^dKhm(bJ*N9&!-4j=?!ktb_Ia@UP7H`njRK9JPYlc2nD6 zdu8`{!(e;$Y6V!i+G@DgGPF9pVW_?C#kmb5?cUXq4P))?%da=wZSP(^1Gv^--7xNS z1ZFlW?R~3fdbf7o_m6pZbWZq3ykVVHFI9V|c_wU`bvAZqHd^hQaAqfZ zV>(-Vqr7pQf!-MJyv{Yfao&{9^}X}FX`LH;Q-Ysdyo)-w^rnf2dlxZoGrgIe+k10m zoyTX};HTQ)=h?~6sx60bmdB@5jQD2xeCo~Z+|}#m=akT=RIYDccV~ZK)LWK2*jwf; zZ>#Ao_f~f9@2&J!cMkMcd+R!n;A~4hUT^1d|88%4=c(=k((X%9(r$0v?|+W&JlpG) zYlGf)iMrlyi8pW_S<<_fz3B6HcV6h;DrdtNPuAS*yuAFj^lSOensuF*dpFgb?7WIv z+d6Ob)_K=9clK`e_O&hS-68X+cQ<5)@%bHBjL>$z^H%TPhU(4>y$9r+TUP1a)On}( zkaxG==&hdIm%!QCzt_9hJJfqZuKIe9dJp)+dQS&;A!-Mj*I~R4`KR@stJ&v|>b*F* z+YtO*AKXviCwK2fe_HR@E_RRqL`lWI@c|{BJHy%B z8P3C=aD}oAJJ`QaD!6z33U{qvgT{31`F$LFZchBtPBgyF`3&~|zJOzy@)ZSd>&8y| zH*vrFw{UzC&m(_VS%D|?|3-NQ&m#|FpZ_go7~ims;2w?+<=5D{TdnG9qVjq5qw2?$ z0W}A|rt>}gKE@v_|E6VX*~-6bFKa85hgy@?s_I&=wqBj0eM8%&zF+&cHlTh``@VKT z{gC#SHmc6j{#CoDKBxV=HlaSRtNJwcBl-vQ6g5x(h@PRorZ3S~sP+0QI)1s(7%+y^ zKQ)GppQ)FOw~e>e%f^^7q5jacnKpIU3^(y+0JG3^YjI|YS*p!7mz#&Qc}9ZxBtEUqITN;w*77GlKtoQUur+F-?!h_ zuG;_I{_onGQ>-bLcI~P0r^dA(V|Q}9auVJQ$G7>|yLDj4&f!+nhIHg*$Q{VbktZN6 zR-zq?ab)4h$5D)98IBb=R^nKN!-K=u5bNk{h;ShRfLy}_;j(rUa z90wZ~Iu7GFhT|lTGdRvWBw{Rn_n;WB8P$qrtTI+1Zt9JC#WWfXJUe1|4KMbWH6>Dg zQ+*R#uRm3Ps;GEd!q51m`7K3Pf1%#S8=ilq{tA1w<9Hg+rr}Sqit;r4bw$ByDeK zH;Q!IanJDpow3iKI)D27==rhp^+yRUu~6cX9s@-eZNkrUr48C_l$hN*^snoR%wP<_dF#@{(DJdx@8uE6rDx zm(ADA*OX71wPvld!fY@bluwyWW|LB32Fxzy)8;1g%gQU}SIn$aT0KWk}_YN=J3- z9Y-CK*U|3icC2;uIW{@AI(9gAJN7ybI1V|EI!-uFJI*;SItCrr97B!~$C%@;V|>0c z-uqD;5X-n!{QA@n8m?iD5xFy}Lc}v#1QkL|&(w1y;En2eG zmAPbxD|g9mmwU-xSJ{#Su5#vwT$M|Xx~i9)aMdk2?eZ=;=W1Va(bc_V(6x5SHCNw~ zA=f7A9C2-3GUnQ`C{v{CMAi(~>8zQqbL7u;U0i~C zSqZMeEQjk_R=R5_Yq4u2E6X*OmG8QnRqPtiT2`oJtthmzRu+b5ttyPn@}N)XPnNH6 zMpmcGoz>$i%UTD!q+jorU{lty!Yr|gcAYHD&pK0BoOQl%S=Ob(6N z#E!?)^}! ztlNd1S%=Yv_~%|>kN7e>31bUCWG^V(C*vkQ&0bh|Q2LdfQFu7pS$HhlRd_PHwD1i5 zB{3rM%U#p5D+a^VeZ(CtF(l)gecV--eaaoneu{skuV>xy z?Arx*lH@Yp*_Yi5vah-qX5VmUFqXy6VOLo8Ew@v0#+$^n*m}q9;`qY9{6FM}$(%7S z_3yjpWly+EorZh4jJq?;UE!SOu5w1XYn(CeMrWM6)j2QYfXoevS!aqn;7oI`kvWnj z@rxv5B5^EpMRYvMF>l1rGH;k;?nqoa7rCmPneO$W{)hT4^NH~#;|)KA{+Id1*qA82@1G)E0qH`xoV)KlWc#+GR^m8cB z3v*x1n^uyP7ge%=@rLren39EgaU~fN6M6GWoOvlFE|JemD=E!eRI)rTv!o*A=aA1h z2jIiJ+>)w1cS()>pI27Wm{(rXDzU)-D@y{8jIS}HXcIC>to;R7xxrFPytkI9pktgO1 z$MYQG0^=<6Bs8v}JntgTL-1cHmo-J^)RM`$CI9CQmh^}Irw*)np|vmXTFL&rp^|~T zk&+{MV{^~+3r5# z?8ew4hMa5Nr<{H6vl3G>f1O+1mz_J@S4EF=xBG^3uY1^ezrZtnPU~@ ziXU^ri`=qKi63(!i^_6l6qV=9EUL_zTT~tDTTVhzU5=y3n;%(nA%8~6<(%}QcIiw0 z%#y45b4zaICzK55J4$Zlrsvr{8goK zq4)@mhs?oz56;avFX#J8=ShDHJ>L9r))U1?hWhDjSXmo5s` z%imU-nZL6%m)98>m(UvdD1TxN%->V$&fiyBmVdCcJpXWM{PJiKCpR=woGG{~4X~vlJS>kbX z(K)#m$=OzPQLYzrb`}lF`7dWr(Y2g?MMIK8*K|1ti$-z|7mZ1ObB-0=%{f^#o^z&H z$vIzaNnGb#DURf|9_Db)_2L<9|7P*boYCUBa;=hcyEuXAUa=$RL2-JnR=k+k3|RYf z?ZsKSQ;YL+rxzFJMi(#3jV)f08(+Lq=1*=?@hTZhriI16+>GMRTxW4luB&)mZfWs` z+~viarC+%f#oOdMCbz11XKqdLp4`UbeYvg02XjMp0>y`O*AySiU0-}McVqFH+%3iD zbGH{?%H36bCAYu$dhY(>o4EtUqjFtPuw`jN!S<9p($D-WrQNbd%<(9lz+3d zFMqUjQ~vGJtjt3WH|HFJTz^gzMX(nG=%KZ%bDrk5TS zA4p#dqDxN{#Fn0xb96y`={Xsbf~3-m1q(_C3l^4M3!QHYGD_m*{9E8G9g_Ji<5l1) z9VsX+9Si9$SYCR!prUk~*V=NO4SNczmMR4`OD&0sg2tuc1+7aXC0+^wOJ@|U$+YJn zu4H@))-Rn|uyN_!f?b9Ca`(IU7xXW65780OIK!}#oRwuye@mcyA}FZ6ADY(4US8#P{r^w_cE$zvbdW+G5UvPCq|zqJ285y?8N8}*@@BT%TA2G0H1dI@hdQob{695l>E55IBy&_ zd*jyP=!@GlYir!rxE*o39})o7vlzJU5mSh(xJGKxUsmqapQB8 zIo6!;IgxW_%$Yf7?wo`0**A6Gk7 zzmlPSR$H%R%FY>f?Np^)sr+4kVpVH%TsCXI?_r4**5^(2T5)M3@hNoOiJj=8IpS@qeGeT2flN0wp=Hi%& zlYBnzm~`QohC2$~xHGgEyBv|qQarOX9lML=*eQ{_1yR-b$y{^Siz#T+tUKTuHc|a1&`X;db0W!o7ss2@evrM0?`Y#OaCA z3AYnt6XO$;X5UU2oqaQLLE^&1j6`RmE3q_jIj|zJDzPT9@mYIfYhnPnCb1E`^@$r3 zwQ@PHf+aB;vY`?FeN66|rJl~akA(Sw1+tBE(_1`=z~zdMQd z6K*Chmz3y&jjqIrBqQNE=<7*gNz>471vH43V44nlBt?TCkA6ym_N1t!nAx`zcR{{U z5?e!yNpVT@l2Sx(s1?x|N@9bgq%_!a4>cv-e%2mJNsE#)F&?epYl)3Xxk>KC=}Bct z<0mgp&PvWtTqyQDnS`HQoV<)tIX!t*vM1S>+$rOh+ygt;C2xR_wB*gn+d_6G?@Zp4ye}Db zlaFEit2qAfck)TJ9rV2``AqWp0a`K6b&{^MXZNX zFd`PF*i)vaOi$kVcz;P>#f*@INP#}4l<1UL8MT!7lq8PcBrOq?vLIz)N=Aw^#r13; zr8H%EN<~T)`mrbE8_dK0lp55-Sf(>64!{hlvdOaq^wDqiW#^cJXgy4#L}d- zNqxXgNLvw!r3u&Ls*-jjx{`K3YfsvnbRcdZ=}^*9%-5@!;{n8UW6}x4+UdmTq;rW= z(dLb$iw%BZ<3`#**$PjmK>dwu&Dt!!C1Tf3oZ}KfcQ>`}FyYE%E7O z+$D`*&p9C!{o-ltA+KP|)EP%D#VM z#q52K&7y(Q@KeghJV+T%xs`G!aZSqol!-)Fs*xI&Sdls{H7YeGZb96Fq-&{hsq>Pm zpN&pUnSDDoEp-u&%+%aecgihDm!+1&uTxV~QY%xd6XR3sQoX6|sokk-Q~Odk#cfaB zI(uL0j?~?$dy_^|56r!tdMNd1>WS3TNrR7e^@n6nKe2VbE3_{!`}?vtkJV3BFZ=A< z{PyAuR%aJh<~6|eiCdDY9h(se72La*-S{(D57#?xrj}t({x(N5+K>CtC#T)=S|$5k9R za11|_7JciPMdaOyZjHW=V;ILo^u#m9GnvnXJ(K&)v}dM8FNj|7OcbPJqHCUsd&d3D zyl3X29nDx{dIq~#YA+9uvaJ^vR>82I9V)`_W4`9##Rygjiheb2xiGZ2- zUM=nvatHFW`tvjA&Z?N1faE|*M_P=Og_Ms}jI<1C1=32SRY)ErA5te$&t$$1`39uT zNZXKhBJDxihjb9>Fw(KfbaFC3gZ%s?eF^y$r0YmGC+Sh-!oQ6as(TOg10<=3vRN9E z9ce1kbfjqTr9YCSKhl?wtzuV5&y%^>B=$U>#Gc1f$QH5Z@g)4m(yVyc5epvtGb<@5 zJ8KK_kX^!Gh?Ic@o9Q1Z6I(;M(Bk*U6YA0Dl1pDg=?dso(B(ufV<7%HjQ_Btu# z#~83J887L(jIHFNKU7EjC4LCyQZDv9o{K&gc*tq5_)Bb+95&EjVoPc8|5?kC`;f#x zp9aGkXV{kg?t;5)DPvMzD?${Y9QB$)C!r9y$;Zi_a$WGlX=Jw zPv*swZH993llb|)@)c-5fbx|{Hz!lbAEADS@=*UndB_iw{hzf4y4FKSsK4)(V}42O zhsJi+M$jSNllkQM&)SYUyJl6yE<(zLe8^w_UHOy#{;&T3q`yNx`!D99e*dBTNuP)O z^oR1$7`!7#49i+Is~`Cpq)`7u{!Rc-=GT*XD1Or?%l}Xw())+4$7RuM5jeAJ%l~2yKM{D1E{XaQ=Jg-b@mN25HHUjhw#cvO=kSC0@iKYJAEHqt$$2PlK?I1R~;B>tO=g!Uh;)3A-_nr+BokIX?i zH;b)tlYVmQ|<|K%0-*5ULj!4PDUr==>J4A(Sr;w)<%AFAM5=hmE0j z*Fhfrdlb7N+b8q5c(e!md2NP1#VtTuh?IfkL~@}l)OJW`D4t|&x{=mGM*MUVbYGB; z-2{3o(hj8ENPCeEARP+YE9D&9qu`xDib6UKp7<3h_8jsn$S)!dB3(loLK;CD3ntF} zko;Z9V=QCG;a3I8LJEH(MdJS%NHdYpr`ZXpgK?kjm`v%&#lPo+X?7O=&xgIckQXE0 zjvW4;y#jPJ@|8#!OG&&=f-dUwfagQ%MCw6WhqM7{Gs`YAt&|E1QX*1eTXYXT8>nKRE09wEGe!AsS$PNBB5WrZV~&WZP+Jv$F+in zZYJsLD3bV5c=wi_b+eRVVLKg8a?I#tP3 zlyE%j9gb(b!*3wrS?+K=-)$j<;~8(E!||MVIG*#4z$e5A+zn=dAAzUqnWB*6Iq!%# zqj>zNz+IdXZlp3KJR2T?=c-A||J6u!NM5A&$<&QplC%+`LwTs( zP+91I(X|#yay&;Jf#;_q@cc9ro}G@^J(>0*mvjK>5Yka4GyHh?sqnMm7s4-xUk$$z zK8(-Acf#+7Ped3IVK}BmL`B3z#POIHkrI&>u_z)lVqQdUggc@vqCBE9qB^23!i%FF zM>nxOVl58&zmK>H(oslTBX;1}9kDm!K*XVlqY)<}PDh+WJiecAxlkT^zeVuP79Zpr zETZ@Zi>LYSiWt7N;zPVEIhJ=N&*hsc=JOpDX?#1y3%EDA2yfq$_fjn6dnrE3H&T4! z|Hqb8HB!ahgV_SKihdlFs z(EE`Fkd7c7N0RchljRpCbF}lQE@GN>C9b8-;mKTLI+X5!{{8q)46h2W32zK<#SsW! z6TUutWB8Wv?cuw^`@{DG2f~l=c#o)o#4be9{_qJo7(L)w9m#}>;uXi+{6Ai%7<|m`w#Jr)>}9}qWlYvh00HHd=z)IkKmiP zQ5+vrZsAz0{2Ir{mES1iN`~?PN2W4?V+rne*YOKtrfMqLs!g>iPIZbJrsSyMYPgc8 zPQ^-w=b*}QF8n4FVm&fO+^OTp=1T{ffjyvo>s=SOl>~oZIHBZe`KB*R{1g*Kc&2; zep>xB-Xi*n`ikNcB|b=i`t|1D6Q%mbq(H}v{qfKw5y*} zKc{r4pI1MxbgExazo7W>oWMpUpl(t(;a6WbtDBW>b&I-1Sv}>MDe}GG3B!}rkrcotwk-ts?1 zIi!3KHBaCj=n=4Y23mgf4Yd-hXp8SG#v6w4tuXFY#+$;1e4=l5-0S2r^c*oE!LH!)@4*5qdtYLaQ-m$70(c~uz$DB@n8f*Q+Kr7ls;&Ed) zkoTRxYJRJZ0V%8SSEZ3AoR~J^cD%(WdQ^Qsu0UH!&H@%^kp7CiIvK z%(cKq-0!a%t-?3gnwj_xcdF3Z8bN)X37uxH(AFriQqa6)Y(=dh(POx&XI_v``NKln zSCLaKX!PjUiQ=E_`cGK*ZD6#%37jM5ZI(U+*6A;xb-RxDL#Y$`eQ;6?4IGaNdF!qY zd!S8lq0}{2>VFCB!~1putjgro1#CC17~r-{6FQ$Gn#8s3Nu3(4tXsU~%eh16579z^Lr(jUXGfT&u# zdI8u(+KFGSP_;KS*ojue+C}((O;#(+bH$WTKEUn3eLvUNh*GELg*^>pIM5SQO^sl#o)Jo zQ47Bltg3$`8q^vc-&w$4rHcBn&%~TIdKi<_jd6_28>Sz)LTICo{9|}#L$#8G*1hDc z5Jc<&t-Hh;@;gmvHg2)*N^>Lh%wyzVGq=fzi;O)$$(e$PYDA9V){j8*b<(5e9ng1l z8L4&VxX2g=ut(pI7ULy;v>3+KO5-Wo0C}5T?}W@2Vv4>F^h*8nQj75)Fs4CUnf`B( zA7kCU#5%_LdPe?AVjtrGjP{!AZRTG{R)V4l^waQO$~f15#l-mm=LO+> zMNs{uu@m&hV5!juI#+5v9AaJN;XQB^{TvbF`|yH+Ig8TM!Z9#U6~){Q&XtFxC-r=Z zrC+0@wDPCMG2nNJhXhf#75F}*hcZCrFk9R$sLl}m`bWh!UE^B!Lt`cA8bS4k5;JPL z^=)91oQYH)(XcAX&jiMq7ol^p)kqHBXQ%G4(!lw?l@9u=))mm>)@z^*3v&vRYk@PZ zQqp6Bvd(}XN5rgA7TXNsA>w*LydPa;{*p+JZ5B)41kSW!ywo@G-au9TS4*rKvo^ET zPP|EETec0P72s`a5O|I9%Pg!py3I-!ZwPAl&98z^Ab!V0UA;?CecSp6)KYNIl*Ebj zqFQKNCkV>DRC4c?=-)4PZxYx_YfoUum|6uN-Hu`4zg5X zTgoKAQ6$l_`fw+%ctw5*B#)s@tQ8`u#!Yykp>rZ1bf)0L)5JPKWgh7v(qW`;J+#2j zm0AxkkaIy|9yHcZ;2xA7o~(75v`8MC0R3<-@xpK6AJEd)u^|5TKIolN7aUoKJIJ{( z5ev@3i3(sH(Jk_-B`vC>f||#=fmU|Q=$O0htAMG*>4KIeXndTQNd5uxKP0GqK~Vo9 z`7a0>PYYVVB32V410%(E~=maLi+ZS{6$O1ofcb{+67bg4U~~Z<1a>WV>cO`D23S9O621(gkg= zlcSR}Ok6^wJtjS7mJ7%Bc|qL})aX@nK54dYP>=2Jgk$_%(C!zs-XP}z>2^W$1LS;D zP~S^VaI9AfZP7~xy=447OIJ|xbEKybpCM<0G<#tblAb~S8RDRz@k=5ljR5I`#PfpM zaY20{v4Qw3`MHAT_XKT4g2pI07X_`L#~7=6zHs!QALuqekg8KgyG$TmgCx03_mr0kA)=2+3@rs}}BB-;}_K!l_!-@9<%`XdDJ%YA0 za#jl(&y#*X>26{$4mSxM_BFvN^rZb;LfdGY6;J+ z`G}yoi~PSLJ&!c|V!kT0#<^p1jP$33V_QW01SQ$J{u^@WN&TGA8ugpsrOc1W`5Qs& zV}d$454Xs=^stX-t2uJkHZaeyYTXso?#tDSwv{V(wIDtl02N+`;3`dIum_1+*c}2c zC+Div(lZ{qffd5R^|6%xOi&Myvz~NsR zK$|Pbxgu+?RwamY75LaO5M0LVt|X!LJ%UQLtjXFL(S}cw;Ak6h-!HE5$jQZ?jH;#M z6SInQ5=tLlk#*ZVAvCUufmq2=SM3(my%Xyoe~1`Kv-dqH}6cCuL%(;f5g2g{Y;)Q~zRb{&8>h%Fqi+d^x* zM5ne&Xq+F#lN*GC$Fae|)x5~;lRjF@gx1p@t^~#kt={FCD{0~{Ko3$fe&QRD{~`5% z?%_CPa0R7}O{9W$iHtE

    -Vgm|UYOXQf^APFmkbdUVnf;ol{_hWx>a?U3I#@dor9 zqXs+qXC`p<2(JP$cH-O3f?6@_#`pgl*0gMNusJ4CCJh_;*-RE;86J5Dj*j ziF&MD#i^AOay6Ja;ez~Hmd+sNQT}OqZwX^^lpOXH*N3R3#Y{wrX0ZhOpU`Y&3Yw)8 z=~zXJg;sBfW_*4CZMfMZ`cvO799(}2?hB%5(?_Un2HOp4I4z}^n`i}Z<_2w#6|^}7 zO}49FpY$+%Yg;6Ii>rjOMfm19;lNH=LpF21@8j5YODk5llqzAOUvu&koLvy(E1WY@ zihWBUIFN_Opi{pisQLu)2`#8U791C&>n<^lb$!%xU%dxy$E96!nDTa(-k?u11hFQg zUGoGvX@c4!VvHbW1W;c`JVz{}ow1DSt^71GEWN{uB3mQaxW;_8&1)qae^Pg=V;Auf?2Jy?}loFSbQ%wAYpuR%TSVhj)Nw*2w&JbT9 z{~LnlkBHwVMv-q2_Y+SDPVti7Lo6fC7Bs2H@R2?#X#6AbE95*cs1r?EtLF;Gc9^Bp zh}33K#$fCEzmZ=>tQ52b>0WZ!BO_?@PwZ*p8DbM9Ul7{*264Zj{R_gk=r^-eIEIs$ zKr9y2zb9ywkuxmv#+!or4~R>MM~Q=iW{05d^Q7q+lO8h<2**wfZC?{w`>mk<8A`gS z|A^4mY|`wh6||w9d-mb2yOj>bz1~&ZwTLD z9O}O$9WJPECjBXq(HT)@GWo{@%_!j;^^{>eoAZUX{fVG8hxj+-#0i?;CB9A$N6PFY zJx2Zyi9ydqlBS<+T|!&O1#O&J`inyA>&a)N>GYWKKsa{VY`!G)6qleaKui}jIa6%6 zg|^Dcp;ry+wAdFLBiXu18G6S2HR+ELcMIyj5;RDg?61jrWIRWiZ?W`$3YzywZz8hq zCg+{GLpb_JDDx9yCpny}S?jr_Ald)%gjhqHS zJ-7lyll~56*p~f&32h${obn~|87G#PH0`(TB0Y`xK|#|mIK|7jW%OE~Vd)QrV=|WT z8C>X9#Bn0MYThLMx}cRvx{mlJv0cy@qPE-QWRXrIy^}bHGCvl+{#~JUj=1d=p{-!_ zmatZEty?5~+n*4FI!{y5A!z)QNSYiwa~U~b5j6V*^~F+(PoqNrlc4o=mU3+|IrsI4 z!m*tppEJ(c>(V#@RRJ+rqbV z+--~{^O$hL{#I}bS8p5R#IjN6C#k1ZXnlfpzaX^LA+))T^v78Gws4-JSEu}m&{KGh zu!6Hjq0FBNU%yYfmm1QDz0^b7tO{}t2^t?Da?aYmE3}R4q{VnPS5xw=pvAWAjCPAr zYVhn}E};xpLi_VV>r=@2Yhn+Pv(HA_{wg_)AL9z?*+j;+`IkZ)4~b_4ZM0CQRpuAT zKP;%x4?6p^r-XE(pw&&z&xuO~jV}{FE2y6*eN50? zNo*Cg$CKt&y~*o*gIs5#JV6i3Y7z9|*_d4yVq~Vn*;&17$R} zu6G`ki#D7L7Try&a;BHPY9ayk2Wr}#?QYxeWKM0N8d^O3QNBrsQ#LC zBXOgkkt}F^oHTo_(;G&WaBOVdDiT`z2xa)`L-z=+({e3|{9)p6$R8q2dyGF8+6sD} ze$#ieG?$VeAiaR}Ad$A|L7zvkw2=Hg#5Q6l`Lx0Clk=B?=6>>9h*!z)A@W61gcFSF&yfEsa(+t; zj_fMZa|I24rZa*g$S5+4$e$yqe~a`A(i@0n#La@*3DWBYO={D>Ahhv4mU2Go7fHWH z8MbBX656&)(4H-5Fhb0D%Fupm8Tn_3|C^X9Xgw!reuVf%@`Lg7kE92P96RGJ(y>JP z3ZDw4?p{ItKKY}>V2>EF`X38NW2~wiP3wcgF&UYLN%~8I`fcLpi5vy>j?mg&BKg{1 zu~Zi{9HiG0e@x^WrE@jVu2Y6>>0v^L(UK`Xq3y2-+GwZA(KNimnbN{iu5wmzr2bYo z#`^^I1VQbvpqWg*o18xtw7*EC4JPALJHpaW5)Tqz5Y*`>-D(*n)9&Q8;=P@z+GIE!NvYV`ohCHxbhWEu!s@$l(a;n}pW?nVew! zyiQKg+ucH&w9QyTex0C7f10Y$2HVnK6{>?NM%oq=1}ZYuEw;UFFaZ^%6im=U?453|2RlyMLvjiV?% zLpp=<38Y7)mR=>a@w$w%HkXEsgH`JafbLlax$eB zRs*qTjP~S;yyl>`7!&tm>FdZTr{oB={T;0;W4piQybI@?y3AR>f%gBL`eTW&5SLJA zIZJmJd~1+>ahsj6 zd^5-KiqPgp@>2w{R>%n6;7B<|k1@a~J;#}Hh4e|G5xtCL&YA?_18NR1Vq+<}iZd~m7(S^}G>3~kR@6w)?-y;D z<7nNOOKX>l9%H%CdMxd{9&C|Ow~Fnq3C{Xpi|oZ#%6n}Wp?NF4y2uuT{?4S#b;@sN z-J8~2$Xpe~XJoXik4RnZkl3j?I2IoiA5NiF_JEYyJVee!b6iHp=#vqg(jz{%=L^T` z=L!}plIF1V5%&pW1=F{)m3;c)B>O%l{3&y-8>qY8JPiG71Yt=TY}h9nRE|6DNrr`5 zv2YL-Qp)kwGejHogM*Qh^*=#$YX6fhYK*-YVx-Jy@+62>!EX8i@m;Z*AsN>hYZZwP8*g8BzZZ(vkkWGsD?b;~JvikwJdirj&w zZK8Ol6WxNiV(A7xEodB* zc(&FHZTW~ULEBAQTT4!+AnXx*TI9_ILhGx9);E!k611jLW>^q@D+O*5#2s|9@?4dB zZb1W$dn~;mXez`R`1N1aW~YT=EFCiMLUPD-gMVM_!Ts%!$GHq1fIVp4Sjf6(N$(We znn4>%g~q*nS&$r`v|0RSkX}LGZV?*mzzy)%lRuLhe57*)jcDp$OUW{81|(hN-y(l8 zaU12gvDbankSR0QoGE7zb0a-}g_8Rz(<3zcC3uXZnNAIjtZUHzVMfJ>xf?B3vUDC> zcS4uEORI$XqUF5ABMh$B16ppFLo!GWT?AKY`yCIfCv%Z~IfUCqC=3#Qi#1CdEH6Nws z`=ZS}P3)9b@Kl2IVz;2#C#{%^$saKHL+1mQx>@QLFIkJ}+aclTH(9!#cu!C}E-{Rm zBL43aJ>~-8VAP=57-EE9G`|4J4MOW>M6bCM^oXE#S=z9Y7# z3XQRYZ?PI6AX*q}$zCl7+Oenx6ZsTm>i`iRihRO-Ja?HY?or!cDH zIHoDou$FWk{j-tLd!IHOHin?>LsCmmlYZfM1cY9v56}p`C zh;7JN%g7(#EURSXC_LLGKs* zYClK)%Vd%RE$IU?PxW<_=@HM^YNeJQDKUoY8CeMjgf^Xm zI8#gM8qU5t_D&&=iyp%gT0cT3H%-N#7(MC+?D3>O_#1 zdzrLFLaV1HwTaFc;pnRe>=SZIyRQ{TDCGW2Je^~1uSnDe3A4#cxPG~)xoXwPs6T}@m zK-_^Qc$b`A)OJ@SalaY(uuyE+Anj`FSbBr>F3R)1KJ_QUSN0PZ@Y$2yg19Tp3(a3A z{{&k(PfkC3dY1HI>bxuR@BmQx8SgIZp|$q}akmxpt3M^@=d@=l=_|xxqL25zceAat zyi4b(w4#oY!{=*sO(gZ_sqJmrznh#iL5-5?dDa?zxD<5{P%@L&-e)U+C7QL1lrJX6 zQ~pm``c2{l`5z?xYhoU;pE`d{`R|eQ72?apR3bGiLCbeg(na*L^d~|q``Dv#+BTJ# zPR>~=#htOz$0*kNj_}bh>D@kRP=ZK3Gl|v2)zp(j{35lDOT;RrEIli=lyMms<&tpJ z-%`&%6Z2TBl6P(GlRiRHWHPCTv7|*%^812Xyx_wL%2Wy(_e9bdAiYI2z{B9^^ryCg zbvZ9^PuEFkzCk=l>=#rv5>E(f9%8W|MpHP8Cb04#!Ub*5h#ACuVi~dGwbvTF+A5-#7$B}AZX#~4_SC+i?IG?b9wHti zo+6%G<$Lut?Go`CahQ0UI4-Cgp2oHYeJU}EIFlGpOd+OwnqKqh8ANB3$h(MT#1+IU zVja=v6`25WEpY>J3vmZ=Ps^*GR((J5F!2QOEb$WYT1&%gUVWH&hd3c`7)6{(j3*-E5RFlo4blHEDXA}Ut~32t zC=D~>|5SG!U`;Gtdp8N2Yz7bvprUjI6oCyzu%HM^6A=MX6qR0-W<(GhO%V(BE+CMi zDA>EG*MbVDDAsEiy;D{bfsOdUBdiVo-4qX4 zpdIiE`xo*5XiOGPNj&zyeuZaG!e?Y{@^eUHX8*fa{F?x1lf6OwYF0p`EK@<_|Kz(N? zaez2RoF*<3H;B8$W8xL@0e2RS$)NTgj8bYZMj5paqnxV1sG#;kZ5ed{a&oAB5Tlg(1*42Q zgi%f%#;BlR z?;*!pm2NvNAFiQC}Mj2m-QO-vg6?|3JB78N-fkpW07^VDH7-f77 zjB>svMg@F33Ui1rf*ja~uZ2;{*TyL0>tIyCP9=O&ejCVvUHEM=O8MV=dDSqm=J}QO0+~D2F>5378H6!6REb%IjCdcg)knV?*- zk*x!94;veBU?rm}SSeT`SSDC5SS463$QKj{3I%HfOGyVf%T?B6pUWeJ70zIYwMcRi zl&gZC7yQg0BAO1cUSfdH`@uS7m>>+E9UZ}waNGpp%9Ohx0;k49S)?-M4!>*W!IP%h zdeO?1yC4Rq*m|+blsojJ3+o*#Sc|#97y^k9xC1AH)>p1z4Ag1vX{<8kE{MY^wuN|Q z%3Y8Espg&%l__^Y5>B!8#wkQA@u15^g?tfh5X z{>UR5iRZ)%jw7eLU>>Ijr>9{4_jQmK(ndO{4Qh+pAzjoSbwGOmQb&joQblS=9koIl zNE5Y2BDM}(;XD|}&s}X84_qBBSh4BA`lcd+J`FO6a1A@qZeTet*wF9 z*!O+wrvUn8+n0XV1KWO!)|KPg!1e;%X$RBcAbA+pVMoa;gplLFaey5@4$SdP^cd+Q z17wJdkTEhr9Z@G_ip-EX>WsP|3)B@^A}eH#7$inE$QIcld(;g%AXn56^+)c=2l=C+ z$Px8KeUJj#eNiGz|4ZQ792* zqhK@=4M!u;XcU4XP$U|UCZH6QiqgVlP0UEv3SDxi_dDy8rx!b+*WSSfWdX-FD^Mk=e6>W`ID1F%x+5Ui9M z2GI)8wY>KEZ~gx#Kc*!{l?M-Sp296gB#aP%S`!Qn(afulF^297?&dpMklk8t!QKEsXI z1@j($kRG50>;;-IBS>%38`OY(NFPuG_9cBm4cL$L12y0PGJpsn10kvjC5Ms2 zKn-{}IULl0gUMh}10F?=0yW?eG6d9s*_bk#j36UG4LAzopI8zOPy-$dQP5a2o{R@i zPb3pT4R{vzHQ=e_R8Rv>C(}U(&6et z{DVy4x{?qdHRlq)=G5UHbCD`T?mn1p zT>n_zwkZdiB8q~i8xZ>~O^dR$Cox&PeM}ZtTEyjm7LCXjh8T2l{Hek78jUOQfP)yd zucIYZU|gwqnA{;eO2irBFBUPH6l4S<;n2|WF|i5J$%zSK4Mv?UgdgzwMMlIYCPaw! znGS4;P^3LDHe8Z8J~1lU&^1w#lqd;Jj)ix?Qxe$oTv6L^=L2HnBQ5=tL*tVSeO>!9 z`fb$2c8tA^t=K_qE4CjFS$oFuYnI8}@W+v{*2E*@4DI_Lj7W_^?AwuuH*k=zpV*A) z)ST5%aE(ohiIf=j^Y3ri-`}T)o4t*rrLBX5gQa6%hi>9dj7jq+>F~o(;vXqVi4Bir zvPk2WmW4YUHwz{?lnXgouw8mA&ZjoU|Kqca8~5iN-O@OXe_FrSW7WC#Grb=S?oqLG z^RiTzcb|LJ-o8>l>s^8iv2ujYbvnYa-tYa*dG8iWo%YR~pRjvo)tQh%wfR{K;}^D< zXl%ReIwi;}WaP2UL(Z68eewJL7ly}-yB3a}V;T2wBCl$|p(MItr{1PjbE!TPlisB~ zt?Q_jvUQ`Od3J}=Mvp~(N@g@=S62=`v(%8ARyVXlw8Llj_P9U;e|_zJwM?InJ;_s} zB{5CaFIPs{t{Z7QUoWBhN@SfyhmK`yrj%;To>3of73}rVbI)YwE&j)Dy6@R$;$!UI z;oPA;o+&Pp(+hIcJH9^LYY*M6&pQ9$z)zz?Ib4{b(kzk&i>NSqU{XDGo(@lIgt_jv zQxnv}oj$I7y;_^&pU$IWhH4Hw%YX&fQuX{3$5R^!25;6L%(T7cPj5dN5eGk)&0HOspq%0>QqcMe3Rc@yHl~L<;6Lf`;YD4 zToCZd9gVj1>GEpk!yT=5?0T}OGtk##ps({S=&L&Jf=z4tqqm2!)Js%|ooSVVVid;cJ%3%>G{)+jm5!WMb~0 zF!A3K)3R|RpHOb^rq>jV*yVP7^X=`L-MQskw8w|!KU%vpLAO_*&yjcRo-5==qXJjP z4ZFLjSQvcx+%-RI)yP$bq0au|{J8l>Q}@38B=YqOS=wX7o?-Ij(7vThZk3z*co#2E z@-!PYCAxZ${&?&H%TamZ!o=+`a4=?ZuebZ8GZI$T1Dl_V#(@P zo$OY;3Aow1yJKr>*;x6iX~)CPUaNiLWcOyzO?zhV<20Mn+ofeg270G^2Obfjl;`}n zC*8~5=U(uW>zluGvaGG0z9MH_q-O1mD!O0J?Zk#HAIhBj$xG*$^vUupxUek9R}|EC z{AX9ya*OlnjC1rCVhRCE1^;NGa$B&K!KnI?zIlN;2fTXK^6sylxufP_HZz!=+?qV# z3z-|!PyF5Wv1P=pE2)UOz)h~Zy+xRvjo2|tY-`yqDm>KEt~(QD**)CO!O}J=+}_?H zA}ZX@j`;%t)@a_ZuG_9NjI467venVq>6h}>f+R$aXqWnj~>Zw+eOc88vj9M zq`{6_wOs+n%^ip5HcUR$ZfBs)-uja@i?41+_qRwZGtVXp{Og!__Zte=-|+ zzw&eF@9pZ$g~kOpPbFm)wv}8qIXS7T>(kENcP&*hwT#HTmnsa;>qRVn!8(1lb<+=GEZrrFOAZ_ORL*q)f;Yf%yO;Zujs zj#=k!_$}|>xvkH#5e0ikx0gOQ^L@x)dOzMy&2i{82Xp(SJsk7TKN&M)q`I-@sL4#0 zN(JzpteNkGp|+;%-(wJj_&Z}Uqj6v+q!*daTKuAG1ldl93pY1$JEjfQvXK6I?-N@x z7R?ma@f(HtB_=|c2KTDisMzq(?2(+UyUV)B=JDqn zhh2P3E=Y*0_CtlUsy7;XzG{pq8#o|OzCUfixYh3bD<3=EESQj6yMBDX^h=pnU+#a= zO;#1$|JtTYd~2-r zm3HXUqU6r?Db@kkwV0qcb$MYQYpO=OiGBB&iS9ZxwUW*n=Elbze4L7GoEDracBEzm z`vhj0cTus~HQ>^q@P<0eu;=}q8p;I3?{39~XGhF6^}j!9z1Iu3T8Cbah1*kuSb9W&Vgpjf9oXr(B-z!e`(NN8ROf`WuA;X)4#~IsBcc6pXai#{w@L64hPT1 zEEe#EwSdJu7$D^@d0;WepJTD+H4Qsq*!cpj{wsfRNFu0v?{rhQO^*_tx7h3$^GMw~ zVV!5wqtO$dc=xotkV_?^7 zci^fKDJebb@Q|6=q>Cq{9NQujcgcXFdAWm5t}KY!W`mmWu8^ift$@>3ZOVg@$_M zyp>m9m%M9jN=G^_c|OU&Yv0-1f%nf$T-G+Y%3f#m^~HLg^DGaP+x6@4R6|>r7P3i2BFFE@%uKLj9BdB z%$&>bzP(+V?zWE~;vN~|?6cYBvCorjDQTC5c65A)46#AIdcgJHir@d{u2CMb;sKWh|k$to((}a>aDJmz!k>SgsB>om4I_zEr_abmJ4 zKJfRmFZ`_&13S&|ufspV-;4ue#{hxb+cMo*{ubk`EyHI2xn=&}vG=*RNHe&dzVEUR|GSrSBSCq zC+~kei{GkAowuTK)=7gJ+m15}Uc8F#(DlRQhFrae4L;K1Lni*!dGGqy(q~3(IbKe`87BH%{ga&Gk3ExE6W))#834ux9j^c3l=a5GhYTV1@ER^T)yqT(ei0; z>O?OEyZqz*w)bDK#)I&3kJ2>j9JOxw-E&l?SIOJyYc<`q=&UuT_u zVDkLkR_9xn%#9D*J(N@9V<_@nd3};|{m^}zhOO#wTaU~s+c)vWoHLJml27Xo%onPh z$n&Ug^w+*VXv3nr4S8cOWE{G;$Fv;oj458@eVPWXJ#!I`~ zJo1^7UTJSJN_y~7#Z=@n`Mkfx=qXdZZ(?Nd2(pb(OTF%j){57?_CyWaW@+86{A8(M=h>myNSL?d%x3`a{?zkgc zmu$b=r*fQ0Ytt0e%Wv+u;cl*472CFL9vFRMjmzhZG^30{Z6@lzOY2d(Ckl;?&bU6X zc(Cu4$H}heFWY2zn|AT&IC}WQz-NjZD+{W7B<{~NOQtlRrWhSuops18VCR-GPP2+r zLboRrixdafyEnE@{5abtZtJI;gHOygsfyZPpf|I11jos8Q_%d~ca47AvAH^Y`@{g1 z^L?#+%a&}GPu#GrXxRkaUl+|3O)$2$Stm#+8Zo!i!J=o=tBo!`(jQc{>Z#|gCNeT{ z7Mgk@_Qbt}hijLg7I*%vUO6K8^1$}Rm)}_z_OTkGGqy@3{V2}jmBaQ$DQx^QFx~#S zeTn8>-|x3gzU@R8WgcV0HRX;q%@wP**oWr9zV5euY9v-?TAtNrgTXIvm&@R>lP> zq0yYW^DlfN^lgk*5a&0R7@Tg$SWbB5mVRRG?+HheiaE2Sl8omY7752lR%hn_(jaUy zepBGoX406NRWA>`e!Vs%#Me0~A^i#UqBO^$bIqr89h-gSIh_WkYYup6?m(((hSa?t zq`qs9`|wwj`Hwv83#z7%TZQ&5Sy+0e(t6;W&wUC<96eky@wCs@brlO7oOcfw&%Nhz z>!T+f_-oxc`eRb;VQq)}_KIDNuJ$$h!vY?^f2dVa*#G{bUws$7T6ri>b=A`YgKP{Y z-5$Hl0;bO|#pO5bezk8nyj(4;%Iiw)ke!?gdE11`8h5$$vKuvi)3S=QIOa?ir{lM) zM2WLF+EAp4{c_$v76<(JyNDKEIg)AnZPZ*b`kLXB;FDjyPDR`be^J0LRBaf0J7)O5 z_~eA-StGUt@1GEqT;%rVl&8f;^8rU%`U-5evc6J0wRUNYR;b^^T@49M)zd%DOsYTk zCaTqiGiBTQx$Pj{C3#dYxTpK*J}L3y75JN4?;82eMTyRT>KdY_x8 zm2=0eRS5?L9vi*0y^69w6;9jmY|Iiw3M`w$LN!fjDEK}@#f{&rAlXi$| zbNaoe@2%;wMW^UCb?PK{nuvS%;S$}^>ajDXoX-;Ni%+=uIbhSUMH%;X3?hxK9(+7r sV54P2HTAQz@Xrp+tQ + + + + + + + + + + + + + + + + diff --git a/attic/macui/ZeroTier One/Network.h b/attic/macui/ZeroTier One/Network.h new file mode 100644 index 0000000..c1cfbaf --- /dev/null +++ b/attic/macui/ZeroTier One/Network.h @@ -0,0 +1,69 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +enum NetworkStatus { + REQUESTING_CONFIGURATION, + OK, + ACCESS_DENIED, + NOT_FOUND, + PORT_ERROR, + CLIENT_TOO_OLD, +}; + +enum NetworkType { + PUBLIC, + PRIVATE, +}; + +@interface Network : NSObject + +@property (readonly) NSArray *assignedAddresses; +@property (readonly) BOOL bridge; +@property (readonly) BOOL broadcastEnabled; +@property (readonly) BOOL dhcp; +@property (readonly) NSString *mac; +@property (readonly) int mtu; +@property (readonly) int netconfRevision; +@property (readonly) NSString *name; +@property (readonly) UInt64 nwid; +@property (readonly) NSString *portDeviceName; +@property (readonly) int portError; +@property (readonly) enum NetworkStatus status; +@property (readonly) enum NetworkType type; +@property (readonly) BOOL allowManaged; +@property (readonly) BOOL allowGlobal; +@property (readonly) BOOL allowDefault; +@property (readonly) BOOL allowDNS; +@property (readonly) BOOL connected; // not persisted. set to YES if loaded via json + +- (id)initWithJsonData:(NSDictionary*)jsonData; +- (id)initWithCoder:(NSCoder *)aDecoder; +- (void)encodeWithCoder:(NSCoder *)aCoder; ++ (BOOL)defaultRouteExists:(NSArray*)netList; +- (NSString*)statusString; +- (NSString*)typeString; + +- (BOOL)hasSameNetworkId:(UInt64)networkId; + +- (BOOL)isEqualToNetwork:(Network*)network; +- (BOOL)isEqual:(id)object; +- (NSUInteger)hash; + +@end diff --git a/attic/macui/ZeroTier One/Network.m b/attic/macui/ZeroTier One/Network.m new file mode 100644 index 0000000..2379eb6 --- /dev/null +++ b/attic/macui/ZeroTier One/Network.m @@ -0,0 +1,352 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import "Network.h" + +NSString *NetworkAddressesKey = @"addresses"; +NSString *NetworkBridgeKey = @"bridge"; +NSString *NetworkBroadcastKey = @"broadcast"; +NSString *NetworkDhcpKey = @"dhcp"; +NSString *NetworkMacKey = @"mac"; +NSString *NetworkMtuKey = @"mtu"; +NSString *NetworkMulticastKey = @"multicast"; +NSString *NetworkNameKey = @"name"; +NSString *NetworkNetconfKey = @"netconf"; +NSString *NetworkNwidKey = @"nwid"; +NSString *NetworkPortNameKey = @"port"; +NSString *NetworkPortErrorKey = @"portError"; +NSString *NetworkStatusKey = @"status"; +NSString *NetworkTypeKey = @"type"; +NSString *NetworkAllowManagedKey = @"allowManaged"; +NSString *NetworkAllowGlobalKey = @"allowGlobal"; +NSString *NetworkAllowDefaultKey = @"allowDefault"; +NSString *NetworkAllowDNSKey = @"allowDNS"; + +@implementation Network + +- (id)initWithJsonData:(NSDictionary*)jsonData +{ + self = [super init]; + + if(self) { + if([jsonData objectForKey:@"assignedAddresses"]) { + _assignedAddresses = (NSArray*)[jsonData objectForKey:@"assignedAddresses"]; + } + + if([jsonData objectForKey:@"bridge"]) { + _bridge = [(NSNumber*)[jsonData objectForKey:@"bridge"] boolValue]; + } + + if([jsonData objectForKey:@"broadcastEnabled"]) { + _broadcastEnabled = [(NSNumber*)[jsonData objectForKey:@"broadcastEnabled"] boolValue]; + } + + if([jsonData objectForKey:@"dhcp"]) { + _dhcp = [(NSNumber*)[jsonData objectForKey:@"dhcp"] boolValue]; + } + + if([jsonData objectForKey:@"mac"]) { + _mac = (NSString*)[jsonData objectForKey:@"mac"]; + } + + if([jsonData objectForKey:@"mtu"]) { + _mtu = [(NSNumber*)[jsonData objectForKey:@"mtu"] intValue]; + } + + if([jsonData objectForKey:@"name"]) { + _name = (NSString*)[jsonData objectForKey:@"name"]; + } + + if([jsonData objectForKey:@"netconfRevision"]) { + _netconfRevision = [(NSNumber*)[jsonData objectForKey:@"netconfRevision"] intValue]; + } + + if([jsonData objectForKey:@"nwid"]) { + NSString *networkid = (NSString*)[jsonData objectForKey:@"nwid"]; + + NSScanner *scanner = [NSScanner scannerWithString:networkid]; + [scanner scanHexLongLong:&_nwid]; + } + + if([jsonData objectForKey:@"portDeviceName"]) { + _portDeviceName = (NSString*)[jsonData objectForKey:@"portDeviceName"]; + } + + if([jsonData objectForKey:@"portError"]) { + _portError = [(NSNumber*)[jsonData objectForKey:@"portError"] intValue]; + } + + if([jsonData objectForKey:@"allowManaged"]) { + _allowManaged = [(NSNumber*)[jsonData objectForKey:@"allowManaged"] boolValue]; + } + + if([jsonData objectForKey:@"allowGlobal"]) { + _allowGlobal = [(NSNumber*)[jsonData objectForKey:@"allowGlobal"] boolValue]; + } + + if([jsonData objectForKey:@"allowDefault"]) { + _allowDefault = [(NSNumber*)[jsonData objectForKey:@"allowDefault"] boolValue]; + } + if([jsonData objectForKey:@"allowDNS"]) { + _allowDNS = [(NSNumber*)[jsonData objectForKey:@"allowDNS"] boolValue]; + } else { + _allowDNS = false; + } + + if([jsonData objectForKey:@"status"]) { + NSString *statusStr = (NSString*)[jsonData objectForKey:@"status"]; + if([statusStr isEqualToString:@"REQUESTING_CONFIGURATION"]) { + _status = REQUESTING_CONFIGURATION; + } + else if([statusStr isEqualToString:@"OK"]) { + _status = OK; + } + else if([statusStr isEqualToString:@"ACCESS_DENIED"]) { + _status = ACCESS_DENIED; + } + else if([statusStr isEqualToString:@"NOT_FOUND"]) { + _status = NOT_FOUND; + } + else if([statusStr isEqualToString:@"PORT_ERROR"]) { + _status = PORT_ERROR; + } + else if([statusStr isEqualToString:@"CLIENT_TOO_OLD"]) { + _status = CLIENT_TOO_OLD; + } + } + + if([jsonData objectForKey:@"type"]) { + NSString *typeStr = (NSString*)[jsonData objectForKey:@"type"]; + if([typeStr isEqualToString:@"PRIVATE"]) { + _type = PRIVATE; + } + else if([typeStr isEqualToString:@"PUBLIC"]) { + _type = PUBLIC; + } + } + + _connected = YES; + } + + return self; +} +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super init]; + + if(self) { + if([aDecoder containsValueForKey:NetworkAddressesKey]) { + _assignedAddresses = (NSArray*)[aDecoder decodeObjectForKey:NetworkAddressesKey]; + } + + if([aDecoder containsValueForKey:NetworkBridgeKey]) { + _bridge = [aDecoder decodeBoolForKey:NetworkBridgeKey]; + } + + if([aDecoder containsValueForKey:NetworkBroadcastKey]) { + _broadcastEnabled = [aDecoder decodeBoolForKey:NetworkBroadcastKey]; + } + + if([aDecoder containsValueForKey:NetworkDhcpKey]) { + _dhcp = [aDecoder decodeBoolForKey:NetworkDhcpKey]; + } + + if([aDecoder containsValueForKey:NetworkMacKey]) { + _mac = (NSString*)[aDecoder decodeObjectForKey:NetworkMacKey]; + } + + if([aDecoder containsValueForKey:NetworkMtuKey]) { + _mtu = (int)[aDecoder decodeIntegerForKey:NetworkMtuKey]; + } + + if([aDecoder containsValueForKey:NetworkNameKey]) { + _name = (NSString*)[aDecoder decodeObjectForKey:NetworkNameKey]; + } + + if([aDecoder containsValueForKey:NetworkNetconfKey]) { + _netconfRevision = (int)[aDecoder decodeIntegerForKey:NetworkNetconfKey]; + } + + if([aDecoder containsValueForKey:NetworkNwidKey]) { + _nwid = [(NSNumber*)[aDecoder decodeObjectForKey:NetworkNwidKey] unsignedLongLongValue]; + } + + if([aDecoder containsValueForKey:NetworkPortNameKey]) { + _portDeviceName = (NSString*)[aDecoder decodeObjectForKey:NetworkPortNameKey]; + } + + if([aDecoder containsValueForKey:NetworkPortErrorKey]) { + _portError = (int)[aDecoder decodeIntegerForKey:NetworkPortErrorKey]; + } + + if([aDecoder containsValueForKey:NetworkStatusKey]) { + _status = (enum NetworkStatus)[aDecoder decodeIntegerForKey:NetworkStatusKey]; + } + + if([aDecoder containsValueForKey:NetworkTypeKey]) { + _type = (enum NetworkType)[aDecoder decodeIntegerForKey:NetworkTypeKey]; + } + + if([aDecoder containsValueForKey:NetworkAllowManagedKey]) { + _allowManaged = [aDecoder decodeBoolForKey:NetworkAllowManagedKey]; + } + + if([aDecoder containsValueForKey:NetworkAllowGlobalKey]) { + _allowGlobal = [aDecoder decodeBoolForKey:NetworkAllowGlobalKey]; + } + + if([aDecoder containsValueForKey:NetworkAllowDefaultKey]) { + _allowDefault = [aDecoder decodeBoolForKey:NetworkAllowDefaultKey]; + } + + if([aDecoder containsValueForKey:NetworkAllowDNSKey]) { + _allowDNS = [aDecoder decodeBoolForKey:NetworkAllowDNSKey]; + } else { + _allowDNS = false; + } + + _connected = NO; + } + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + [aCoder encodeObject:_assignedAddresses forKey:NetworkAddressesKey]; + [aCoder encodeBool:_bridge forKey:NetworkBridgeKey]; + [aCoder encodeBool:_broadcastEnabled forKey:NetworkBroadcastKey]; + [aCoder encodeBool:_dhcp forKey:NetworkDhcpKey]; + [aCoder encodeObject:_mac forKey:NetworkMacKey]; + [aCoder encodeInteger:_mtu forKey:NetworkMtuKey]; + [aCoder encodeObject:_name forKey:NetworkNameKey]; + [aCoder encodeInteger:_netconfRevision forKey:NetworkNetconfKey]; + [aCoder encodeObject:[NSNumber numberWithUnsignedLongLong:_nwid] + forKey:NetworkNwidKey]; + [aCoder encodeObject:_portDeviceName forKey:NetworkPortNameKey]; + [aCoder encodeInteger:_portError forKey:NetworkPortErrorKey]; + [aCoder encodeInteger:_status forKey:NetworkStatusKey]; + [aCoder encodeInteger:_type forKey:NetworkTypeKey]; + [aCoder encodeBool:_allowManaged forKey:NetworkAllowManagedKey]; + [aCoder encodeBool:_allowGlobal forKey:NetworkAllowGlobalKey]; + [aCoder encodeBool:_allowDefault forKey:NetworkAllowDefaultKey]; + [aCoder encodeBool:_allowDNS forKey:NetworkAllowDNSKey]; +} + ++ (BOOL)defaultRouteExists:(NSArray*)netList +{ + for(Network *net in netList) { + if (net.allowDefault && net.connected) { + return YES; + } + } + return NO; +} + +- (NSString*)statusString { + switch(_status) { + case REQUESTING_CONFIGURATION: + return @"REQUESTING_CONFIGURATION"; + case OK: + return @"OK"; + case ACCESS_DENIED: + return @"ACCESS_DENIED"; + case NOT_FOUND: + return @"NOT_FOUND"; + case PORT_ERROR: + return @"PORT_ERROR"; + case CLIENT_TOO_OLD: + return @"CLIENT_TOO_OLD"; + default: + return @""; + } +} + +- (NSString*)typeString { + switch(_type) { + case PUBLIC: + return @"PUBLIC"; + case PRIVATE: + return @"PRIVATE"; + default: + return @""; + } +} + +- (BOOL)hasSameNetworkId:(UInt64)networkId +{ + return self.nwid == networkId; +} + +- (BOOL)isEqualToNetwork:(Network*)network +{ + return [self.assignedAddresses isEqualToArray:network.assignedAddresses] && + self.bridge == network.bridge && + self.broadcastEnabled == network.broadcastEnabled && + self.dhcp == network.dhcp && + [self.mac isEqualToString:network.mac] && + self.mtu == network.mtu && + self.netconfRevision == network.netconfRevision && + [self.name isEqualToString:network.name] && + self.nwid == network.nwid && + [self.portDeviceName isEqualToString:network.portDeviceName] && + self.status == network.status && + self.type == network.type && + self.allowManaged == network.allowManaged && + self.allowGlobal == network.allowGlobal && + self.allowDefault == network.allowDefault && + self.allowDNS == network.allowDNS && + self.connected == network.connected; +} + +- (BOOL)isEqual:(id)object +{ + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[Network class]]) { + return NO; + } + + return [self isEqualToNetwork:object]; +} + +- (NSUInteger)hash +{ + return [self.assignedAddresses hash] ^ + self.bridge ^ + self.broadcastEnabled ^ + self.dhcp ^ + [self.mac hash] ^ + self.mtu ^ + self.netconfRevision ^ + [self.name hash] ^ + self.nwid ^ + [self.portDeviceName hash] ^ + self.portError ^ + self.status ^ + self.type ^ + self.allowManaged ^ + self.allowGlobal ^ + self.allowDefault ^ + self.allowDNS ^ + self.connected; +} + +@end diff --git a/attic/macui/ZeroTier One/NetworkInfoCell.h b/attic/macui/ZeroTier One/NetworkInfoCell.h new file mode 100644 index 0000000..f764034 --- /dev/null +++ b/attic/macui/ZeroTier One/NetworkInfoCell.h @@ -0,0 +1,51 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +@class ShowNetworksViewController; + +@interface NetworkInfoCell : NSTableCellView + +@property (weak, nonatomic) ShowNetworksViewController *parent; + +@property (weak, nonatomic) IBOutlet NSTextField *networkIdField; +@property (weak, nonatomic) IBOutlet NSTextField *networkNameField; +@property (weak, nonatomic) IBOutlet NSTextField *statusField; +@property (weak, nonatomic) IBOutlet NSTextField *typeField; +@property (weak, nonatomic) IBOutlet NSTextField *macField; +@property (weak, nonatomic) IBOutlet NSTextField *mtuField; +@property (weak, nonatomic) IBOutlet NSTextField *broadcastField; +@property (weak, nonatomic) IBOutlet NSTextField *bridgingField; +@property (weak, nonatomic) IBOutlet NSTextField *deviceField; +@property (weak, nonatomic) IBOutlet NSTextField *addressesField; +@property (weak, nonatomic) IBOutlet NSButton *allowManaged; +@property (weak, nonatomic) IBOutlet NSButton *allowGlobal; +@property (weak, nonatomic) IBOutlet NSButton *allowDefault; +@property (weak, nonatomic) IBOutlet NSButton *allowDNS; +@property (weak, nonatomic) IBOutlet NSButton *connectedCheckbox; +@property (weak, nonatomic) IBOutlet NSButton *deleteButton; + +- (IBAction)onConnectCheckStateChanged:(NSButton*)sender; +- (IBAction)deleteNetwork:(NSButton*)sender; +- (IBAction)onAllowStatusChanged:(NSButton*)sender; + +- (void)joinNetwork:(NSString*)nwid; +- (void)leaveNetwork:(NSString*)nwid; + +@end diff --git a/attic/macui/ZeroTier One/NetworkInfoCell.m b/attic/macui/ZeroTier One/NetworkInfoCell.m new file mode 100644 index 0000000..df1bbf6 --- /dev/null +++ b/attic/macui/ZeroTier One/NetworkInfoCell.m @@ -0,0 +1,86 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import "NetworkInfoCell.h" +#import "ServiceCom.h" +#import "ShowNetworksViewController.h" +#import "Network.h" + +@implementation NetworkInfoCell + +- (void)drawRect:(NSRect)dirtyRect { + [super drawRect:dirtyRect]; + + // Drawing code here. +} + +- (IBAction)onConnectCheckStateChanged:(NSButton*)sender +{ + if(sender.state == NSOnState) { + [self joinNetwork:self.networkIdField.stringValue]; + } + else { + [self leaveNetwork:self.networkIdField.stringValue]; + } +} + +- (IBAction)deleteNetwork:(NSButton*)sender; +{ + [self leaveNetwork:self.networkIdField.stringValue]; + [self.parent deleteNetworkFromList:self.networkIdField.stringValue]; +} + +- (IBAction)onAllowStatusChanged:(NSButton*)sender +{ + [self joinNetwork:self.networkIdField.stringValue]; +} + +- (void)joinNetwork:(NSString*)nwid +{ + NSError *error = nil; + [[ServiceCom sharedInstance] joinNetwork:nwid + allowManaged:(self.allowManaged.state == NSOnState) + allowGlobal:(self.allowGlobal.state == NSOnState) + allowDefault:![Network defaultRouteExists:_parent.networkList] && (self.allowDefault.state == NSOnState) + allowDNS:(self.allowDNS.state == NSOnState) + error:&error]; + + if (error) { + NSAlert *alert = [NSAlert alertWithError:error]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Ok"]; + + [alert runModal]; + } +} + +- (void)leaveNetwork:(NSString*)nwid +{ + NSError *error = nil; + [[ServiceCom sharedInstance] leaveNetwork:nwid error:&error]; + + if (error) { + NSAlert *alert = [NSAlert alertWithError:error]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Ok"]; + + [alert runModal]; + } +} + +@end diff --git a/attic/macui/ZeroTier One/NetworkMonitor.h b/attic/macui/ZeroTier One/NetworkMonitor.h new file mode 100644 index 0000000..8cdec4e --- /dev/null +++ b/attic/macui/ZeroTier One/NetworkMonitor.h @@ -0,0 +1,45 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +extern NSString * const NetworkUpdateKey; +extern NSString * const StatusUpdateKey; + +@class Network; + +@interface NetworkMonitor : NSObject +{ + NSMutableArray *_savedNetworks; + NSArray *_receivedNetworks; + NSMutableArray *_allNetworks; + + NSTimer *_timer; +} + +- (id)init; +- (void)dealloc; + +- (void)start; +- (void)stop; + +- (void)updateNetworkInfo; + +- (void)deleteSavedNetwork:(NSString*)networkId; + +@end diff --git a/attic/macui/ZeroTier One/NetworkMonitor.m b/attic/macui/ZeroTier One/NetworkMonitor.m new file mode 100644 index 0000000..7ed22c4 --- /dev/null +++ b/attic/macui/ZeroTier One/NetworkMonitor.m @@ -0,0 +1,253 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import "NetworkMonitor.h" +#import "Network.h" +#import "ServiceCom.h" +#import "NodeStatus.h" + +@import AppKit; + + +NSString * const NetworkUpdateKey = @"com.zerotier.one.network-list"; +NSString * const StatusUpdateKey = @"com.zerotier.one.status"; + +@interface NetworkMonitor (private) + +- (NSString*)dataFile; +- (void)internal_updateNetworkInfo; +- (NSInteger)findNetworkWithID:(UInt64)networkId; +- (NSInteger)findSavedNetworkWithID:(UInt64)networkId; +- (void)saveNetworks; + +@end + +@implementation NetworkMonitor + +- (id)init +{ + self = [super init]; + if(self) + { + _savedNetworks = [NSMutableArray array]; + _receivedNetworks = [NSArray array]; + _allNetworks = [NSMutableArray array]; + _timer = nil; + } + + return self; +} + +- (void)dealloc +{ + [_timer invalidate]; +} + +- (void)start +{ + NSLog(@"ZeroTier monitor started"); + _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f + target:self + selector:@selector(updateNetworkInfo) + userInfo:nil + repeats:YES]; +} + +- (void)stop +{ + NSLog(@"ZeroTier monitor stopped"); + [_timer invalidate]; + _timer = nil; +} + +- (void)updateNetworkInfo +{ + NSString *filePath = [self dataFile]; + + if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { + NSArray *networks = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; + + if(networks != nil) { + _savedNetworks = [networks mutableCopy]; + } + } + + NSError *error = nil; + + [[ServiceCom sharedInstance] getNetworklist:^(NSArray *networkList) { + _receivedNetworks = networkList; + + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + [self internal_updateNetworkInfo]; + } ]; + } error:&error]; + + if(error) { + [self stop]; + + NSAlert *alert = [NSAlert alertWithError:error]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Retry"]; + + NSModalResponse res = [alert runModal]; + + if(res == NSAlertFirstButtonReturn) { + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + } + else if(res == NSAlertSecondButtonReturn) { + [self start]; + return; + } + } + + [[ServiceCom sharedInstance] getNodeStatus:^(NodeStatus *status) { + NSDictionary *userInfo = [NSDictionary dictionaryWithObject:status forKey:@"status"]; + + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + [[NSNotificationCenter defaultCenter] postNotificationName:StatusUpdateKey + object:nil + userInfo:userInfo]; + }]; + } error:&error]; + + if (error) { + [self stop]; + + NSAlert *alert = [NSAlert alertWithError:error]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Retry"]; + + NSModalResponse res = [alert runModal]; + + if(res == NSAlertFirstButtonReturn) { + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + } + else if(res == NSAlertSecondButtonReturn) { + [self start]; + return; + } + } +} + +- (void)deleteSavedNetwork:(NSString*)networkId +{ + UInt64 nwid = 0; + NSScanner *scanner = [NSScanner scannerWithString:networkId]; + [scanner scanHexLongLong:&nwid]; + + NSInteger index = [self findNetworkWithID:nwid]; + + if(index != NSNotFound) { + [_allNetworks removeObjectAtIndex:index]; + } + + index = [self findSavedNetworkWithID:nwid]; + + if(index != NSNotFound) { + [_savedNetworks removeObjectAtIndex:index]; + } + + [self saveNetworks]; +} + +@end + +@implementation NetworkMonitor (private) +- (NSString*)dataFile +{ + NSURL *appSupport = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory + inDomains:NSUserDomainMask] objectAtIndex:0]; + + appSupport = [[[appSupport URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"] URLByAppendingPathComponent:@"networkinfo.dat"]; + return appSupport.path; +} + +- (void)internal_updateNetworkInfo +{ + NSMutableArray *networks = [_savedNetworks mutableCopy]; + + for(Network *nw in _receivedNetworks) { + NSInteger index = [self findSavedNetworkWithID:nw.nwid]; + + if(index != NSNotFound) { + [networks setObject:nw atIndexedSubscript:index]; + } + else { + [networks addObject:nw]; + } + } + + [networks sortUsingComparator:^NSComparisonResult(Network *obj1, Network *obj2) { + if(obj1.nwid > obj2.nwid) { + return true; + } + return false; + }]; + + @synchronized(_allNetworks) { + _allNetworks = networks; + } + + [self saveNetworks]; + + NSDictionary *userInfo = [NSDictionary dictionaryWithObject:networks forKey:@"networks"]; + + [[NSNotificationCenter defaultCenter] postNotificationName:NetworkUpdateKey + object:nil + userInfo:userInfo]; +} + +- (NSInteger)findNetworkWithID:(UInt64)networkId +{ + for(int i = 0; i < [_allNetworks count]; ++i) { + Network *nw = [_allNetworks objectAtIndex:i]; + + if(nw.nwid == networkId) { + return i; + } + } + + return NSNotFound; +} + + +- (NSInteger)findSavedNetworkWithID:(UInt64)networkId +{ + for(int i = 0; i < [_savedNetworks count]; ++i) { + Network *nw = [_savedNetworks objectAtIndex:i]; + + if(nw.nwid == networkId) { + return i; + } + } + + return NSNotFound; +} + +- (void)saveNetworks +{ + NSString *filePath = [self dataFile]; + + @synchronized(_allNetworks) { + [NSKeyedArchiver archiveRootObject:_allNetworks toFile:filePath]; + } +} + +@end diff --git a/attic/macui/ZeroTier One/NodeStatus.h b/attic/macui/ZeroTier One/NodeStatus.h new file mode 100644 index 0000000..eab5bfe --- /dev/null +++ b/attic/macui/ZeroTier One/NodeStatus.h @@ -0,0 +1,35 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +@interface NodeStatus : NSObject + +@property (readonly) NSString *address; +@property (readonly) NSString *publicIdentity; +@property (readonly) BOOL online; +@property (readonly) BOOL tcpFallbackActive; +@property (readonly) int versionMajor; +@property (readonly) int versionMinor; +@property (readonly) int versionRev; +@property (readonly) NSString *version; +@property (readonly) UInt64 clock; + +- (id)initWithJsonData:(NSDictionary*)jsonData; + +@end diff --git a/attic/macui/ZeroTier One/NodeStatus.m b/attic/macui/ZeroTier One/NodeStatus.m new file mode 100644 index 0000000..3bae3c7 --- /dev/null +++ b/attic/macui/ZeroTier One/NodeStatus.m @@ -0,0 +1,40 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#import "NodeStatus.h" + +@implementation NodeStatus + +- (id)initWithJsonData:(NSDictionary*)jsonData +{ + self = [super init]; + + if(self) { + _address = (NSString*)[jsonData objectForKey:@"address"]; + _publicIdentity = (NSString*)[jsonData objectForKey:@"publicIdentity"]; + _online = [(NSNumber*)[jsonData objectForKey:@"online"] boolValue]; + _tcpFallbackActive = [(NSNumber*)[jsonData objectForKey:@"tcpFallbackActive"] boolValue]; + _versionMajor = [(NSNumber*)[jsonData objectForKey:@"versionMajor"] intValue]; + _versionMinor = [(NSNumber*)[jsonData objectForKey:@"versionMinor"] intValue]; + _versionRev = [(NSNumber*)[jsonData objectForKey:@"versionRev"] intValue]; + _version = (NSString*)[jsonData objectForKey:@"version"]; + _clock = [(NSNumber*)[jsonData objectForKey:@"clock"] unsignedLongLongValue]; + } + + return self; +} +@end diff --git a/attic/macui/ZeroTier One/PreferencesViewController.h b/attic/macui/ZeroTier One/PreferencesViewController.h new file mode 100644 index 0000000..56d0fdb --- /dev/null +++ b/attic/macui/ZeroTier One/PreferencesViewController.h @@ -0,0 +1,31 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +@interface PreferencesViewController : NSViewController + +@property (nonatomic, weak) IBOutlet NSButton *startupCheckBox; + +- (IBAction)onStartupCheckBoxChanged:(NSButton*)sender; + +- (BOOL)isLaunchAtStartup; +- (LSSharedFileListItemRef)itemRefInLoginItems; +- (void)setLaunchAtLoginEnabled:(BOOL)enabled; + +@end diff --git a/attic/macui/ZeroTier One/PreferencesViewController.m b/attic/macui/ZeroTier One/PreferencesViewController.m new file mode 100644 index 0000000..13927fb --- /dev/null +++ b/attic/macui/ZeroTier One/PreferencesViewController.m @@ -0,0 +1,112 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import "PreferencesViewController.h" + +@interface PreferencesViewController () + +@end + +@implementation PreferencesViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + if([self isLaunchAtStartup]) { + self.startupCheckBox.state = NSOnState; + } + else { + self.startupCheckBox.state = NSOffState; + } +} + +- (IBAction)onStartupCheckBoxChanged:(NSButton *)sender +{ + if(sender.state == NSOnState) { + [self setLaunchAtLoginEnabled:YES]; + } + else { + [self setLaunchAtLoginEnabled:NO]; + } + +} + +- (void)setLaunchAtLoginEnabled:(BOOL)enabled +{ + LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); + + if (enabled) { + // Add the app to the LoginItems list. + CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; + LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL); + if (itemRef) CFRelease(itemRef); + } + else { + // Remove the app from the LoginItems list. + LSSharedFileListItemRef itemRef = [self itemRefInLoginItems]; + LSSharedFileListItemRemove(loginItemsRef,itemRef); + if (itemRef != nil) CFRelease(itemRef); + } +} + + +- (BOOL)isLaunchAtStartup { + // See if the app is currently in LoginItems. + LSSharedFileListItemRef itemRef = [self itemRefInLoginItems]; + // Store away that boolean. + BOOL isInList = itemRef != nil; + // Release the reference if it exists. + if (itemRef != nil) CFRelease(itemRef); + + return isInList; +} + +- (LSSharedFileListItemRef)itemRefInLoginItems { + LSSharedFileListItemRef itemRef = nil; + + NSString * appPath = [[NSBundle mainBundle] bundlePath]; + + // This will retrieve the path for the application + // For example, /Applications/test.app + CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:appPath]; + + // Create a reference to the shared file list. + LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); + + if (loginItems) { + UInt32 seedValue; + //Retrieve the list of Login Items and cast them to + // a NSArray so that it will be easier to iterate. + NSArray *loginItemsArray = (__bridge NSArray *)LSSharedFileListCopySnapshot(loginItems, &seedValue); + for(int i = 0; i< [loginItemsArray count]; i++){ + LSSharedFileListItemRef currentItemRef = (__bridge LSSharedFileListItemRef)[loginItemsArray + objectAtIndex:i]; + //Resolve the item with URL + if (LSSharedFileListItemResolve(currentItemRef, 0, (CFURLRef*) &url, NULL) == noErr) { + NSString * urlPath = [(__bridge NSURL*)url path]; + if ([urlPath compare:appPath] == NSOrderedSame){ + itemRef = currentItemRef; + } + } + } + } + CFRelease(loginItems); + return itemRef; +} + +@end diff --git a/attic/macui/ZeroTier One/PreferencesViewController.xib b/attic/macui/ZeroTier One/PreferencesViewController.xib new file mode 100644 index 0000000..62aef4c --- /dev/null +++ b/attic/macui/ZeroTier One/PreferencesViewController.xib @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/attic/macui/ZeroTier One/ServiceCom.h b/attic/macui/ZeroTier One/ServiceCom.h new file mode 100644 index 0000000..17b738e --- /dev/null +++ b/attic/macui/ZeroTier One/ServiceCom.h @@ -0,0 +1,40 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +@class NodeStatus; +@class Network; + +@interface ServiceCom : NSObject +{ + NSString *baseURL; + NSURLSession *session; + BOOL _isQuitting; + BOOL _resetKey; +} ++ (ServiceCom*)sharedInstance; + +- (id)init; + +- (void)getNetworklist:(void (^)(NSArray*))completionHandler error:(NSError* __autoreleasing *)error; +- (void)getNodeStatus:(void (^)(NodeStatus*))completionHandler error:(NSError*__autoreleasing*)error; +- (void)joinNetwork:(NSString*)networkId allowManaged:(BOOL)allowManaged allowGlobal:(BOOL)allowGlobal allowDefault:(BOOL)allowDefault allowDNS:(BOOL)allowDNS error:(NSError*__autoreleasing*)error; +- (void)leaveNetwork:(NSString*)networkId error:(NSError*__autoreleasing*)error; + +@end diff --git a/attic/macui/ZeroTier One/ServiceCom.m b/attic/macui/ZeroTier One/ServiceCom.m new file mode 100644 index 0000000..55d6774 --- /dev/null +++ b/attic/macui/ZeroTier One/ServiceCom.m @@ -0,0 +1,522 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import "ServiceCom.h" +#import "AuthtokenCopy.h" +#import "Network.h" +#import "NodeStatus.h" +@import AppKit; + +@interface ServiceCom (Private) + +- (NSString*)key; + +@end + +@implementation ServiceCom + ++ (ServiceCom*)sharedInstance { + static ServiceCom *sc = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sc = [[ServiceCom alloc] init]; + }); + return sc; +} + +- (id)init +{ + self = [super init]; + if(self) { + baseURL = @"http://127.0.0.1:9993"; + session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]]; + _isQuitting = NO; + _resetKey = NO; + } + + return self; +} + +- (NSString*)key:(NSError* __autoreleasing *)err +{ + static NSString *k = nil; + static NSUInteger resetCount = 0; + + @synchronized (self) { + if (_isQuitting) { + return @""; + } + + if (_resetKey && k != nil) { + k = nil; + ++resetCount; + NSLog(@"ResetCount: %lu", (unsigned long)resetCount); + if (resetCount > 10) { + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + NSAlert *alert = [NSAlert alertWithMessageText:@"Error obtaining Auth Token" + defaultButton:@"Quit" + alternateButton:@"Retry" + otherButton:nil + informativeTextWithFormat:@"Please ensure ZeroTier is installed correctly"]; + alert.alertStyle = NSCriticalAlertStyle; + + NSModalResponse res; + if (!_isQuitting) { + res = [alert runModal]; + } + else { + return; + } + + if(res == 1) { + _isQuitting = YES; + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + } + }]; + return @""; + } + } + + if (k == nil) { + NSError *error = nil; + NSURL *appSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:&error]; + + if (error) { + NSLog(@"Error: %@", error); + return @""; + } + + appSupportDir = [[appSupportDir URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"]; + NSURL *authtokenURL = [appSupportDir URLByAppendingPathComponent:@"authtoken.secret"]; + + if (!_resetKey && [[NSFileManager defaultManager] fileExistsAtPath:[authtokenURL path]]) { + k = [NSString stringWithContentsOfURL:authtokenURL + encoding:NSUTF8StringEncoding + error:&error]; + + k = [k stringByReplacingOccurrencesOfString:@"\n" withString:@""]; + + if (error) { + NSLog(@"Error: %@", error); + k = nil; + *err = error; + return @""; + } + } + else { + _resetKey = NO; + NSURL *sysAppSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSSystemDomainMask appropriateForURL:nil create:false error:nil]; + + sysAppSupportDir = [[sysAppSupportDir URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"]; + NSURL *sysAuthtokenURL = [sysAppSupportDir URLByAppendingPathComponent:@"authtoken.secret"]; + + if(![[NSFileManager defaultManager] fileExistsAtPath:[sysAuthtokenURL path]]) { + + } + + [[NSFileManager defaultManager] createDirectoryAtURL:appSupportDir + withIntermediateDirectories:YES + attributes:nil + error:&error]; + + if (error) { + NSLog(@"Error: %@", error); + *err = error; + k = nil; + return @""; + } + + AuthorizationRef authRef; + OSStatus status = AuthorizationCreate(nil, nil, kAuthorizationFlagDefaults, &authRef); + + if (status != errAuthorizationSuccess) { + NSLog(@"Authorization Failed! %d", status); + + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't create AuthorizationRef", nil), + }; + *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo]; + + return @""; + } + + AuthorizationItem authItem; + authItem.name = kAuthorizationRightExecute; + authItem.valueLength = 0; + authItem.flags = 0; + + AuthorizationRights authRights; + authRights.count = 1; + authRights.items = &authItem; + + AuthorizationFlags authFlags = kAuthorizationFlagDefaults | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagPreAuthorize | + kAuthorizationFlagExtendRights; + + status = AuthorizationCopyRights(authRef, &authRights, nil, authFlags, nil); + + if (status != errAuthorizationSuccess) { + NSLog(@"Authorization Failed! %d", status); + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't copy authorization rights", nil), + }; + *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo]; + return @""; + } + + NSString *localKey = getAdminAuthToken(authRef); + AuthorizationFree(authRef, kAuthorizationFlagDestroyRights); + + if (localKey != nil && [localKey lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > 0) { + k = localKey; + + [localKey writeToURL:authtokenURL + atomically:YES + encoding:NSUTF8StringEncoding + error:&error]; + + if (error) { + NSLog(@"Error writing token to disk: %@", error); + *err = error; + } + } + } + } + + if (k == nil) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Unknown error finding authorization key", nil), + }; + *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo]; + + return @""; + } + } + return k; +} + +- (void)getNetworklist:(void (^)(NSArray *))completionHandler error:(NSError *__autoreleasing*)error +{ + NSString* key = [self key:error]; + if(*error) { + return; + } + + NSString *urlString = [[baseURL stringByAppendingString:@"/network?auth="] stringByAppendingString:key]; + + NSURL *url = [NSURL URLWithString:urlString]; + NSURLSessionDataTask *task = + [session dataTaskWithURL:url + completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable err) { + + if (err) { + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + NSAlert *alert = [NSAlert alertWithError:err]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Retry"]; + + NSModalResponse res; + if (!_isQuitting) { + res = [alert runModal]; + } + else { + return; + } + + if(res == NSAlertFirstButtonReturn) { + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + _isQuitting = YES; + } + }]; + return; + } + + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; + NSInteger status = [httpResponse statusCode]; + + NSError *err2; + + if (status == 200) { + NSArray *json = [NSJSONSerialization JSONObjectWithData:data + options:0 + error:&err2]; + if (err) { + NSLog(@"Error fetching network list: %@", err2); + + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + NSAlert *alert = [NSAlert alertWithError:err2]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Retry"]; + + NSModalResponse res; + if (!_isQuitting) { + res = [alert runModal]; + } + else { + return; + } + + if(res == NSAlertFirstButtonReturn) { + _isQuitting = YES; + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + } + }]; + return; + } + + NSMutableArray *networks = [[NSMutableArray alloc] init]; + for(NSDictionary *dict in json) { + [networks addObject:[[Network alloc] initWithJsonData:dict]]; + } + + completionHandler(networks); + } + else if (status == 401) { + self->_resetKey = YES; + } + }]; + [task resume]; +} + +- (void)getNodeStatus:(void (^)(NodeStatus*))completionHandler error:(NSError*__autoreleasing*)error +{ + NSString *key = [self key:error]; + if(*error) { + return; + } + + NSString *urlString = [[baseURL stringByAppendingString:@"/status?auth="] stringByAppendingString:key]; + + NSURL *url = [NSURL URLWithString:urlString]; + NSURLSessionDataTask *task = + [session dataTaskWithURL:url + completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable err) { + + if(err) { + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + NSAlert *alert = [NSAlert alertWithError:err]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Retry"]; + + NSModalResponse res; + if (!_isQuitting) { + res = [alert runModal]; + } + else { + return; + } + + if(res == NSAlertFirstButtonReturn) { + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + _isQuitting = YES; + } + }]; + return; + } + + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; + NSInteger status = [httpResponse statusCode]; + + NSError *err2; + if(status == 200) { + NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data + options:0 + error:&err2]; + + if(err2) { + NSLog(@"Error fetching node status: %@", err2); + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + NSAlert *alert = [NSAlert alertWithError:err2]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Retry"]; + + NSModalResponse res; + if (!_isQuitting) { + res = [alert runModal]; + } + else { + return; + } + + if(res == NSAlertFirstButtonReturn) { + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + _isQuitting = YES; + } + }]; + return; + } + + NodeStatus *status = [[NodeStatus alloc] initWithJsonData:json]; + + completionHandler(status); + } + else if (status == 401) { + self->_resetKey = YES; + } + }]; + [task resume]; +} + +- (void)joinNetwork:(NSString*)networkId + allowManaged:(BOOL)allowManaged + allowGlobal:(BOOL)allowGlobal + allowDefault:(BOOL)allowDefault + allowDNS:(BOOL)allowDNS + error:(NSError *__autoreleasing*)error +{ + NSString *key = [self key:error]; + if(*error) { + return; + } + + NSString *urlString = [[[[baseURL stringByAppendingString:@"/network/"] + stringByAppendingString:networkId] + stringByAppendingString:@"?auth="] + stringByAppendingString:key]; + + NSURL *url = [NSURL URLWithString:urlString]; + + NSMutableDictionary *jsonDict = [NSMutableDictionary dictionary]; + [jsonDict setObject:[NSNumber numberWithBool:allowManaged] forKey:@"allowManaged"]; + [jsonDict setObject:[NSNumber numberWithBool:allowGlobal] forKey:@"allowGlobal"]; + [jsonDict setObject:[NSNumber numberWithBool:allowDefault] forKey:@"allowDefault"]; + [jsonDict setObject:[NSNumber numberWithBool:allowDNS] forKey:@"allowDNS"]; + + NSError *err = nil; + + NSData *json = [NSJSONSerialization dataWithJSONObject:jsonDict + options:0 + error:&err]; + + if(err) { + NSLog(@"Error creating json data: %@", err); + *error = err; + return; + } + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + request.HTTPMethod = @"POST"; + request.HTTPBody = json; + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + + NSURLSessionDataTask *task = + [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable err) { + if(err) { + NSLog(@"Error posting join request: %@", err); + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + NSAlert *alert = [NSAlert alertWithError:err]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Retry"]; + + NSModalResponse res; + if (!_isQuitting) { + res = [alert runModal]; + } + else { + return; + } + + if(res == NSAlertFirstButtonReturn) { + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + _isQuitting = YES; + } + }]; + } + + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; + NSInteger status = [httpResponse statusCode]; + + if(status == 200) { + NSLog(@"join ok"); + } + else if (status == 401) { + self->_resetKey = YES; + } + else { + NSLog(@"join error: %ld", (long)status); + } + }]; + [task resume]; +} + +- (void)leaveNetwork:(NSString*)networkId error:(NSError*__autoreleasing*)error +{ + NSString *key = [self key:error]; + if(*error) { + return; + } + + NSString *urlString = [[[[baseURL stringByAppendingString:@"/network/"] + stringByAppendingString:networkId] + stringByAppendingString:@"?auth="] + stringByAppendingString:key]; + + NSURL *url = [NSURL URLWithString:urlString]; + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + request.HTTPMethod = @"DELETE"; + + NSURLSessionDataTask *task = + [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable err) { + if(err) { + NSLog(@"Error posting delete request: %@", err); + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + NSAlert *alert = [NSAlert alertWithError:err]; + alert.alertStyle = NSCriticalAlertStyle; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Retry"]; + + NSModalResponse res; + if (!_isQuitting) { + res = [alert runModal]; + } + else { + return; + } + + if(res == NSAlertFirstButtonReturn) { + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; + _isQuitting = YES; + } + }]; + return; + } + + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; + NSInteger status = httpResponse.statusCode; + + if(status == 200) { + NSLog(@"leave ok"); + } + else if (status == 401) { + self->_resetKey = YES; + } + else { + NSLog(@"leave error: %ld", status); + } + }]; + [task resume]; +} + +@end diff --git a/attic/macui/ZeroTier One/ShowNetworksViewController.h b/attic/macui/ZeroTier One/ShowNetworksViewController.h new file mode 100644 index 0000000..6138958 --- /dev/null +++ b/attic/macui/ZeroTier One/ShowNetworksViewController.h @@ -0,0 +1,36 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +@class NetworkMonitor; +@class Network; + +@interface ShowNetworksViewController : NSViewController + +@property (nonatomic) NSMutableArray *networkList; +@property (nonatomic) NetworkMonitor *netMonitor; +@property (nonatomic) BOOL visible; + +@property (weak, nonatomic) IBOutlet NSTableView *tableView; + +- (void)deleteNetworkFromList:(NSString*)nwid; +- (void)setNetworks:(NSArray*)list; + + +@end diff --git a/attic/macui/ZeroTier One/ShowNetworksViewController.m b/attic/macui/ZeroTier One/ShowNetworksViewController.m new file mode 100644 index 0000000..acd2947 --- /dev/null +++ b/attic/macui/ZeroTier One/ShowNetworksViewController.m @@ -0,0 +1,184 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import "ShowNetworksViewController.h" +#import "NetworkMonitor.h" +#import "NetworkInfoCell.h" +#import "Network.h" + +BOOL hasNetworkWithID(NSArray *list, UInt64 nwid) +{ + for(Network *n in list) { + if(n.nwid == nwid) { + return YES; + } + } + + return NO; +} + +@interface ShowNetworksViewController () + +@end + +@implementation ShowNetworksViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.networkList = [NSMutableArray array]; + + [self.tableView setDelegate:self]; + [self.tableView setDataSource:self]; + [self.tableView setBackgroundColor:[NSColor clearColor]]; +} + +- (void)viewWillAppear { + [super viewWillAppear]; + self.visible = YES; +} + +- (void)viewWillDisappear { + [super viewWillDisappear]; + self.visible = NO; +} + +- (NSInteger)findNetworkWithID:(UInt64)networkId +{ + for(int i = 0; i < [_networkList count]; ++i) { + Network *nw = [_networkList objectAtIndex:i]; + + if(nw.nwid == networkId) { + return i; + } + } + + return NSNotFound; +} + + +- (void)deleteNetworkFromList:(NSString *)nwid { + [self.netMonitor deleteSavedNetwork:nwid]; + + UInt64 netid = 0; + NSScanner *scanner = [NSScanner scannerWithString:nwid]; + [scanner scanHexLongLong:&netid]; + for (Network *n in _networkList) { + if (n.nwid == netid) { + NSInteger index = [self findNetworkWithID:netid]; + + if (index != NSNotFound) { + [_networkList removeObjectAtIndex:index]; + [_tableView reloadData]; + } + } + } +} + +- (void)setNetworks:(NSArray *)list { + for (Network *n in list) { + if ([_networkList containsObject:n]) { + // don't need to do anything here. Already an identical object in the list + continue; + } + else { + // network not in the list based on equality. Did an object change? or is it a new item? + if (hasNetworkWithID(_networkList, n.nwid)) { + + for (int i = 0; i < [_networkList count]; ++i) { + Network *n2 = [_networkList objectAtIndex:i]; + if (n.nwid == n2.nwid) + { + [_networkList replaceObjectAtIndex:i withObject:n]; + [_tableView reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:i] + columnIndexes:[NSIndexSet indexSetWithIndex:0]]; + } + } + } + else { + [_networkList addObject:n]; + [_tableView reloadData]; + } + } + } +} + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { + return [_networkList count]; +} + +- (NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + NetworkInfoCell *cell = (NetworkInfoCell*)[tableView makeViewWithIdentifier:@"NetworkInfoCell" + owner:nil]; + Network *network = [_networkList objectAtIndex:row]; + cell.parent = self; + cell.networkIdField.stringValue = [NSString stringWithFormat:@"%10llx", network.nwid]; + cell.networkNameField.stringValue = network.name; + cell.statusField.stringValue = [network statusString]; + cell.typeField.stringValue = [network typeString]; + cell.mtuField.stringValue = [NSString stringWithFormat:@"%d", network.mtu]; + cell.macField.stringValue = network.mac; + cell.broadcastField.stringValue = network.broadcastEnabled ? @"ENABLED" : @"DISABLED"; + cell.bridgingField.stringValue = network.bridge ? @"ENABLED" : @"DISABLED"; + cell.deviceField.stringValue = network.portDeviceName; + + if(network.connected) { + cell.connectedCheckbox.state = NSOnState; + + if(network.allowDefault) { + cell.allowDefault.enabled = YES; + cell.allowDefault.state = NSOnState; + } + else { + cell.allowDefault.state = NSOffState; + + if([Network defaultRouteExists:_networkList]) { + cell.allowDefault.enabled = NO; + } + else { + cell.allowDefault.enabled = YES; + } + } + + cell.allowGlobal.enabled = YES; + cell.allowManaged.enabled = YES; + cell.allowDNS.enabled = YES; + } + else { + cell.connectedCheckbox.state = NSOffState; + cell.allowDefault.enabled = NO; + cell.allowGlobal.enabled = NO; + cell.allowManaged.enabled = NO; + cell.allowDNS.enabled = NO; + } + + cell.allowGlobal.state = network.allowGlobal ? NSOnState : NSOffState; + cell.allowManaged.state = network.allowManaged ? NSOnState : NSOffState; + cell.allowDNS.state = network.allowDNS ? NSOnState : NSOffState; + + cell.addressesField.stringValue = @""; + + for(NSString *addr in network.assignedAddresses) { + cell.addressesField.stringValue = [[cell.addressesField.stringValue stringByAppendingString:addr] stringByAppendingString:@"\n"]; + } + + return cell; +} + +@end diff --git a/attic/macui/ZeroTier One/ShowNetworksViewController.xib b/attic/macui/ZeroTier One/ShowNetworksViewController.xib new file mode 100644 index 0000000..485adb0 --- /dev/null +++ b/attic/macui/ZeroTier One/ShowNetworksViewController.xib @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/attic/macui/ZeroTier One/ZeroTier One.entitlements b/attic/macui/ZeroTier One/ZeroTier One.entitlements new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/attic/macui/ZeroTier One/ZeroTier One.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/attic/macui/ZeroTier One/ZeroTierIcon.icns b/attic/macui/ZeroTier One/ZeroTierIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..17e60d587da5167203d579a4468f4612fc403cbd GIT binary patch literal 125598 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 literal 0 HcmV?d00001 diff --git a/attic/macui/ZeroTier One/about.html b/attic/macui/ZeroTier One/about.html new file mode 100644 index 0000000..09f6eb3 --- /dev/null +++ b/attic/macui/ZeroTier One/about.html @@ -0,0 +1,58 @@ + + + + + +

    +
    +

    Welcome to ZeroTier

    +

    Getting Started

    +

    Networks are identified by 16-digit network IDs. If someone invited you to join theirs you probably received one. If not you can create your own at my.zerotier.com or by running running your own network controller. +

    Your computer is identified by a 10-digit ZeroTier address. You can find it at the top of the ZeroTier app's pull-down menu or by typing "sudo zerotier-cli info" in a terminal window. This number is unique to your system and is how network administrators can recognize you. If someone invited you to a network, give them this ID so they can authorize you to join.

    +

    Starting, Stopping, and Uninstalling

    +

    The ZeroTier service is separate from the UI app and starts on system boot. The app can be started on login or only when needed. To stop the ZeroTier service use:

    +      sudo launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist

    + Replace "unload" with "load" to start it again.

    +

    ZeroTier can be uninstalled with:

    +      sudo '/Library/Application Support/ZeroTier/One/uninstall.sh' +

    +

    For more information, visit zerotier.com.

    +
    + + \ No newline at end of file diff --git a/attic/macui/ZeroTier One/main.m b/attic/macui/ZeroTier One/main.m new file mode 100644 index 0000000..108a6bd --- /dev/null +++ b/attic/macui/ZeroTier One/main.m @@ -0,0 +1,23 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/attic/world/README.md b/attic/world/README.md new file mode 100644 index 0000000..dda4920 --- /dev/null +++ b/attic/world/README.md @@ -0,0 +1,7 @@ +World Definitions and Generator Code +====== + +This little bit of code is used to generate world updates. Ordinary users probably will never need this unless they want to test or experiment. + +See mkworld.cpp for documentation. To build from this directory use 'source ./build.sh'. + diff --git a/attic/world/build.sh b/attic/world/build.sh new file mode 100755 index 0000000..f3bcfab --- /dev/null +++ b/attic/world/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +c++ -std=c++11 -I../.. -I../../ext -I.. -g -o mkworld ../../node/C25519.cpp ../../node/Salsa20.cpp ../../node/SHA512.cpp ../../node/Identity.cpp ../../node/Utils.cpp ../../node/InetAddress.cpp ../../osdep/OSUtils.cpp mkworld.cpp -lm diff --git a/attic/world/mkworld.cpp b/attic/world/mkworld.cpp new file mode 100644 index 0000000..6b9bbe8 --- /dev/null +++ b/attic/world/mkworld.cpp @@ -0,0 +1,173 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* + * This utility makes the World from the configuration specified below. + * It probably won't be much use to anyone outside ZeroTier, Inc. except + * for testing and experimentation purposes. + * + * If you want to make your own World you must edit this file. + * + * When run, it expects two files in the current directory: + * + * previous.c25519 - key pair to sign this world (key from previous world) + * current.c25519 - key pair whose public key should be embedded in this world + * + * If these files do not exist, they are both created with the same key pair + * and a self-signed initial World is born. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace ZeroTier; + +int main(int argc,char **argv) +{ + std::string previous,current; + if ((!OSUtils::readFile("previous.c25519",previous))||(!OSUtils::readFile("current.c25519",current))) { + C25519::Pair np(C25519::generate()); + previous = std::string(); + previous.append((const char *)np.pub.data,ZT_C25519_PUBLIC_KEY_LEN); + previous.append((const char *)np.priv.data,ZT_C25519_PRIVATE_KEY_LEN); + current = previous; + OSUtils::writeFile("previous.c25519",previous); + OSUtils::writeFile("current.c25519",current); + fprintf(stderr,"INFO: created initial world keys: previous.c25519 and current.c25519 (both initially the same)" ZT_EOL_S); + } + + if ((previous.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))||(current.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))) { + fprintf(stderr,"FATAL: previous.c25519 or current.c25519 empty or invalid" ZT_EOL_S); + return 1; + } + C25519::Pair previousKP; + memcpy(previousKP.pub.data,previous.data(),ZT_C25519_PUBLIC_KEY_LEN); + memcpy(previousKP.priv.data,previous.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); + C25519::Pair currentKP; + memcpy(currentKP.pub.data,current.data(),ZT_C25519_PUBLIC_KEY_LEN); + memcpy(currentKP.priv.data,current.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); + + // ========================================================================= + // EDIT BELOW HERE + + std::vector roots; + + const uint64_t id = ZT_WORLD_ID_EARTH; + const uint64_t ts = 1567191349589ULL; // August 30th, 2019 + + // Los Angeles + roots.push_back(World::Root()); + roots.back().identity = Identity("3a46f1bf30:0:76e66fab33e28549a62ee2064d1843273c2c300ba45c3f20bef02dbad225723bb59a9bb4b13535730961aeecf5a163ace477cceb0727025b99ac14a5166a09a3"); + roots.back().stableEndpoints.push_back(InetAddress("185.180.13.82/9993")); + roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c815::/9993")); + + // Miami + roots.push_back(World::Root()); + roots.back().identity = Identity("de8950a8b2:0:1b3ada8251b91b6b6fa6535b8c7e2460918f4f729abdec97d3c7f3796868fb02f0de0b0ee554b2d59fc3524743eebfcf5315e790ed6d92db5bd10c28c09b40ef"); + roots.back().stableEndpoints.push_back(InetAddress("207.246.73.245/443")); + roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:9002:5cb:ec4:7aff:fe8f:69d9/443")); + + // Tokyo + roots.push_back(World::Root()); + roots.back().identity = Identity("34e0a5e174:0:93efb50934788f856d5cfb9ca5be88e85b40965586b75befac900df77352c145a1ba7007569d37c77bfe52c0999f3bdc67a47a4a6000b720a883ce47aa2fb7f8"); + roots.back().stableEndpoints.push_back(InetAddress("147.75.92.2/443")); + roots.back().stableEndpoints.push_back(InetAddress("2604:1380:3000:7100::1/443")); + + // Amsterdam + roots.push_back(World::Root()); + roots.back().identity = Identity("992fcf1db7:0:206ed59350b31916f749a1f85dffb3a8787dcbf83b8c6e9448d4e3ea0e3369301be716c3609344a9d1533850fb4460c50af43322bcfc8e13d3301a1f1003ceb6"); + roots.back().stableEndpoints.push_back(InetAddress("195.181.173.159/443")); + roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c024::/443")); + + // Alice + //roots.push_back(World::Root()); + //roots.back().identity = Identity("9d219039f3:0:01f0922a98e3b34ebcbff333269dc265d7a020aab69d72be4d4acc9c8c9294785771256cd1d942a90d1bd1d2dca3ea84ef7d85afe6611fb43ff0b74126d90a6e"); + //roots.back().stableEndpoints.push_back(InetAddress("188.166.94.177/9993")); // Amsterdam + //roots.back().stableEndpoints.push_back(InetAddress("2a03:b0c0:2:d0::7d:1/9993")); // Amsterdam + //roots.back().stableEndpoints.push_back(InetAddress("154.66.197.33/9993")); // Johannesburg + //roots.back().stableEndpoints.push_back(InetAddress("2c0f:f850:154:197::33/9993")); // Johannesburg + //roots.back().stableEndpoints.push_back(InetAddress("159.203.97.171/9993")); // New York + //roots.back().stableEndpoints.push_back(InetAddress("2604:a880:800:a1::54:6001/9993")); // New York + //roots.back().stableEndpoints.push_back(InetAddress("131.255.6.16/9993")); // Buenos Aires + //roots.back().stableEndpoints.push_back(InetAddress("2803:eb80:0:e::2/9993")); // Buenos Aires + //roots.back().stableEndpoints.push_back(InetAddress("107.170.197.14/9993")); // San Francisco + //roots.back().stableEndpoints.push_back(InetAddress("2604:a880:1:20::200:e001/9993")); // San Francisco + //roots.back().stableEndpoints.push_back(InetAddress("128.199.197.217/9993")); // Singapore + //roots.back().stableEndpoints.push_back(InetAddress("2400:6180:0:d0::b7:4001/9993")); // Singapore + + // Bob + //roots.push_back(World::Root()); + //roots.back().identity = Identity("8841408a2e:0:bb1d31f2c323e264e9e64172c1a74f77899555ed10751cd56e86405cde118d02dffe555d462ccf6a85b5631c12350c8d5dc409ba10b9025d0f445cf449d92b1c"); + //roots.back().stableEndpoints.push_back(InetAddress("45.32.198.130/9993")); // Dallas + //roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:6400:81c3:5400:00ff:fe18:1d61/9993")); // Dallas + //roots.back().stableEndpoints.push_back(InetAddress("46.101.160.249/9993")); // Frankfurt + //roots.back().stableEndpoints.push_back(InetAddress("2a03:b0c0:3:d0::6a:3001/9993")); // Frankfurt + //roots.back().stableEndpoints.push_back(InetAddress("107.191.46.210/9993")); // Paris + //roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:6800:83a4::64/9993")); // Paris + //roots.back().stableEndpoints.push_back(InetAddress("45.32.246.179/9993")); // Sydney + //roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:5800:8bf8:5400:ff:fe15:b39a/9993")); // Sydney + //roots.back().stableEndpoints.push_back(InetAddress("45.32.248.87/9993")); // Tokyo + //roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:7000:9bc9:5400:00ff:fe15:c4f5/9993")); // Tokyo + //roots.back().stableEndpoints.push_back(InetAddress("159.203.2.154/9993")); // Toronto + //roots.back().stableEndpoints.push_back(InetAddress("2604:a880:cad:d0::26:7001/9993")); // Toronto + + // END WORLD DEFINITION + // ========================================================================= + + fprintf(stderr,"INFO: generating and signing id==%llu ts==%llu" ZT_EOL_S,(unsigned long long)id,(unsigned long long)ts); + + World nw = World::make(World::TYPE_PLANET,id,ts,currentKP.pub,roots,previousKP); + + Buffer outtmp; + nw.serialize(outtmp,false); + World testw; + testw.deserialize(outtmp,0); + if (testw != nw) { + fprintf(stderr,"FATAL: serialization test failed!" ZT_EOL_S); + return 1; + } + + OSUtils::writeFile("world.bin",std::string((const char *)outtmp.data(),outtmp.size())); + fprintf(stderr,"INFO: world.bin written with %u bytes of binary world data." ZT_EOL_S,outtmp.size()); + + fprintf(stdout,ZT_EOL_S); + fprintf(stdout,"#define ZT_DEFAULT_WORLD_LENGTH %u" ZT_EOL_S,outtmp.size()); + fprintf(stdout,"static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {"); + for(unsigned int i=0;i 0) + fprintf(stdout,","); + fprintf(stdout,"0x%.2x",(unsigned int)d[i]); + } + fprintf(stdout,"};" ZT_EOL_S); + + return 0; +} diff --git a/attic/world/world.bin b/attic/world/world.bin new file mode 100644 index 0000000000000000000000000000000000000000..88049ccdc83167db4887d147d432c80e5102951b GIT binary patch literal 570 zcmV-A0>%9S00000225mq)IuzEdXVj$;cS%8U9(jG8=TcQA1wyp}|Ye zuQ79arkS$)m(k77vAhI8L$5>w0Cv5- zqv&*ZY^{VBgqPDS$Gd8^9t;M{T%-RoI;u9(1Ug3Xzc2uH=5MPr;)O}3F5(7F7(*vK zEHDeCTt6Vb@GZL1C2~8pnwzw-H8pbyVXo};p<}G%cg*VtCjwiUtQ4gdY6+tN0tC6V z4N@lw1}Xw>pvV;f000000000004E9FiBPDr02?~mf>F5}Yj37gTa11rV3Chca+zv&r=oWknL@f+gs5LD8QRQ?*IY>&-O|60lNku z0U7X+0tL$s#Cre!k7?NfyENdX;dB6#@3jduc#nl`T>G4*zKG~sK$ca8w_ES5kPY{9 zQo%)`x^M?poj1pO{!+l1pF7-VqJBq$FdOF< z!(fv{snJt7Q2Rt+#R~K@BE0;L6Vosn9}ol1wg3VI!?mrS0lNk&0&bwdBme*a00000 I00001yS+X8wEzGB literal 0 HcmV?d00001 diff --git a/attic/world/world.c b/attic/world/world.c new file mode 100644 index 0000000..ecf30e6 --- /dev/null +++ b/attic/world/world.c @@ -0,0 +1,3 @@ + +#define ZT_DEFAULT_WORLD_LENGTH 732 +static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x6b,0xd4,0x16,0x08,0xc1,0xb8,0xb3,0x88,0xa4,0x69,0x22,0x14,0x91,0xaa,0x9a,0xcd,0x66,0xcc,0x76,0x4c,0xde,0xfd,0x56,0x03,0x9f,0x10,0x67,0xae,0x15,0xe6,0x9c,0x6f,0xb4,0x2d,0x7b,0x55,0x33,0x0e,0x3f,0xda,0xac,0x52,0x9c,0x07,0x92,0xfd,0x73,0x40,0xa6,0xaa,0x21,0xab,0xa8,0xa4,0x89,0xfd,0xae,0xa4,0x4a,0x39,0xbf,0x2d,0x00,0x65,0x9a,0xc9,0xc8,0x18,0xeb,0x16,0x93,0xf4,0xe5,0xbd,0x20,0xda,0x10,0xad,0xc7,0x05,0xf4,0x99,0xfe,0x04,0x08,0x9b,0xe0,0x9e,0x77,0x1d,0x9f,0x47,0x16,0xaa,0x92,0x4f,0x10,0x16,0x3d,0xc7,0xec,0xd3,0x90,0x9e,0xd1,0x74,0xfc,0xb3,0xb5,0x07,0x9c,0x4d,0x95,0xc5,0x17,0x8b,0x3d,0x0b,0x60,0x76,0xe8,0x51,0xbb,0xb6,0x3d,0x74,0xb5,0x21,0x83,0x7b,0x95,0x1d,0x02,0x9b,0xcd,0xaf,0x5c,0x3e,0x96,0xdf,0x37,0x2c,0x56,0x6d,0xfa,0x75,0x0f,0xda,0x55,0x85,0x13,0xf4,0x76,0x1a,0x66,0x4d,0x3b,0x8d,0xcf,0x12,0xc9,0x34,0xb9,0x0d,0x61,0x03,0x3a,0x46,0xf1,0xbf,0x30,0x00,0x76,0xe6,0x6f,0xab,0x33,0xe2,0x85,0x49,0xa6,0x2e,0xe2,0x06,0x4d,0x18,0x43,0x27,0x3c,0x2c,0x30,0x0b,0xa4,0x5c,0x3f,0x20,0xbe,0xf0,0x2d,0xba,0xd2,0x25,0x72,0x3b,0xb5,0x9a,0x9b,0xb4,0xb1,0x35,0x35,0x73,0x09,0x61,0xae,0xec,0xf5,0xa1,0x63,0xac,0xe4,0x77,0xcc,0xeb,0x07,0x27,0x02,0x5b,0x99,0xac,0x14,0xa5,0x16,0x6a,0x09,0xa3,0x00,0x02,0x04,0xb9,0xb4,0x0d,0x52,0x27,0x09,0x06,0x2a,0x02,0x6e,0xa0,0xc8,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0x09,0x9d,0x21,0x90,0x39,0xf3,0x00,0x01,0xf0,0x92,0x2a,0x98,0xe3,0xb3,0x4e,0xbc,0xbf,0xf3,0x33,0x26,0x9d,0xc2,0x65,0xd7,0xa0,0x20,0xaa,0xb6,0x9d,0x72,0xbe,0x4d,0x4a,0xcc,0x9c,0x8c,0x92,0x94,0x78,0x57,0x71,0x25,0x6c,0xd1,0xd9,0x42,0xa9,0x0d,0x1b,0xd1,0xd2,0xdc,0xa3,0xea,0x84,0xef,0x7d,0x85,0xaf,0xe6,0x61,0x1f,0xb4,0x3f,0xf0,0xb7,0x41,0x26,0xd9,0x0a,0x6e,0x00,0x0c,0x04,0xbc,0xa6,0x5e,0xb1,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x7d,0x00,0x01,0x27,0x09,0x04,0x9a,0x42,0xc5,0x21,0x27,0x09,0x06,0x2c,0x0f,0xf8,0x50,0x01,0x54,0x01,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x27,0x09,0x04,0x9f,0xcb,0x61,0xab,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,0x54,0x60,0x01,0x27,0x09,0x04,0x83,0xff,0x06,0x10,0x27,0x09,0x06,0x28,0x03,0xeb,0x80,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0x04,0x6b,0xaa,0xc5,0x0e,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x00,0xe0,0x01,0x27,0x09,0x04,0x80,0xc7,0xc5,0xd9,0x27,0x09,0x06,0x24,0x00,0x61,0x80,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0xb7,0x40,0x01,0x27,0x09,0x88,0x41,0x40,0x8a,0x2e,0x00,0xbb,0x1d,0x31,0xf2,0xc3,0x23,0xe2,0x64,0xe9,0xe6,0x41,0x72,0xc1,0xa7,0x4f,0x77,0x89,0x95,0x55,0xed,0x10,0x75,0x1c,0xd5,0x6e,0x86,0x40,0x5c,0xde,0x11,0x8d,0x02,0xdf,0xfe,0x55,0x5d,0x46,0x2c,0xcf,0x6a,0x85,0xb5,0x63,0x1c,0x12,0x35,0x0c,0x8d,0x5d,0xc4,0x09,0xba,0x10,0xb9,0x02,0x5d,0x0f,0x44,0x5c,0xf4,0x49,0xd9,0x2b,0x1c,0x00,0x0c,0x04,0x2d,0x20,0xc6,0x82,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x64,0x00,0x81,0xc3,0x54,0x00,0x00,0xff,0xfe,0x18,0x1d,0x61,0x27,0x09,0x04,0x2e,0x65,0xa0,0xf9,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x6a,0x30,0x01,0x27,0x09,0x04,0x6b,0xbf,0x2e,0xd2,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x68,0x00,0x83,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x27,0x09,0x04,0x2d,0x20,0xf6,0xb3,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x58,0x00,0x8b,0xf8,0x54,0x00,0x00,0xff,0xfe,0x15,0xb3,0x9a,0x27,0x09,0x04,0x2d,0x20,0xf8,0x57,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x70,0x00,0x9b,0xc9,0x54,0x00,0x00,0xff,0xfe,0x15,0xc4,0xf5,0x27,0x09,0x04,0x9f,0xcb,0x02,0x9a,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x0c,0xad,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x26,0x70,0x01,0x27,0x09}; diff --git a/backone-cli-completion.bash b/backone-cli-completion.bash new file mode 100644 index 0000000..291da68 --- /dev/null +++ b/backone-cli-completion.bash @@ -0,0 +1,57 @@ +#compdef backone-cli +#autoload + + +_get_network_ids () +{ + if [[ "$OSTYPE" == "darwin"* ]]; then + COMPREPLY=($(compgen -W "$(ls -1 /Library/Application\ Support/BackOne/networks.d | cut -c 1-16)" -- ${cur})) + else + COMPREPLY=($(compgen -W "$(ls -1 /var/lib/backone/networks.d | cut -c 1-16)" -- ${cur})) + fi +} + +_get_network_ids_from_history () +{ + COMPREPLY=($(compgen -W "$(fc -l -1000 -1 | sed -n 's/.*\([[:xdigit:]]\{16\}\).*/\1/p')" -- ${cur})) +} + +_backone-cli_completions() +{ + local cur prev + + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + case ${COMP_CWORD} in + 1) + COMPREPLY=($(compgen -W "info listpeers peers listnetworks join leave set get listmoons orbit deorbit" -- ${cur})) + ;; + 2) + case ${prev} in + leave) + _get_network_ids + ;; + join) + _get_network_ids_from_history + ;; + set) + _get_network_ids + ;; + get) + _get_network_ids + ;; + *) + COMPREPLY=() + ;; + esac + ;; + *) + COMPREPLY=() + ;; + esac +} + +complete -F _backone-cli_completions backone-cli + + diff --git a/backone.spec b/backone.spec new file mode 100644 index 0000000..532dfc5 --- /dev/null +++ b/backone.spec @@ -0,0 +1,162 @@ +Name: backone +Version: 1.14.1 +Release: 1%{?dist} +Summary: BackOne global ethernet switch + +License: BackOne BSL 1.1 +URL: https://backone.cloud + +# Fedora + +%if "%{?dist}" == ".fc35" +BuildRequires: systemd clang openssl openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".fc36" +BuildRequires: systemd clang openssl openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".fc37" +BuildRequires: systemd clang openssl openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".fc38" +BuildRequires: systemd clang openssl openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".fc39" +BuildRequires: systemd clang openssl openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".fc40" +BuildRequires: systemd clang openssl openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +# RHEL + +%if "%{?dist}" == ".el6" +Requires: chkconfig +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".el7" +BuildRequires: systemd openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".el8" +BuildRequires: systemd openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".el9" +BuildRequires: systemd openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +# Amazon + +%if "%{?dist}" == ".amzn2" +BuildRequires: systemd openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%if "%{?dist}" == ".amzn2022" +BuildRequires: systemd openssl-devel +Requires: systemd openssl +Requires(pre): /usr/sbin/useradd, /usr/bin/getent +%endif + +%description +BackOne is a software defined networking layer for Earth. + +It can be used for on-premise network virtualization, as a peer to peer VPN +for mobile teams, for hybrid or multi-data-center cloud deployments, or just +about anywhere else secure software defined virtual networking is useful. + +This is our OS-level client service. It allows Mac, Linux, Windows, +FreeBSD, and soon other types of clients to join BackOne virtual networks +like conventional VPNs or VLANs. It can run on native systems, VMs, or +containers (Docker, OpenVZ, etc.). + +%prep +%if "%{?dist}" != ".el6" +rm -rf BUILD BUILDROOT RPMS SRPMS SOURCES +ln -s %{getenv:PWD} %{name}-%{version} +mkdir -p SOURCES +tar --exclude=%{name}-%{version}/.git --exclude=%{name}-%{version}/%{name}-%{version} -czf SOURCES/%{name}-%{version}.tar.gz %{name}-%{version}/* +rm -f %{name}-%{version} +# cp -a %{getenv:PWD}/* . +%endif + +%build +%if "%{?dist}" != ".el6" +make ZT_USE_MINIUPNPC=1 %{?_smp_mflags} one +%endif + +%pre +/usr/bin/getent passwd backone || /usr/sbin/useradd -r -d /var/lib/backone -s /sbin/nologin backone + +%install +%if "%{?dist}" != ".el6" +make install DESTDIR=$RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT%{_unitdir} +cp %{getenv:PWD}/debian/backone.service $RPM_BUILD_ROOT%{_unitdir}/%{name}.service +%else +rm -rf $RPM_BUILD_ROOT +pushd %{getenv:PWD} +make install DESTDIR=$RPM_BUILD_ROOT +popd +mkdir -p $RPM_BUILD_ROOT/etc/init.d +cp %{getenv:PWD}/ext/installfiles/linux/backone.init.rhel6 $RPM_BUILD_ROOT/etc/init.d/backone +chmod 0755 $RPM_BUILD_ROOT/etc/init.d/backone +%endif + +%files +%{_sbindir}/* +%{_mandir}/* +%{_localstatedir}/* + +%if 0%{?rhel} && 0%{?rhel} <= 6 +/etc/init.d/backone +%else +%{_unitdir}/%{name}.service +%endif + +%post +%if ! 0%{?rhel} && 0%{?rhel} <= 6 +%systemd_post backone.service +%endif + +%preun +%if ! 0%{?rhel} && 0%{?rhel} <= 6 +%systemd_preun backone.service +%endif + +%postun +%if ! 0%{?rhel} && 0%{?rhel} <= 6 +%systemd_postun_with_restart backone.service +%endif + +%changelog +* Tue Oct 8 2024 Dedy Sutanto - 1.14.1 +- see https://github.com/proitlab/BackOne for release notes + +* Thu Nov 16 2023 Dedy Sutanto - 1.12.1 +- see https://github.com/proitlab/BackOne for release notes diff --git a/ci/Dockerfile-build.el6 b/ci/Dockerfile-build.el6 new file mode 100644 index 0000000..c5848c9 --- /dev/null +++ b/ci/Dockerfile-build.el6 @@ -0,0 +1,36 @@ +ARG DOCKER_ARCH +FROM --platform=linux/${DOCKER_ARCH} alpine:edge AS builder + +RUN apk update +RUN apk add curl +RUN apk add bash +RUN apk add file +RUN apk add rust +RUN apk add cargo +RUN apk add make +RUN apk add cmake +RUN apk add clang +RUN apk add openssl-dev +RUN apk add linux-headers +RUN apk add build-base +RUN apk add openssl-libs-static + +COPY . . +RUN ZT_STATIC=1 make +RUN ls -la + +ARG DOCKER_ARCH +FROM --platform=linux/${DOCKER_ARCH} centos:6 AS stage +WORKDIR /root/rpmbuild/BUILD +COPY . . +COPY --from=builder zerotier-* ./ +RUN curl https://gist.githubusercontent.com/someara/b363002ba6e57b3c474dd027d4daef85/raw/4ac5534139752fc92fbe1a53599a390214f69615/el6%2520vault --output /etc/yum.repos.d/CentOS-Base.repo +RUN uname -a +RUN yum -y install make gcc rpm-build +RUN pwd +RUN ls -la +RUN make redhat + +FROM scratch AS export +ARG ZT_NAME +COPY --from=stage /root/rpmbuild/RPMS/*/*.rpm ./${ZT_NAME}/ diff --git a/ci/Dockerfile-test.el6 b/ci/Dockerfile-test.el6 new file mode 100644 index 0000000..4996673 --- /dev/null +++ b/ci/Dockerfile-test.el6 @@ -0,0 +1,4 @@ +ARG DOCKER_ARCH +FROM --platform=linux/${DOCKER_ARCH} centos:6 +RUN printf "[C6.10-base]\nname=CentOS-6.10 - Base\nbaseurl=http://vault.epel.cloud/6.10/os/\$basearch/\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6\nenabled=1\nmetadata_expire=never\n" > /etc/yum.repos.d/CentOS-Base.repo +RUN yum -y install curl diff --git a/ci/scripts/build.sh b/ci/scripts/build.sh new file mode 100755 index 0000000..a4b8ca9 --- /dev/null +++ b/ci/scripts/build.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +ZT_NAME="$1" ; shift +DISTRO="$1" ; shift +ZT_ISA="$1" ; shift +VERSION="$1" ; shift +BUILD_EVENT="$1" ; shift + +source "$(dirname $0)/lib.sh" + +if [ -f "ci/Dockerfile-build.${ZT_NAME}" ]; then + DOCKERFILE="ci/Dockerfile-build.${ZT_NAME}" +else + DOCKERFILE="ci/Dockerfile-build.${PKGFMT}" +fi + +echo "#~~~~~~~~~~~~~~~~~~~~" +echo "$0 variables:" +echo "nproc: $(nproc)" +echo "ZT_NAME: ${ZT_NAME}" +echo "DISTRO: ${DISTRO}" +echo "ZT_ISA: ${ZT_ISA}" +echo "VERSION: ${VERSION}" +echo "BUILD_EVENT: ${BUILD_EVENT}" +echo "DOCKER_ARCH: ${DOCKER_ARCH}" +echo "DNF_ARCH: ${DNF_ARCH}" +echo "RUST_TRIPLET: ${RUST_TRIPLET}" +echo "PKGFMT: ${PKGFMT}" +echo "PWD: ${PWD}" +echo "DOCKERFILE: ${DOCKERFILE}" +echo "#~~~~~~~~~~~~~~~~~~~~" + +make munge_rpm zerotier-one.spec VERSION=${VERSION} +make munge_deb debian/changelog VERSION=${VERSION} + +docker buildx build \ + --no-cache=true \ + --build-arg ZT_NAME="${ZT_NAME}" \ + --build-arg RUST_TRIPLET="${RUST_TRIPLET}" \ + --build-arg DOCKER_ARCH="${DOCKER_ARCH}" \ + --build-arg DNF_ARCH="${DNF_ARCH}" \ + --platform linux/${DOCKER_ARCH} \ + -f ${DOCKERFILE} \ + -t build \ + . \ + --output type=local,dest=. \ + --target export diff --git a/ci/scripts/lib.sh b/ci/scripts/lib.sh new file mode 100755 index 0000000..43c3576 --- /dev/null +++ b/ci/scripts/lib.sh @@ -0,0 +1,63 @@ + +case $ZT_NAME in + el*|fc*|amzn*) + export PKGFMT=rpm + ;; + *) + export PKGFMT=deb +esac + +case $ZT_ISA in + 386) + export DOCKER_ARCH=386 + export DEB_ARCH=i386 + export DNF_ARCH=i686 + export RUST_TRIPLET=i686-unknown-linux-gnu + ;; + amd64) + export DOCKER_ARCH=amd64 + export DEB_ARCH=amd64 + export DNF_ARCH=x86_64 + export RUST_TRIPLET=x86_64-unknown-linux-gnu + ;; + armv7) + export DOCKER_ARCH=arm/v7 + export DNF_ARCH=armv7 + export DEB_ARCH=armhf + export RUST_TRIPLET=armv7-unknown-linux-gnueabihf + ;; + arm64) + export DOCKER_ARCH=arm64/v8 + export DEB_ARCH=arm64 + export DNF_ARCH=linux64 + export RUST_TRIPLET=aarch64-unknown-linux-gnu + ;; + riscv64) + export DOCKER_ARCH=riscv64 + export DEB_ARCH=riscv64 + export DNF_ARCH=riscv64 + export RUST_TRIPLET=riscv64gc-unknown-linux-gnu + ;; + ppc64le) + export DOCKER_ARCH=ppc64le + export DEB_ARCH=ppc64el + export DNF_ARCH=ppc64le + export RUST_TRIPLET=powerpc64le-unknown-linux-gnu + ;; + mips64le) + export DOCKER_ARCH=mips64le + export DEB_ARCH=mips64le + export DNF_ARCH=mips64le + export RUST_TRIPLET=mips64el-unknown-linux-gnuabi64 + ;; + s390x) + export DOCKER_ARCH=s390x + export DEB_ARCH=s390x + export DNF_ARCH=s390x + export RUST_TRIPLET=s390x-unknown-linux-gnu + ;; + *) + echo "ERROR: could not determine architecture settings. PLEASE FIX ME" + exit 1 + ;; +esac diff --git a/ci/scripts/munge_debian_changelog.sh b/ci/scripts/munge_debian_changelog.sh new file mode 100755 index 0000000..d37cb06 --- /dev/null +++ b/ci/scripts/munge_debian_changelog.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +export FILE=$1 +export VERSION=$2 +export NAME=$3 +export MESSAGE=$4 +export DATE=$(date "+%a, %d %b %Y %T %z") +# export DATE=$(date "+%a %b %d %Y") + +set +e +grep --version | grep BSD &> /dev/null +if [ $? == 0 ]; then BSDGREP=true ; else BSDGREP=false ; fi +set -e + +# echo "#~~~~~~~~~~~~~~~~~~~~" +# echo "$0 variables:" +# echo "VERSION: ${VERSION}" +# echo "NAME: ${NAME}" +# echo "MESSAGE: ${MESSAGE}" +# echo "DATE: ${DATE}" +# echo "BSDGREP: ${BSDGREP}" +# echo "#~~~~~~~~~~~~~~~~~~~~" +# echo + +if $BSDGREP ; then + sed -i '' s/^Version:.*/"Version: ${VERSION}"/ ${FILE} +else + sed -i s/^Version:.*/"Version: ${VERSION}"/ ${FILE} +fi + +awk -v version=${VERSION} -v date=${DATE} -v name=${NAME} -v message=${MESSAGE} \ + 'BEGIN{print "zerotier-one (" version ") stable; urgency=medium\n\n * " message "\n\n -- " name " " date "\n" }{ print }' \ + ${FILE} > ${FILE}.new + +mv ${FILE}.new ${FILE} diff --git a/ci/scripts/munge_rpm_spec.sh b/ci/scripts/munge_rpm_spec.sh new file mode 100755 index 0000000..289df1e --- /dev/null +++ b/ci/scripts/munge_rpm_spec.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +export FILE=$1 +export VERSION=$2 +export NAME=$3 +export MESSAGE=$4 +export DATE=$(date "+%a %b %d %Y") + +set +e +grep --version | grep BSD &> /dev/null +if [ $? == 0 ]; then BSDGREP=true ; else BSDGREP=false ; fi +set -e + +# echo "#~~~~~~~~~~~~~~~~~~~~" +# echo "$0 variables:" +# echo "VERSION: ${VERSION}" +# echo "NAME: ${NAME}" +# echo "MESSAGE: ${MESSAGE}" +# echo "DATE: ${DATE}" +# echo "BSDGREP: ${BSDGREP}" +# echo "#~~~~~~~~~~~~~~~~~~~~" +# echo + +if $BSDGREP ; then + sed -i '' s/^Version:.*/"Version: ${VERSION}"/ ${FILE} +else + sed -i s/^Version:.*/"Version: ${VERSION}"/ ${FILE} +fi + +awk -v version=${VERSION} -v date=${DATE} -v name=${NAME} -v message=${MESSAGE} \ + 'FNR==NR{ if (/%changelog/) p=NR; next} 1; FNR==p{ print "* " date " " name " - " version "\n- " message "\n" }' \ + ${FILE} ${FILE} > ${FILE}.new + +mv ${FILE}.new ${FILE} diff --git a/ci/scripts/publish.sh b/ci/scripts/publish.sh new file mode 100755 index 0000000..fa1e246 --- /dev/null +++ b/ci/scripts/publish.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +ZT_NAME="$1" ; shift +DISTRO="$1" ; shift +ZT_ISA="$1" ; shift +VERSION="$1" ; shift +BUILD_EVENT="$1" ; shift + +source "$(dirname $0)/lib.sh" + +if [ ${BUILD_EVENT} == "tag" ]; then + CHANNEL="zerotier-releases" +else + CHANNEL="zerotier-builds" +fi + +function publish_rpm { + mkdir -p /${CHANNEL}/${DISTRO} + ls -la /${CHANNEL} + ls -la . + cp -a ${ZT_NAME} /${CHANNEL}/${DISTRO} +} + +function publish_deb { + mkdir -p /${CHANNEL}/${DISTRO}/pool/dists/${ZT_NAME}/main + cp -a ${ZT_NAME}/* /${CHANNEL}/${DISTRO}/pool/dists/${ZT_NAME}/main +} + +case ${PKGFMT} in + "rpm") + publish_rpm + ;; + "deb") + publish_deb +esac + diff --git a/ci/scripts/test.sh b/ci/scripts/test.sh new file mode 100755 index 0000000..931e9bb --- /dev/null +++ b/ci/scripts/test.sh @@ -0,0 +1,55 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +ZT_NAME="$1" ; shift +DISTRO="$1" ; shift +ZT_ISA="$1" ; shift +VERSION="$1" ; shift +BUILD_EVENT="$1" ; shift + +source "$(dirname $0)/lib.sh" + +if [ -f "ci/Dockerfile-test.${ZT_NAME}" ]; then + DOCKERFILE="ci/Dockerfile-test.${ZT_NAME}" +else + DOCKERFILE="ci/Dockerfile-test.${PKGFMT}" +fi + +if [ ${BUILD_EVENT} == "tag" ]; then + BASEURL="zerotier-releases.home.arpa" +else + BASEURL="zerotier-builds.home.arpa" +fi + +echo "#~~~~~~~~~~~~~~~~~~~~" +echo "$0 variables:" +echo "nproc: $(nproc)" +echo "ZT_NAME: ${ZT_NAME}" +echo "DISTRO: ${DISTRO}" +echo "ZT_ISA: ${ZT_ISA}" +echo "VERSION: ${VERSION}" +echo "BUILD_EVENT: ${BUILD_EVENT}" +echo "DOCKER_ARCH: ${DOCKER_ARCH}" +echo "DNF_ARCH: ${DNF_ARCH}" +echo "RUST_TRIPLET: ${RUST_TRIPLET}" +echo "PKGFMT: ${PKGFMT}" +echo "PWD: ${PWD}" +echo "DOCKERFILE: ${DOCKERFILE}" +echo "#~~~~~~~~~~~~~~~~~~~~" + +# docker pull -q --platform="linux/${DOCKER_ARCH}" 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-tester + +docker buildx build \ + --build-arg BASEURL="${BASEURL}" \ + --build-arg ZT_NAME="${ZT_NAME}" \ + --build-arg DISTRO="${DISTRO}" \ + --build-arg DEB_ARCH="${DEB_ARCH}" \ + --build-arg DNF_ARCH="${DNF_ARCH}" \ + --build-arg VERSION="${VERSION}" \ + --build-arg DOCKER_ARCH="${DOCKER_ARCH}" \ + --platform "linux/${DOCKER_ARCH}" \ + --no-cache \ + -f ${DOCKERFILE} \ + -t test \ + . diff --git a/controller/ConnectionPool.hpp b/controller/ConnectionPool.hpp new file mode 100644 index 0000000..8ccfb6b --- /dev/null +++ b/controller/ConnectionPool.hpp @@ -0,0 +1,175 @@ +/* + * Copyright (c)2021 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#ifndef ZT_CONNECTION_POOL_H_ +#define ZT_CONNECTION_POOL_H_ + + +#ifndef _DEBUG + #define _DEBUG(x) +#endif + +#include "../node/Metrics.hpp" + +#include +#include +#include +#include +#include +#include + +namespace ZeroTier { + +struct ConnectionUnavailable : std::exception { + char const* what() const throw() { + return "Unable to allocate connection"; + }; +}; + + +class Connection { +public: + virtual ~Connection() {}; +}; + +class ConnectionFactory { +public: + virtual ~ConnectionFactory() {}; + virtual std::shared_ptr create()=0; +}; + +struct ConnectionPoolStats { + size_t pool_size; + size_t borrowed_size; +}; + +template +class ConnectionPool { +public: + ConnectionPool(size_t max_pool_size, size_t min_pool_size, std::shared_ptr factory) + : m_maxPoolSize(max_pool_size) + , m_minPoolSize(min_pool_size) + , m_factory(factory) + { + Metrics::max_pool_size += max_pool_size; + Metrics::min_pool_size += min_pool_size; + while(m_pool.size() < m_minPoolSize){ + m_pool.push_back(m_factory->create()); + Metrics::pool_avail++; + } + }; + + ConnectionPoolStats get_stats() { + std::unique_lock lock(m_poolMutex); + + ConnectionPoolStats stats; + stats.pool_size = m_pool.size(); + stats.borrowed_size = m_borrowed.size(); + + return stats; + }; + + ~ConnectionPool() { + }; + + /** + * Borrow + * + * Borrow a connection for temporary use + * + * When done, either (a) call unborrow() to return it, or (b) (if it's bad) just let it go out of scope. This will cause it to automatically be replaced. + * @retval a shared_ptr to the connection object + */ + std::shared_ptr borrow() { + std::unique_lock l(m_poolMutex); + + while((m_pool.size() + m_borrowed.size()) < m_minPoolSize) { + std::shared_ptr conn = m_factory->create(); + m_pool.push_back(conn); + Metrics::pool_avail++; + } + + if(m_pool.size()==0){ + + if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) { + try { + std::shared_ptr conn = m_factory->create(); + m_borrowed.insert(conn); + Metrics::pool_in_use++; + return std::static_pointer_cast(conn); + } catch (std::exception &e) { + Metrics::pool_errors++; + throw ConnectionUnavailable(); + } + } else { + for(auto it = m_borrowed.begin(); it != m_borrowed.end(); ++it){ + if((*it).unique()) { + // This connection has been abandoned! Destroy it and create a new connection + try { + // If we are able to create a new connection, return it + _DEBUG("Creating new connection to replace discarded connection"); + std::shared_ptr conn = m_factory->create(); + m_borrowed.erase(it); + m_borrowed.insert(conn); + return std::static_pointer_cast(conn); + } catch(std::exception& e) { + // Error creating a replacement connection + Metrics::pool_errors++; + throw ConnectionUnavailable(); + } + } + } + // Nothing available + Metrics::pool_errors++; + throw ConnectionUnavailable(); + } + } + + // Take one off the front + std::shared_ptr conn = m_pool.front(); + m_pool.pop_front(); + Metrics::pool_avail--; + // Add it to the borrowed list + m_borrowed.insert(conn); + Metrics::pool_in_use++; + return std::static_pointer_cast(conn); + }; + + /** + * Unborrow a connection + * + * Only call this if you are returning a working connection. If the connection was bad, just let it go out of scope (so the connection manager can replace it). + * @param the connection + */ + void unborrow(std::shared_ptr conn) { + // Lock + std::unique_lock lock(m_poolMutex); + m_borrowed.erase(conn); + Metrics::pool_in_use--; + if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) { + Metrics::pool_avail++; + m_pool.push_back(conn); + } + }; +protected: + size_t m_maxPoolSize; + size_t m_minPoolSize; + std::shared_ptr m_factory; + std::deque > m_pool; + std::set > m_borrowed; + std::mutex m_poolMutex; +}; + +} + +#endif diff --git a/controller/DB.cpp b/controller/DB.cpp new file mode 100644 index 0000000..2c354ae --- /dev/null +++ b/controller/DB.cpp @@ -0,0 +1,422 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#include "DB.hpp" +#include "EmbeddedNetworkController.hpp" +#include "../node/Metrics.hpp" + +#include +#include +#include + +using json = nlohmann::json; + +namespace ZeroTier { + +void DB::initNetwork(nlohmann::json &network) +{ + if (!network.count("private")) network["private"] = true; + if (!network.count("creationTime")) network["creationTime"] = OSUtils::now(); + if (!network.count("name")) network["name"] = ""; + if (!network.count("multicastLimit")) network["multicastLimit"] = (uint64_t)32; + if (!network.count("enableBroadcast")) network["enableBroadcast"] = true; + if (!network.count("v4AssignMode")) network["v4AssignMode"] = {{"zt",false}}; + if (!network.count("v6AssignMode")) network["v6AssignMode"] = {{"rfc4193",false},{"zt",false},{"6plane",false}}; + if (!network.count("authTokens")) network["authTokens"] = {{}}; + if (!network.count("capabilities")) network["capabilities"] = nlohmann::json::array(); + if (!network.count("tags")) network["tags"] = nlohmann::json::array(); + if (!network.count("routes")) network["routes"] = nlohmann::json::array(); + if (!network.count("ipAssignmentPools")) network["ipAssignmentPools"] = nlohmann::json::array(); + if (!network.count("mtu")) network["mtu"] = ZT_DEFAULT_MTU; + if (!network.count("remoteTraceTarget")) network["remoteTraceTarget"] = nlohmann::json(); + if (!network.count("removeTraceLevel")) network["remoteTraceLevel"] = 0; + if (!network.count("rulesSource")) network["rulesSource"] = ""; + if (!network.count("rules")) { + // If unspecified, rules are set to allow anything and behave like a flat L2 segment + network["rules"] = {{ + { "not",false }, + { "or", false }, + { "type","ACTION_ACCEPT" } + }}; + } + if (!network.count("dns")) network["dns"] = nlohmann::json::array(); + if (!network.count("ssoEnabled")) network["ssoEnabled"] = false; + if (!network.count("clientId")) network["clientId"] = ""; + if (!network.count("authorizationEndpoint")) network["authorizationEndpoint"] = ""; + + network["objtype"] = "network"; +} + +void DB::initMember(nlohmann::json &member) +{ + if (!member.count("authorized")) member["authorized"] = false; + if (!member.count("ssoExempt")) member["ssoExempt"] = false; + if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array(); + if (!member.count("activeBridge")) member["activeBridge"] = false; + if (!member.count("tags")) member["tags"] = nlohmann::json::array(); + if (!member.count("capabilities")) member["capabilities"] = nlohmann::json::array(); + if (!member.count("creationTime")) member["creationTime"] = OSUtils::now(); + if (!member.count("noAutoAssignIps")) member["noAutoAssignIps"] = false; + if (!member.count("revision")) member["revision"] = 0ULL; + if (!member.count("lastDeauthorizedTime")) member["lastDeauthorizedTime"] = 0ULL; + if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL; + if (!member.count("lastAuthorizedCredentialType")) member["lastAuthorizedCredentialType"] = nlohmann::json(); + if (!member.count("lastAuthorizedCredential")) member["lastAuthorizedCredential"] = nlohmann::json(); + if (!member.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = 0LL; + if (!member.count("vMajor")) member["vMajor"] = -1; + if (!member.count("vMinor")) member["vMinor"] = -1; + if (!member.count("vRev")) member["vRev"] = -1; + if (!member.count("vProto")) member["vProto"] = -1; + if (!member.count("remoteTraceTarget")) member["remoteTraceTarget"] = nlohmann::json(); + if (!member.count("removeTraceLevel")) member["remoteTraceLevel"] = 0; + member["objtype"] = "member"; +} + +void DB::cleanNetwork(nlohmann::json &network) +{ + network.erase("clock"); + network.erase("authorizedMemberCount"); + network.erase("activeMemberCount"); + network.erase("totalMemberCount"); + network.erase("lastModified"); +} + +void DB::cleanMember(nlohmann::json &member) +{ + member.erase("clock"); + member.erase("physicalAddr"); + member.erase("recentLog"); + member.erase("lastModified"); + member.erase("lastRequestMetaData"); + member.erase("authenticationURL"); // computed + member.erase("authenticationClientID"); // computed +} + +DB::DB() {} +DB::~DB() {} + +bool DB::get(const uint64_t networkId,nlohmann::json &network) +{ + waitForReady(); + Metrics::db_get_network++; + std::shared_ptr<_Network> nw; + { + std::shared_lock l(_networks_l); + auto nwi = _networks.find(networkId); + if (nwi == _networks.end()) + return false; + nw = nwi->second; + } + { + std::shared_lock l2(nw->lock); + network = nw->config; + } + return true; +} + +bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member) +{ + waitForReady(); + Metrics::db_get_network_and_member++; + std::shared_ptr<_Network> nw; + { + std::shared_lock l(_networks_l); + auto nwi = _networks.find(networkId); + if (nwi == _networks.end()) + return false; + nw = nwi->second; + } + { + std::shared_lock l2(nw->lock); + network = nw->config; + auto m = nw->members.find(memberId); + if (m == nw->members.end()) + return false; + member = m->second; + } + return true; +} + +bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,NetworkSummaryInfo &info) +{ + waitForReady(); + Metrics::db_get_network_and_member_and_summary++; + std::shared_ptr<_Network> nw; + { + std::shared_lock l(_networks_l); + auto nwi = _networks.find(networkId); + if (nwi == _networks.end()) + return false; + nw = nwi->second; + } + { + std::shared_lock l2(nw->lock); + network = nw->config; + _fillSummaryInfo(nw,info); + auto m = nw->members.find(memberId); + if (m == nw->members.end()) + return false; + member = m->second; + } + return true; +} + +bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector &members) +{ + waitForReady(); + Metrics::db_get_member_list++; + std::shared_ptr<_Network> nw; + { + std::shared_lock l(_networks_l); + auto nwi = _networks.find(networkId); + if (nwi == _networks.end()) + return false; + nw = nwi->second; + } + { + std::shared_lock l2(nw->lock); + network = nw->config; + for(auto m=nw->members.begin();m!=nw->members.end();++m) { + members.push_back(m->second); + } + } + return true; +} + +void DB::networks(std::set &networks) +{ + waitForReady(); + Metrics::db_get_network_list++; + std::shared_lock l(_networks_l); + for(auto n=_networks.begin();n!=_networks.end();++n) + networks.insert(n->first); +} + +void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners) +{ + Metrics::db_member_change++; + uint64_t memberId = 0; + uint64_t networkId = 0; + bool isAuth = false; + bool wasAuth = false; + std::shared_ptr<_Network> nw; + + if (old.is_object()) { + memberId = OSUtils::jsonIntHex(old["id"],0ULL); + networkId = OSUtils::jsonIntHex(old["nwid"],0ULL); + if ((memberId)&&(networkId)) { + { + std::unique_lock l(_networks_l); + auto nw2 = _networks.find(networkId); + if (nw2 != _networks.end()) { + nw = nw2->second; + } + } + if (nw) { + std::unique_lock l(nw->lock); + if (OSUtils::jsonBool(old["activeBridge"],false)) { + nw->activeBridgeMembers.erase(memberId); + } + wasAuth = OSUtils::jsonBool(old["authorized"],false); + if (wasAuth) { + nw->authorizedMembers.erase(memberId); + } + json &ips = old["ipAssignments"]; + if (ips.is_array()) { + for(unsigned long i=0;iallocatedIps.erase(ipa); + } + } + } + } + } + } + + if (memberConfig.is_object()) { + if (!nw) { + memberId = OSUtils::jsonIntHex(memberConfig["id"],0ULL); + networkId = OSUtils::jsonIntHex(memberConfig["nwid"],0ULL); + if ((!memberId)||(!networkId)) + return; + std::unique_lock l(_networks_l); + std::shared_ptr<_Network> &nw2 = _networks[networkId]; + if (!nw2) + nw2.reset(new _Network); + nw = nw2; + } + + { + std::unique_lock l(nw->lock); + + nw->members[memberId] = memberConfig; + + if (OSUtils::jsonBool(memberConfig["activeBridge"],false)) { + nw->activeBridgeMembers.insert(memberId); + } + isAuth = OSUtils::jsonBool(memberConfig["authorized"],false); + if (isAuth) { + Metrics::member_auths++; + nw->authorizedMembers.insert(memberId); + } + json &ips = memberConfig["ipAssignments"]; + if (ips.is_array()) { + for(unsigned long i=0;iallocatedIps.insert(ipa); + } + } + } + + if (!isAuth) { + const int64_t ldt = (int64_t)OSUtils::jsonInt(memberConfig["lastDeauthorizedTime"],0ULL); + if (ldt > nw->mostRecentDeauthTime) + nw->mostRecentDeauthTime = ldt; + } + } + + if (notifyListeners) { + std::unique_lock ll(_changeListeners_l); + for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { + (*i)->onNetworkMemberUpdate(this,networkId,memberId,memberConfig); + } + } + } else if (memberId) { + if (nw) { + std::unique_lock l(nw->lock); + nw->members.erase(memberId); + } + if (networkId) { + std::unique_lock l(_networks_l); + auto er = _networkByMember.equal_range(memberId); + for(auto i=er.first;i!=er.second;++i) { + if (i->second == networkId) { + _networkByMember.erase(i); + break; + } + } + } + } + + if (notifyListeners) { + if(networkId != 0 && memberId != 0 && old.is_object() && !memberConfig.is_object()) { + // member delete + Metrics::member_count--; + } else if (networkId != 0 && memberId != 0 && !old.is_object() && memberConfig.is_object()) { + // new member + Metrics::member_count++; + } + + if (!wasAuth && isAuth) { + Metrics::member_auths++; + } else if (wasAuth && !isAuth) { + Metrics::member_deauths++; + } else { + Metrics::member_changes++; + } + } + + if ((notifyListeners)&&((wasAuth)&&(!isAuth)&&(networkId)&&(memberId))) { + std::unique_lock ll(_changeListeners_l); + for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { + (*i)->onNetworkMemberDeauthorize(this,networkId,memberId); + } + } +} + +void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners) +{ + Metrics::db_network_change++; + if (notifyListeners) { + if (old.is_object() && old.contains("id") && networkConfig.is_object() && networkConfig.contains("id")) { + Metrics::network_changes++; + } else if (!old.is_object() && networkConfig.is_object() && networkConfig.contains("id")) { + Metrics::network_count++; + } else if (old.is_object() && old.contains("id") && !networkConfig.is_object()) { + Metrics::network_count--; + } + } + + if (networkConfig.is_object()) { + const std::string ids = networkConfig["id"]; + const uint64_t networkId = Utils::hexStrToU64(ids.c_str()); + if (networkId) { + std::shared_ptr<_Network> nw; + { + std::unique_lock l(_networks_l); + std::shared_ptr<_Network> &nw2 = _networks[networkId]; + if (!nw2) + nw2.reset(new _Network); + nw = nw2; + } + { + std::unique_lock l2(nw->lock); + nw->config = networkConfig; + } + if (notifyListeners) { + std::unique_lock ll(_changeListeners_l); + for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { + (*i)->onNetworkUpdate(this,networkId,networkConfig); + } + } + } + } else if (old.is_object()) { + const std::string ids = old["id"]; + const uint64_t networkId = Utils::hexStrToU64(ids.c_str()); + if (networkId) { + try { + // deauth all members on the network + nlohmann::json network; + std::vector members; + this->get(networkId, network, members); + for(auto i=members.begin();i!=members.end();++i) { + const std::string nodeID = (*i)["id"]; + const uint64_t memberId = Utils::hexStrToU64(nodeID.c_str()); + std::unique_lock ll(_changeListeners_l); + for(auto j=_changeListeners.begin();j!=_changeListeners.end();++j) { + (*j)->onNetworkMemberDeauthorize(this,networkId,memberId); + } + } + } catch (std::exception &e) { + std::cerr << "Error deauthorizing members on network delete: " << e.what() << std::endl; + } + + // delete the network + std::unique_lock l(_networks_l); + _networks.erase(networkId); + } + } +} + +void DB::_fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info) +{ + for(auto ab=nw->activeBridgeMembers.begin();ab!=nw->activeBridgeMembers.end();++ab) + info.activeBridges.push_back(Address(*ab)); + std::sort(info.activeBridges.begin(),info.activeBridges.end()); + for(auto ip=nw->allocatedIps.begin();ip!=nw->allocatedIps.end();++ip) + info.allocatedIps.push_back(*ip); + std::sort(info.allocatedIps.begin(),info.allocatedIps.end()); + info.authorizedMemberCount = (unsigned long)nw->authorizedMembers.size(); + info.totalMemberCount = (unsigned long)nw->members.size(); + info.mostRecentDeauthTime = nw->mostRecentDeauthTime; +} + +} // namespace ZeroTier diff --git a/controller/DB.hpp b/controller/DB.hpp new file mode 100644 index 0000000..50a57be --- /dev/null +++ b/controller/DB.hpp @@ -0,0 +1,197 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#ifndef ZT_CONTROLLER_DB_HPP +#define ZT_CONTROLLER_DB_HPP + +//#define ZT_CONTROLLER_USE_LIBPQ + +#include "../node/Constants.hpp" +#include "../node/Identity.hpp" +#include "../node/InetAddress.hpp" +#include "../osdep/OSUtils.hpp" +#include "../osdep/BlockingQueue.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define ZT_MEMBER_AUTH_TIMEOUT_NOTIFY_BEFORE 25000 + +namespace ZeroTier +{ + +struct AuthInfo +{ +public: + AuthInfo() + : enabled(false) + , version(0) + , authenticationURL() + , authenticationExpiryTime(0) + , issuerURL() + , centralAuthURL() + , ssoNonce() + , ssoState() + , ssoClientID() + , ssoProvider("default") + {} + + bool enabled; + uint64_t version; + std::string authenticationURL; + uint64_t authenticationExpiryTime; + std::string issuerURL; + std::string centralAuthURL; + std::string ssoNonce; + std::string ssoState; + std::string ssoClientID; + std::string ssoProvider; +}; + +/** + * Base class with common infrastructure for all controller DB implementations + */ +class DB +{ +public: + class ChangeListener + { + public: + ChangeListener() {} + virtual ~ChangeListener() {} + virtual void onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network) {} + virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member) {} + virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId) {} + }; + + struct NetworkSummaryInfo + { + NetworkSummaryInfo() : authorizedMemberCount(0),totalMemberCount(0),mostRecentDeauthTime(0) {} + std::vector
    activeBridges; + std::vector allocatedIps; + unsigned long authorizedMemberCount; + unsigned long totalMemberCount; + int64_t mostRecentDeauthTime; + }; + + static void initNetwork(nlohmann::json &network); + static void initMember(nlohmann::json &member); + static void cleanNetwork(nlohmann::json &network); + static void cleanMember(nlohmann::json &member); + + DB(); + virtual ~DB(); + + virtual bool waitForReady() = 0; + virtual bool isReady() = 0; + + inline bool hasNetwork(const uint64_t networkId) const + { + std::shared_lock l(_networks_l); + return (_networks.find(networkId) != _networks.end()); + } + + bool get(const uint64_t networkId,nlohmann::json &network); + bool get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member); + bool get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,NetworkSummaryInfo &info); + bool get(const uint64_t networkId,nlohmann::json &network,std::vector &members); + + void networks(std::set &networks); + + template + inline void each(F f) + { + nlohmann::json nullJson; + std::unique_lock lck(_networks_l); + for(auto nw=_networks.begin();nw!=_networks.end();++nw) { + f(nw->first,nw->second->config,0,nullJson); // first provide network with 0 for member ID + for(auto m=nw->second->members.begin();m!=nw->second->members.end();++m) { + f(nw->first,nw->second->config,m->first,m->second); + } + } + } + + virtual bool save(nlohmann::json &record,bool notifyListeners) = 0; + virtual void eraseNetwork(const uint64_t networkId) = 0; + virtual void eraseMember(const uint64_t networkId,const uint64_t memberId) = 0; + virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) = 0; + + virtual AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL) { return AuthInfo(); } + + inline void addListener(DB::ChangeListener *const listener) + { + std::unique_lock l(_changeListeners_l); + _changeListeners.push_back(listener); + } + +protected: + static inline bool _compareRecords(const nlohmann::json &a,const nlohmann::json &b) + { + if (a.is_object() == b.is_object()) { + if (a.is_object()) { + if (a.size() != b.size()) + return false; + auto amap = a.get(); + auto bmap = b.get(); + for(auto ai=amap.begin();ai!=amap.end();++ai) { + if (ai->first != "revision") { // ignore revision, compare only non-revision-counter fields + auto bi = bmap.find(ai->first); + if ((bi == bmap.end())||(bi->second != ai->second)) + return false; + } + } + return true; + } + return (a == b); + } + return false; + } + + struct _Network + { + _Network() : mostRecentDeauthTime(0) {} + nlohmann::json config; + std::unordered_map members; + std::unordered_set activeBridgeMembers; + std::unordered_set authorizedMembers; + std::unordered_set allocatedIps; + int64_t mostRecentDeauthTime; + std::shared_mutex lock; + }; + + virtual void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners); + virtual void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners); + void _fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info); + + std::vector _changeListeners; + std::unordered_map< uint64_t,std::shared_ptr<_Network> > _networks; + std::unordered_multimap< uint64_t,uint64_t > _networkByMember; + mutable std::shared_mutex _changeListeners_l; + mutable std::shared_mutex _networks_l; +}; + +} // namespace ZeroTier + +#endif diff --git a/controller/DBMirrorSet.cpp b/controller/DBMirrorSet.cpp new file mode 100644 index 0000000..78fa82a --- /dev/null +++ b/controller/DBMirrorSet.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#include "DBMirrorSet.hpp" + +namespace ZeroTier { + +DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener) + : _listener(listener) + , _running(true) + , _syncCheckerThread() + , _dbs() + , _dbs_l() +{ + _syncCheckerThread = std::thread([this]() { + for(;;) { + for(int i=0;i<120;++i) { // 1 minute delay between checks + if (!_running) + return; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + + std::vector< std::shared_ptr > dbs; + { + std::unique_lock l(_dbs_l); + if (_dbs.size() <= 1) + continue; // no need to do this if there's only one DB, so skip the iteration + dbs = _dbs; + } + + for(auto db=dbs.begin();db!=dbs.end();++db) { + (*db)->each([&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) { + try { + if (network.is_object()) { + if (memberId == 0) { + for(auto db2=dbs.begin();db2!=dbs.end();++db2) { + if (db->get() != db2->get()) { + nlohmann::json nw2; + if ((!(*db2)->get(networkId,nw2))||((nw2.is_object())&&(OSUtils::jsonInt(nw2["revision"],0) < OSUtils::jsonInt(network["revision"],0)))) { + nw2 = network; + (*db2)->save(nw2,false); + } + } + } + } else if (member.is_object()) { + for(auto db2=dbs.begin();db2!=dbs.end();++db2) { + if (db->get() != db2->get()) { + nlohmann::json nw2,m2; + if ((!(*db2)->get(networkId,nw2,memberId,m2))||((m2.is_object())&&(OSUtils::jsonInt(m2["revision"],0) < OSUtils::jsonInt(member["revision"],0)))) { + m2 = member; + (*db2)->save(m2,false); + } + } + } + } + } + } catch ( ... ) {} // skip entries that generate JSON errors + }); + } + } + }); +} + +DBMirrorSet::~DBMirrorSet() +{ + _running = false; + _syncCheckerThread.join(); +} + +bool DBMirrorSet::hasNetwork(const uint64_t networkId) const +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + if ((*d)->hasNetwork(networkId)) + return true; + } + return false; +} + +bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network) +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + if ((*d)->get(networkId,network)) { + return true; + } + } + return false; +} + +bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member) +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + if ((*d)->get(networkId,network,memberId,member)) + return true; + } + return false; +} + +bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,DB::NetworkSummaryInfo &info) +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + if ((*d)->get(networkId,network,memberId,member,info)) + return true; + } + return false; +} + +bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,std::vector &members) +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + if ((*d)->get(networkId,network,members)) + return true; + } + return false; +} + +AuthInfo DBMirrorSet::getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL) +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + AuthInfo info = (*d)->getSSOAuthInfo(member, redirectURL); + if (info.enabled) { + return info; + } + } + return AuthInfo(); +} + +void DBMirrorSet::networks(std::set &networks) +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + (*d)->networks(networks); + } +} + +bool DBMirrorSet::waitForReady() +{ + bool r = false; + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + r |= (*d)->waitForReady(); + } + return r; +} + +bool DBMirrorSet::isReady() +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + if (!(*d)->isReady()) + return false; + } + return true; +} + +bool DBMirrorSet::save(nlohmann::json &record,bool notifyListeners) +{ + std::vector< std::shared_ptr > dbs; + { + std::unique_lock l(_dbs_l); + dbs = _dbs; + } + if (notifyListeners) { + for(auto d=dbs.begin();d!=dbs.end();++d) { + if ((*d)->save(record,true)) + return true; + } + return false; + } else { + bool modified = false; + for(auto d=dbs.begin();d!=dbs.end();++d) { + modified |= (*d)->save(record,false); + } + return modified; + } +} + +void DBMirrorSet::eraseNetwork(const uint64_t networkId) +{ + std::unique_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + (*d)->eraseNetwork(networkId); + } +} + +void DBMirrorSet::eraseMember(const uint64_t networkId,const uint64_t memberId) +{ + std::unique_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + (*d)->eraseMember(networkId,memberId); + } +} + +void DBMirrorSet::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) +{ + std::shared_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + (*d)->nodeIsOnline(networkId,memberId,physicalAddress); + } +} + +void DBMirrorSet::onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network) +{ + nlohmann::json record(network); + std::unique_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + if (d->get() != db) { + (*d)->save(record,false); + } + } + _listener->onNetworkUpdate(this,networkId,network); +} + +void DBMirrorSet::onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member) +{ + nlohmann::json record(member); + std::unique_lock l(_dbs_l); + for(auto d=_dbs.begin();d!=_dbs.end();++d) { + if (d->get() != db) { + (*d)->save(record,false); + } + } + _listener->onNetworkMemberUpdate(this,networkId,memberId,member); +} + +void DBMirrorSet::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId) +{ + _listener->onNetworkMemberDeauthorize(this,networkId,memberId); +} + +} // namespace ZeroTier diff --git a/controller/DBMirrorSet.hpp b/controller/DBMirrorSet.hpp new file mode 100644 index 0000000..8881440 --- /dev/null +++ b/controller/DBMirrorSet.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#ifndef ZT_DBMIRRORSET_HPP +#define ZT_DBMIRRORSET_HPP + +#include "DB.hpp" + +#include +#include +#include +#include +#include + +namespace ZeroTier { + +class DBMirrorSet : public DB::ChangeListener +{ +public: + DBMirrorSet(DB::ChangeListener *listener); + virtual ~DBMirrorSet(); + + bool hasNetwork(const uint64_t networkId) const; + + bool get(const uint64_t networkId,nlohmann::json &network); + bool get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member); + bool get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,DB::NetworkSummaryInfo &info); + bool get(const uint64_t networkId,nlohmann::json &network,std::vector &members); + + void networks(std::set &networks); + + bool waitForReady(); + bool isReady(); + bool save(nlohmann::json &record,bool notifyListeners); + void eraseNetwork(const uint64_t networkId); + void eraseMember(const uint64_t networkId,const uint64_t memberId); + void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress); + + // These are called by various DB instances when changes occur. + virtual void onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network); + virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member); + virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId); + + AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL); + + inline void addDB(const std::shared_ptr &db) + { + db->addListener(this); + std::unique_lock l(_dbs_l); + _dbs.push_back(db); + } + +private: + DB::ChangeListener *const _listener; + std::atomic_bool _running; + std::thread _syncCheckerThread; + std::vector< std::shared_ptr< DB > > _dbs; + mutable std::shared_mutex _dbs_l; +}; + +} // namespace ZeroTier + +#endif diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp new file mode 100644 index 0000000..14c3725 --- /dev/null +++ b/controller/EmbeddedNetworkController.cpp @@ -0,0 +1,2139 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../include/ZeroTierOne.h" +#include "../version.h" + +#include "EmbeddedNetworkController.hpp" +#include "LFDB.hpp" +#include "FileDB.hpp" +#ifdef ZT_CONTROLLER_USE_LIBPQ +#include "PostgreSQL.hpp" +#endif + +#include "../node/Node.hpp" +#include "../node/CertificateOfMembership.hpp" +#include "../node/NetworkConfig.hpp" +#include "../node/Dictionary.hpp" +#include "../node/MAC.hpp" + +using json = nlohmann::json; + +// API version reported via JSON control plane +#define ZT_NETCONF_CONTROLLER_API_VERSION 4 + +// Min duration between requests for an address/nwid combo to prevent floods +#define ZT_NETCONF_MIN_REQUEST_PERIOD 1000 + +// Global maximum size of arrays in JSON objects +#define ZT_CONTROLLER_MAX_ARRAY_SIZE 16384 + +namespace ZeroTier { + +namespace { + +static json _renderRule(ZT_VirtualNetworkRule &rule) +{ + char tmp[128]; + json r = json::object(); + const ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rule.t & 0x3f); + + switch(rt) { + case ZT_NETWORK_RULE_ACTION_DROP: + r["type"] = "ACTION_DROP"; + break; + case ZT_NETWORK_RULE_ACTION_ACCEPT: + r["type"] = "ACTION_ACCEPT"; + break; + case ZT_NETWORK_RULE_ACTION_TEE: + r["type"] = "ACTION_TEE"; + r["address"] = Address(rule.v.fwd.address).toString(tmp); + r["flags"] = (unsigned int)rule.v.fwd.flags; + r["length"] = (unsigned int)rule.v.fwd.length; + break; + case ZT_NETWORK_RULE_ACTION_WATCH: + r["type"] = "ACTION_WATCH"; + r["address"] = Address(rule.v.fwd.address).toString(tmp); + r["flags"] = (unsigned int)rule.v.fwd.flags; + r["length"] = (unsigned int)rule.v.fwd.length; + break; + case ZT_NETWORK_RULE_ACTION_REDIRECT: + r["type"] = "ACTION_REDIRECT"; + r["address"] = Address(rule.v.fwd.address).toString(tmp); + r["flags"] = (unsigned int)rule.v.fwd.flags; + break; + case ZT_NETWORK_RULE_ACTION_BREAK: + r["type"] = "ACTION_BREAK"; + break; + default: + break; + } + + if (r.empty()) { + switch(rt) { + case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS: + r["type"] = "MATCH_SOURCE_ZEROTIER_ADDRESS"; + r["zt"] = Address(rule.v.zt).toString(tmp); + break; + case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS: + r["type"] = "MATCH_DEST_ZEROTIER_ADDRESS"; + r["zt"] = Address(rule.v.zt).toString(tmp); + break; + case ZT_NETWORK_RULE_MATCH_VLAN_ID: + r["type"] = "MATCH_VLAN_ID"; + r["vlanId"] = (unsigned int)rule.v.vlanId; + break; + case ZT_NETWORK_RULE_MATCH_VLAN_PCP: + r["type"] = "MATCH_VLAN_PCP"; + r["vlanPcp"] = (unsigned int)rule.v.vlanPcp; + break; + case ZT_NETWORK_RULE_MATCH_VLAN_DEI: + r["type"] = "MATCH_VLAN_DEI"; + r["vlanDei"] = (unsigned int)rule.v.vlanDei; + break; + case ZT_NETWORK_RULE_MATCH_MAC_SOURCE: + r["type"] = "MATCH_MAC_SOURCE"; + OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]); + r["mac"] = tmp; + break; + case ZT_NETWORK_RULE_MATCH_MAC_DEST: + r["type"] = "MATCH_MAC_DEST"; + OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]); + r["mac"] = tmp; + break; + case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE: + r["type"] = "MATCH_IPV4_SOURCE"; + r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(tmp); + break; + case ZT_NETWORK_RULE_MATCH_IPV4_DEST: + r["type"] = "MATCH_IPV4_DEST"; + r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(tmp); + break; + case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE: + r["type"] = "MATCH_IPV6_SOURCE"; + r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(tmp); + break; + case ZT_NETWORK_RULE_MATCH_IPV6_DEST: + r["type"] = "MATCH_IPV6_DEST"; + r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(tmp); + break; + case ZT_NETWORK_RULE_MATCH_IP_TOS: + r["type"] = "MATCH_IP_TOS"; + r["mask"] = (unsigned int)rule.v.ipTos.mask; + r["start"] = (unsigned int)rule.v.ipTos.value[0]; + r["end"] = (unsigned int)rule.v.ipTos.value[1]; + break; + case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL: + r["type"] = "MATCH_IP_PROTOCOL"; + r["ipProtocol"] = (unsigned int)rule.v.ipProtocol; + break; + case ZT_NETWORK_RULE_MATCH_ETHERTYPE: + r["type"] = "MATCH_ETHERTYPE"; + r["etherType"] = (unsigned int)rule.v.etherType; + break; + case ZT_NETWORK_RULE_MATCH_ICMP: + r["type"] = "MATCH_ICMP"; + r["icmpType"] = (unsigned int)rule.v.icmp.type; + if ((rule.v.icmp.flags & 0x01) != 0) + r["icmpCode"] = (unsigned int)rule.v.icmp.code; + else r["icmpCode"] = json(); + break; + case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE: + r["type"] = "MATCH_IP_SOURCE_PORT_RANGE"; + r["start"] = (unsigned int)rule.v.port[0]; + r["end"] = (unsigned int)rule.v.port[1]; + break; + case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE: + r["type"] = "MATCH_IP_DEST_PORT_RANGE"; + r["start"] = (unsigned int)rule.v.port[0]; + r["end"] = (unsigned int)rule.v.port[1]; + break; + case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS: + r["type"] = "MATCH_CHARACTERISTICS"; + OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.characteristics); + r["mask"] = tmp; + break; + case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE: + r["type"] = "MATCH_FRAME_SIZE_RANGE"; + r["start"] = (unsigned int)rule.v.frameSize[0]; + r["end"] = (unsigned int)rule.v.frameSize[1]; + break; + case ZT_NETWORK_RULE_MATCH_RANDOM: + r["type"] = "MATCH_RANDOM"; + r["probability"] = (unsigned long)rule.v.randomProbability; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE: + r["type"] = "MATCH_TAGS_DIFFERENCE"; + r["id"] = rule.v.tag.id; + r["value"] = rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND: + r["type"] = "MATCH_TAGS_BITWISE_AND"; + r["id"] = rule.v.tag.id; + r["value"] = rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR: + r["type"] = "MATCH_TAGS_BITWISE_OR"; + r["id"] = rule.v.tag.id; + r["value"] = rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR: + r["type"] = "MATCH_TAGS_BITWISE_XOR"; + r["id"] = rule.v.tag.id; + r["value"] = rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL: + r["type"] = "MATCH_TAGS_EQUAL"; + r["id"] = rule.v.tag.id; + r["value"] = rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAG_SENDER: + r["type"] = "MATCH_TAG_SENDER"; + r["id"] = rule.v.tag.id; + r["value"] = rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER: + r["type"] = "MATCH_TAG_RECEIVER"; + r["id"] = rule.v.tag.id; + r["value"] = rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: + r["type"] = "INTEGER_RANGE"; + OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.intRange.start); + r["start"] = tmp; + OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.intRange.start + (uint64_t)rule.v.intRange.end); + r["end"] = tmp; + r["idx"] = rule.v.intRange.idx; + r["little"] = ((rule.v.intRange.format & 0x80) != 0); + r["bits"] = (rule.v.intRange.format & 63) + 1; + break; + default: + break; + } + + if (!r.empty()) { + r["not"] = ((rule.t & 0x80) != 0); + r["or"] = ((rule.t & 0x40) != 0); + } + } + + return r; +} + +static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule) +{ + if (!r.is_object()) + return false; + + const std::string t(OSUtils::jsonString(r["type"],"")); + memset(&rule,0,sizeof(ZT_VirtualNetworkRule)); + + if (OSUtils::jsonBool(r["not"],false)) + rule.t = 0x80; + else rule.t = 0x00; + if (OSUtils::jsonBool(r["or"],false)) + rule.t |= 0x40; + + bool tag = false; + if (t == "ACTION_DROP") { + rule.t |= ZT_NETWORK_RULE_ACTION_DROP; + return true; + } else if (t == "ACTION_ACCEPT") { + rule.t |= ZT_NETWORK_RULE_ACTION_ACCEPT; + return true; + } else if (t == "ACTION_TEE") { + rule.t |= ZT_NETWORK_RULE_ACTION_TEE; + rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL; + rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL); + rule.v.fwd.length = (uint16_t)(OSUtils::jsonInt(r["length"],0ULL) & 0xffffULL); + return true; + } else if (t == "ACTION_WATCH") { + rule.t |= ZT_NETWORK_RULE_ACTION_WATCH; + rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL; + rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL); + rule.v.fwd.length = (uint16_t)(OSUtils::jsonInt(r["length"],0ULL) & 0xffffULL); + return true; + } else if (t == "ACTION_REDIRECT") { + rule.t |= ZT_NETWORK_RULE_ACTION_REDIRECT; + rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL; + rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL); + return true; + } else if (t == "ACTION_BREAK") { + rule.t |= ZT_NETWORK_RULE_ACTION_BREAK; + return true; + } else if (t == "MATCH_SOURCE_ZEROTIER_ADDRESS") { + rule.t |= ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS; + rule.v.zt = Utils::hexStrToU64(OSUtils::jsonString(r["zt"],"0").c_str()) & 0xffffffffffULL; + return true; + } else if (t == "MATCH_DEST_ZEROTIER_ADDRESS") { + rule.t |= ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS; + rule.v.zt = Utils::hexStrToU64(OSUtils::jsonString(r["zt"],"0").c_str()) & 0xffffffffffULL; + return true; + } else if (t == "MATCH_VLAN_ID") { + rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_ID; + rule.v.vlanId = (uint16_t)(OSUtils::jsonInt(r["vlanId"],0ULL) & 0xffffULL); + return true; + } else if (t == "MATCH_VLAN_PCP") { + rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_PCP; + rule.v.vlanPcp = (uint8_t)(OSUtils::jsonInt(r["vlanPcp"],0ULL) & 0xffULL); + return true; + } else if (t == "MATCH_VLAN_DEI") { + rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_DEI; + rule.v.vlanDei = (uint8_t)(OSUtils::jsonInt(r["vlanDei"],0ULL) & 0xffULL); + return true; + } else if (t == "MATCH_MAC_SOURCE") { + rule.t |= ZT_NETWORK_RULE_MATCH_MAC_SOURCE; + std::string mac(OSUtils::jsonString(r["mac"],"0")); + Utils::cleanMac(mac); + Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6); + return true; + } else if (t == "MATCH_MAC_DEST") { + rule.t |= ZT_NETWORK_RULE_MATCH_MAC_DEST; + std::string mac(OSUtils::jsonString(r["mac"],"0")); + Utils::cleanMac(mac); + Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6); + return true; + } else if (t == "MATCH_IPV4_SOURCE") { + rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_SOURCE; + InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0").c_str()); + rule.v.ipv4.ip = reinterpret_cast(&ip)->sin_addr.s_addr; + rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast(&ip)->sin_port) & 0xff; + if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32; + return true; + } else if (t == "MATCH_IPV4_DEST") { + rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_DEST; + InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0").c_str()); + rule.v.ipv4.ip = reinterpret_cast(&ip)->sin_addr.s_addr; + rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast(&ip)->sin_port) & 0xff; + if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32; + return true; + } else if (t == "MATCH_IPV6_SOURCE") { + rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_SOURCE; + InetAddress ip(OSUtils::jsonString(r["ip"],"::0").c_str()); + memcpy(rule.v.ipv6.ip,reinterpret_cast(&ip)->sin6_addr.s6_addr,16); + rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast(&ip)->sin6_port) & 0xff; + if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128; + return true; + } else if (t == "MATCH_IPV6_DEST") { + rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_DEST; + InetAddress ip(OSUtils::jsonString(r["ip"],"::0").c_str()); + memcpy(rule.v.ipv6.ip,reinterpret_cast(&ip)->sin6_addr.s6_addr,16); + rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast(&ip)->sin6_port) & 0xff; + if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128; + return true; + } else if (t == "MATCH_IP_TOS") { + rule.t |= ZT_NETWORK_RULE_MATCH_IP_TOS; + rule.v.ipTos.mask = (uint8_t)(OSUtils::jsonInt(r["mask"],0ULL) & 0xffULL); + rule.v.ipTos.value[0] = (uint8_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffULL); + rule.v.ipTos.value[1] = (uint8_t)(OSUtils::jsonInt(r["end"],0ULL) & 0xffULL); + return true; + } else if (t == "MATCH_IP_PROTOCOL") { + rule.t |= ZT_NETWORK_RULE_MATCH_IP_PROTOCOL; + rule.v.ipProtocol = (uint8_t)(OSUtils::jsonInt(r["ipProtocol"],0ULL) & 0xffULL); + return true; + } else if (t == "MATCH_ETHERTYPE") { + rule.t |= ZT_NETWORK_RULE_MATCH_ETHERTYPE; + rule.v.etherType = (uint16_t)(OSUtils::jsonInt(r["etherType"],0ULL) & 0xffffULL); + return true; + } else if (t == "MATCH_ICMP") { + rule.t |= ZT_NETWORK_RULE_MATCH_ICMP; + rule.v.icmp.type = (uint8_t)(OSUtils::jsonInt(r["icmpType"],0ULL) & 0xffULL); + json &code = r["icmpCode"]; + if (code.is_null()) { + rule.v.icmp.code = 0; + rule.v.icmp.flags = 0x00; + } else { + rule.v.icmp.code = (uint8_t)(OSUtils::jsonInt(code,0ULL) & 0xffULL); + rule.v.icmp.flags = 0x01; + } + return true; + } else if (t == "MATCH_IP_SOURCE_PORT_RANGE") { + rule.t |= ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE; + rule.v.port[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL); + rule.v.port[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.port[0]) & 0xffffULL); + return true; + } else if (t == "MATCH_IP_DEST_PORT_RANGE") { + rule.t |= ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE; + rule.v.port[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL); + rule.v.port[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.port[0]) & 0xffffULL); + return true; + } else if (t == "MATCH_CHARACTERISTICS") { + rule.t |= ZT_NETWORK_RULE_MATCH_CHARACTERISTICS; + if (r.count("mask")) { + json &v = r["mask"]; + if (v.is_number()) { + rule.v.characteristics = v; + } else { + std::string tmp = v; + rule.v.characteristics = Utils::hexStrToU64(tmp.c_str()); + } + } + return true; + } else if (t == "MATCH_FRAME_SIZE_RANGE") { + rule.t |= ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE; + rule.v.frameSize[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL); + rule.v.frameSize[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.frameSize[0]) & 0xffffULL); + return true; + } else if (t == "MATCH_RANDOM") { + rule.t |= ZT_NETWORK_RULE_MATCH_RANDOM; + rule.v.randomProbability = (uint32_t)(OSUtils::jsonInt(r["probability"],0ULL) & 0xffffffffULL); + return true; + } else if (t == "MATCH_TAGS_DIFFERENCE") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE; + tag = true; + } else if (t == "MATCH_TAGS_BITWISE_AND") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND; + tag = true; + } else if (t == "MATCH_TAGS_BITWISE_OR") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR; + tag = true; + } else if (t == "MATCH_TAGS_BITWISE_XOR") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR; + tag = true; + } else if (t == "MATCH_TAGS_EQUAL") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_EQUAL; + tag = true; + } else if (t == "MATCH_TAG_SENDER") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAG_SENDER; + tag = true; + } else if (t == "MATCH_TAG_RECEIVER") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAG_RECEIVER; + tag = true; + } else if (t == "INTEGER_RANGE") { + json &s = r["start"]; + if (s.is_string()) { + std::string tmp = s; + rule.v.intRange.start = Utils::hexStrToU64(tmp.c_str()); + } else { + rule.v.intRange.start = OSUtils::jsonInt(s,0ULL); + } + json &e = r["end"]; + if (e.is_string()) { + std::string tmp = e; + rule.v.intRange.end = (uint32_t)(Utils::hexStrToU64(tmp.c_str()) - rule.v.intRange.start); + } else { + rule.v.intRange.end = (uint32_t)(OSUtils::jsonInt(e,0ULL) - rule.v.intRange.start); + } + rule.v.intRange.idx = (uint16_t)OSUtils::jsonInt(r["idx"],0ULL); + rule.v.intRange.format = (OSUtils::jsonBool(r["little"],false)) ? 0x80 : 0x00; + rule.v.intRange.format |= (uint8_t)((OSUtils::jsonInt(r["bits"],1ULL) - 1) & 63); + } + + if (tag) { + rule.v.tag.id = (uint32_t)(OSUtils::jsonInt(r["id"],0ULL) & 0xffffffffULL); + rule.v.tag.value = (uint32_t)(OSUtils::jsonInt(r["value"],0ULL) & 0xffffffffULL); + return true; + } + + return false; +} + +} // anonymous namespace + +EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, RedisConfig *rc) + : _startTime(OSUtils::now()) + , _listenPort(listenPort) + , _node(node) + , _ztPath(ztPath) + , _path(dbPath) + , _signingId() + , _signingIdAddressString() + , _sender((NetworkController::Sender *)0) + , _db(this) + , _queue() + , _threads() + , _threads_l() + , _memberStatus() + , _memberStatus_l() + , _expiringSoon() + , _expiringSoon_l() + , _rc(rc) + , _ssoExpiryRunning(true) + , _ssoExpiry(std::thread(&EmbeddedNetworkController::_ssoExpiryThread, this)) + +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + , _member_status_lookup{"nc_member_status_lookup",""} + , _member_status_lookup_count{"nc_member_status_lookup_count",""} + , _node_is_online{"nc_node_is_online",""} + , _node_is_online_count{"nc_node_is_online_count",""} + , _get_and_init_member{"nc_get_and_init_member",""} + , _get_and_init_member_count{"nc_get_and_init_member_count",""} + , _have_identity{"nc_have_identity",""} + , _have_identity_count{"nc_have_identity_count",""} + , _determine_auth{"nc_determine_auth",""} + , _determine_auth_count{"nc_determine_auth_count",""} + , _sso_check{"nc_sso_check",""} + , _sso_check_count{"nc_sso_check_count",""} + , _auth_check{"nc_auth_check",""} + , _auth_check_count{"nc_auth_check_count",""} + , _json_schlep{"nc_json_schlep",""} + , _json_schlep_count{"nc_json_schlep_count",""} + , _issue_certificate{"nc_issue_certificate", ""} + , _issue_certificate_count{"nc_issue_certificate_count",""} + , _save_member{"nc_save_member",""} + , _save_member_count{"nc_save_member_count",""} + , _send_netconf{"nc_send_netconf2",""} + , _send_netconf_count{"nc_send_netconf2_count",""} +#endif +{ +} + +EmbeddedNetworkController::~EmbeddedNetworkController() +{ + std::lock_guard l(_threads_l); + _queue.stop(); + for(auto t=_threads.begin();t!=_threads.end();++t) { + t->join(); + } + _ssoExpiryRunning = false; + _ssoExpiry.join(); +} + +void EmbeddedNetworkController::setSSORedirectURL(const std::string &url) { + _ssoRedirectURL = url; +} + +void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender) +{ + char tmp[64]; + _signingId = signingId; + _sender = sender; + _signingIdAddressString = signingId.address().toString(tmp); + +#ifdef ZT_CONTROLLER_USE_LIBPQ + if ((_path.length() > 9)&&(_path.substr(0,9) == "postgres:")) { + _db.addDB(std::shared_ptr(new PostgreSQL(_signingId,_path.substr(9).c_str(), _listenPort, _rc))); + } else { +#endif + _db.addDB(std::shared_ptr(new FileDB(_path.c_str()))); +#ifdef ZT_CONTROLLER_USE_LIBPQ + } +#endif + + std::string lfJSON; + OSUtils::readFile((_ztPath + ZT_PATH_SEPARATOR_S "local.conf").c_str(),lfJSON); + if (lfJSON.length() > 0) { + nlohmann::json lfConfig(OSUtils::jsonParse(lfJSON)); + nlohmann::json &settings = lfConfig["settings"]; + if (settings.is_object()) { + nlohmann::json &controllerDb = settings["controllerDb"]; + if (controllerDb.is_object()) { + std::string type = controllerDb["type"]; + if (type == "lf") { + std::string lfOwner = controllerDb["owner"]; + std::string lfHost = controllerDb["host"]; + int lfPort = controllerDb["port"]; + bool storeOnlineState = controllerDb["storeOnlineState"]; + if ((lfOwner.length())&&(lfHost.length())&&(lfPort > 0)&&(lfPort < 65536)) { + std::size_t pubHdrLoc = lfOwner.find("Public: "); + if ((pubHdrLoc > 0)&&((pubHdrLoc + 8) < lfOwner.length())) { + std::string lfOwnerPublic = lfOwner.substr(pubHdrLoc + 8); + std::size_t pubHdrEnd = lfOwnerPublic.find_first_of("\n\r\t "); + if (pubHdrEnd != std::string::npos) { + lfOwnerPublic = lfOwnerPublic.substr(0,pubHdrEnd); + _db.addDB(std::shared_ptr(new LFDB(_signingId,_path.c_str(),lfOwner.c_str(),lfOwnerPublic.c_str(),lfHost.c_str(),lfPort,storeOnlineState))); + } + } + } + } + } + } + } + + _db.waitForReady(); +} + +void EmbeddedNetworkController::request( + uint64_t nwid, + const InetAddress &fromAddr, + uint64_t requestPacketId, + const Identity &identity, + const Dictionary &metaData) +{ + if (((!_signingId)||(!_signingId.hasPrivate()))||(_signingId.address().toInt() != (nwid >> 24))||(!_sender)) + return; + _startThreads(); + + const int64_t now = OSUtils::now(); + + if (requestPacketId) { + std::lock_guard l(_memberStatus_l); + _MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,identity.address().toInt())]; + if ((now - ms.lastRequestTime) <= ZT_NETCONF_MIN_REQUEST_PERIOD) { + return; + } + ms.lastRequestTime = now; + } + + _RQEntry *qe = new _RQEntry; + qe->nwid = nwid; + qe->requestPacketId = requestPacketId; + qe->fromAddr = fromAddr; + qe->identity = identity; + qe->metaData = metaData; + qe->type = _RQEntry::RQENTRY_TYPE_REQUEST; + _queue.post(qe); +} + +std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networkID, const std::string &body) +{ + json b = OSUtils::jsonParse(body); + + char nwids[24]; + OSUtils::ztsnprintf(nwids, sizeof(nwids), "%.16llx", networkID); + + json network; + _db.get(networkID, network); + DB::initNetwork(network); + if (b.count("name")) network["name"] = OSUtils::jsonString(b["name"],""); + if (b.count("private")) network["private"] = OSUtils::jsonBool(b["private"],true); + if (b.count("enableBroadcast")) network["enableBroadcast"] = OSUtils::jsonBool(b["enableBroadcast"],false); + if (b.count("multicastLimit")) network["multicastLimit"] = OSUtils::jsonInt(b["multicastLimit"],32ULL); + if (b.count("mtu")) network["mtu"] = std::max(std::min((unsigned int)OSUtils::jsonInt(b["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU); + + if (b.count("remoteTraceTarget")) { + const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],"")); + if (rtt.length() == 10) { + network["remoteTraceTarget"] = rtt; + } else { + network["remoteTraceTarget"] = json(); + } + } + if (b.count("remoteTraceLevel")) network["remoteTraceLevel"] = OSUtils::jsonInt(b["remoteTraceLevel"],0ULL); + + if (b.count("v4AssignMode")) { + json nv4m; + json &v4m = b["v4AssignMode"]; + if (v4m.is_string()) { // backward compatibility + nv4m["zt"] = (OSUtils::jsonString(v4m,"") == "zt"); + } else if (v4m.is_object()) { + nv4m["zt"] = OSUtils::jsonBool(v4m["zt"],false); + } else nv4m["zt"] = false; + network["v4AssignMode"] = nv4m; + } + + if (b.count("v6AssignMode")) { + json nv6m; + json &v6m = b["v6AssignMode"]; + if (!nv6m.is_object()) nv6m = json::object(); + if (v6m.is_string()) { // backward compatibility + std::vector v6ms(OSUtils::split(OSUtils::jsonString(v6m,"").c_str(),",","","")); + std::sort(v6ms.begin(),v6ms.end()); + v6ms.erase(std::unique(v6ms.begin(),v6ms.end()),v6ms.end()); + nv6m["rfc4193"] = false; + nv6m["zt"] = false; + nv6m["6plane"] = false; + for(std::vector::iterator i(v6ms.begin());i!=v6ms.end();++i) { + if (*i == "rfc4193") + nv6m["rfc4193"] = true; + else if (*i == "zt") + nv6m["zt"] = true; + else if (*i == "6plane") + nv6m["6plane"] = true; + } + } else if (v6m.is_object()) { + if (v6m.count("rfc4193")) nv6m["rfc4193"] = OSUtils::jsonBool(v6m["rfc4193"],false); + if (v6m.count("zt")) nv6m["zt"] = OSUtils::jsonBool(v6m["zt"],false); + if (v6m.count("6plane")) nv6m["6plane"] = OSUtils::jsonBool(v6m["6plane"],false); + } else { + nv6m["rfc4193"] = false; + nv6m["zt"] = false; + nv6m["6plane"] = false; + } + network["v6AssignMode"] = nv6m; + } + + if (b.count("routes")) { + json &rts = b["routes"]; + if (rts.is_array()) { + json nrts = json::array(); + for(unsigned long i=0;i().c_str()); + InetAddress v; + if (via.is_string()) v.fromString(via.get().c_str()); + if ( ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) && (t.netmaskBitsValid()) ) { + json tmp; + char tmp2[64]; + tmp["target"] = t.toString(tmp2); + if (v.ss_family == t.ss_family) + tmp["via"] = v.toIpString(tmp2); + else tmp["via"] = json(); + nrts.push_back(tmp); + if (nrts.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + } + } + } + network["routes"] = nrts; + } + } + + if (b.count("ipAssignmentPools")) { + json &ipp = b["ipAssignmentPools"]; + if (ipp.is_array()) { + json nipp = json::array(); + for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + } + } + network["ipAssignmentPools"] = nipp; + } + } + + if (b.count("rules")) { + json &rules = b["rules"]; + if (rules.is_array()) { + json nrules = json::array(); + for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + } + } + network["rules"] = nrules; + } + } + + if (b.count("authTokens")) { + json &authTokens = b["authTokens"]; + if (authTokens.is_object()) { + json nat; + for(json::iterator t(authTokens.begin());t!=authTokens.end();++t) { + if ((t.value().is_number())&&(t.value() >= 0)) + nat[t.key()] = t.value(); + } + network["authTokens"] = nat; + } else { + network["authTokens"] = {{}}; + } + } + + if (b.count("capabilities")) { + json &capabilities = b["capabilities"]; + if (capabilities.is_array()) { + std::map< uint64_t,json > ncaps; + for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + } + } + } + ncap["rules"] = nrules; + + ncaps[capId] = ncap; + } + } + + json ncapsa = json::array(); + for(std::map< uint64_t,json >::iterator c(ncaps.begin());c!=ncaps.end();++c) { + ncapsa.push_back(c->second); + if (ncapsa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + network["capabilities"] = ncapsa; + } + } + + if (b.count("tags")) { + json &tags = b["tags"]; + if (tags.is_array()) { + std::map< uint64_t,json > ntags; + for(unsigned long i=0;i::iterator t(ntags.begin());t!=ntags.end();++t) { + ntagsa.push_back(t->second); + if (ntagsa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + network["tags"] = ntagsa; + } + } + + if (b.count("dns")) { + json &dns = b["dns"]; + if (dns.is_object()) { + json nd; + + nd["domain"] = dns["domain"]; + + json &srv = dns["servers"]; + if (srv.is_array()) { + json ns = json::array(); + for(unsigned int i=0;i setContent) +{ + // Control plane Endpoints + std::string controllerPath = "/controller"; + std::string networkListPath = "/controller/network"; + std::string networkListPath2 = "/unstable/controller/network"; + std::string networkPath = "/controller/network/([0-9a-fA-F]{16})"; + std::string oldAndBustedNetworkCreatePath = "/controller/network/([0-9a-fA-F]{10})______"; + std::string memberListPath = "/controller/network/([0-9a-fA-F]{16})/member"; + std::string memberListPath2 = "/unstable/controller/network/([0-9a-fA-F]{16})/member"; + std::string memberPath = "/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})"; + + + auto controllerGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + char tmp[4096]; + const bool dbOk = _db.isReady(); + OSUtils::ztsnprintf( + tmp, + sizeof(tmp), + "{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu,\n\t\"databaseReady\": %s\n}\n", + ZT_NETCONF_CONTROLLER_API_VERSION, + (unsigned long long)OSUtils::now(), + dbOk ? "true" : "false"); + + if (!dbOk) { + res.status = 503; + } + + setContent(req, res, tmp); + }; + s.Get(controllerPath, controllerGet); + sv6.Get(controllerPath, controllerGet); + + auto networkListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + std::set networkIds; + _db.networks(networkIds); + char tmp[64]; + + auto out = json::array(); + for(std::set::const_iterator i(networkIds.begin()); i != networkIds.end(); ++i) { + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", *i); + out.push_back(tmp); + } + + setContent(req, res, out.dump()); + }; + s.Get(networkListPath, networkListGet); + sv6.Get(networkListPath, networkListGet); + + auto networkListGet2 = [&, setContent](const httplib::Request &req, httplib::Response &res) { + std::set networkIds; + _db.networks(networkIds); + + auto meta = json::object(); + auto data = json::array(); + uint64_t networkCount = 0; + + for(std::set::const_iterator nwid(networkIds.begin()); nwid != networkIds.end(); ++nwid) { + json network; + if (!_db.get(*nwid, network)) { + continue; + } + + std::vector memTmp; + if (_db.get(*nwid, network, memTmp)) { + if (!network.is_null()) { + uint64_t authorizedCount = 0; + uint64_t totalCount = memTmp.size(); + networkCount++; + + for (auto m = memTmp.begin(); m != memTmp.end(); ++m) { + bool a = OSUtils::jsonBool((*m)["authorized"], 0); + if (a) { authorizedCount++; } + } + + auto nwMeta = json::object(); + nwMeta["totalMemberCount"] = totalCount; + nwMeta["authorizedMemberCount"] = authorizedCount; + network["meta"] = nwMeta; + + data.push_back(network); + } + } + } + meta["networkCount"] = networkCount; + + auto out = json::object(); + out["data"] = data; + out["meta"] = meta; + + setContent(req, res, out.dump()); + }; + s.Get(networkListPath2, networkListGet2); + sv6.Get(networkListPath2, networkListGet2); + + auto networkGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkID = req.matches[1]; + uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str()); + json network; + if (!_db.get(nwid, network)) { + res.status = 404; + return; + } + + setContent(req, res, network.dump()); + }; + s.Get(networkPath, networkGet); + sv6.Get(networkPath, networkGet); + + auto createNewNetwork = [&, setContent](const httplib::Request &req, httplib::Response &res) { + // fprintf(stderr, "creating new network (new style)\n"); + uint64_t nwid = 0; + uint64_t nwidPrefix = (Utils::hexStrToU64(_signingIdAddressString.c_str()) << 24) & 0xffffffffff000000ULL; + uint64_t nwidPostfix = 0; + for(unsigned long k=0;k<100000;++k) { // sanity limit on trials + Utils::getSecureRandom(&nwidPostfix,sizeof(nwidPostfix)); + uint64_t tryNwid = nwidPrefix | (nwidPostfix & 0xffffffULL); + if ((tryNwid & 0xffffffULL) == 0ULL) tryNwid |= 1ULL; + if (!_db.hasNetwork(tryNwid)) { + nwid = tryNwid; + break; + } + } + if (!nwid) { + res.status = 503; + return; + } + + setContent(req, res, networkUpdateFromPostData(nwid, req.body)); + }; + s.Put(networkListPath, createNewNetwork); + s.Post(networkListPath, createNewNetwork); + sv6.Put(networkListPath, createNewNetwork); + sv6.Post(networkListPath, createNewNetwork); + + auto createNewNetworkOldAndBusted = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto inID = req.matches[1].str(); + + if (inID != _signingIdAddressString) { + res.status = 400; + return; + } + + uint64_t nwid = 0; + uint64_t nwidPrefix = (Utils::hexStrToU64(inID.c_str()) << 24) & 0xffffffffff000000ULL; + uint64_t nwidPostfix = 0; + for(unsigned long k=0;k<100000;++k) { // sanity limit on trials + Utils::getSecureRandom(&nwidPostfix,sizeof(nwidPostfix)); + uint64_t tryNwid = nwidPrefix | (nwidPostfix & 0xffffffULL); + if ((tryNwid & 0xffffffULL) == 0ULL) tryNwid |= 1ULL; + if (!_db.hasNetwork(tryNwid)) { + nwid = tryNwid; + break; + } + } + if (!nwid) { + res.status = 503; + return; + } + setContent(req, res, networkUpdateFromPostData(nwid, req.body)); + }; + s.Put(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted); + s.Post(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted); + sv6.Put(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted); + sv6.Post(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted); + + auto networkPost = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkID = req.matches[1].str(); + uint64_t nwid = Utils::hexStrToU64(networkID.c_str()); + + res.status = 200; + setContent(req, res, networkUpdateFromPostData(nwid, req.body)); + }; + s.Put(networkPath, networkPost); + s.Post(networkPath, networkPost); + sv6.Put(networkPath, networkPost); + sv6.Post(networkPath, networkPost); + + auto networkDelete = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkID = req.matches[1].str(); + uint64_t nwid = Utils::hexStrToU64(networkID.c_str()); + + json network; + if (!_db.get(nwid,network)) { + res.status = 404; + return; + } + + _db.eraseNetwork(nwid); + setContent(req, res, network.dump()); + }; + s.Delete(networkPath, networkDelete); + sv6.Delete(networkPath, networkDelete); + + auto memberListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkID = req.matches[1]; + uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str()); + json network; + if (!_db.get(nwid, network)) { + res.status = 404; + return; + } + + json out = json::object(); + std::vector memTmp; + if (_db.get(nwid, network, memTmp)) { + for (auto m = memTmp.begin(); m != memTmp.end(); ++m) { + int revision = OSUtils::jsonInt((*m)["revision"], 0); + std::string id = OSUtils::jsonString((*m)["id"], ""); + if (id.length() == 10) { + out[id] = revision; + } + } + } + + setContent(req, res, out.dump()); + }; + s.Get(memberListPath, memberListGet); + sv6.Get(memberListPath, memberListGet); + + auto memberListGet2 = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkID = req.matches[1]; + uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str()); + json network; + if (!_db.get(nwid, network)) { + res.status = 404; + return; + } + + auto out = nlohmann::json::object(); + auto meta = nlohmann::json::object(); + std::vector memTmp; + if (_db.get(nwid, network, memTmp)) { + uint64_t authorizedCount = 0; + uint64_t totalCount = memTmp.size(); + for (auto m = memTmp.begin(); m != memTmp.end(); ++m) { + bool a = OSUtils::jsonBool((*m)["authorized"], 0); + if (a) { authorizedCount++; } + } + + meta["totalCount"] = totalCount; + meta["authorizedCount"] = authorizedCount; + + out["data"] = memTmp; + out["meta"] = meta; + + setContent(req, res, out.dump()); + } else { + res.status = 404; + return; + } + }; + s.Get(memberListPath2, memberListGet2); + sv6.Get(memberListPath2, memberListGet2); + + auto memberGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkID = req.matches[1]; + auto memberID = req.matches[2]; + uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str()); + uint64_t memid = Utils::hexStrToU64(memberID.str().c_str()); + json network; + json member; + if (!_db.get(nwid, network, memid, member)) { + res.status = 404; + return; + } + + setContent(req, res, member.dump()); + }; + s.Get(memberPath, memberGet); + sv6.Get(memberPath, memberGet); + + auto memberPost = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkID = req.matches[1].str(); + auto memberID = req.matches[2].str(); + uint64_t nwid = Utils::hexStrToU64(networkID.c_str()); + uint64_t memid = Utils::hexStrToU64(memberID.c_str()); + + if (!_db.hasNetwork(nwid)) { + res.status = 404; + return; + } + + json network; + json member; + _db.get(nwid, network, memid, member); + DB::initMember(member); + + json b = OSUtils::jsonParse(req.body); + + if (b.count("activeBridge")) member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"], false); + if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"], false); + if (b.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = (uint64_t)OSUtils::jsonInt(b["authenticationExpiryTime"], 0ULL); + if (b.count("authenticationURL")) member["authenticationURL"] = OSUtils::jsonString(b["authenticationURL"], ""); + if (b.count("name")) member["name"] = OSUtils::jsonString(b["name"], ""); + + if (b.count("remoteTraceTarget")) { + const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],"")); + if (rtt.length() == 10) { + member["remoteTraceTarget"] = rtt; + } else { + member["remoteTraceTarget"] = json(); + } + } + if (b.count("remoteTraceLevel")) member["remoteTraceLevel"] = OSUtils::jsonInt(b["remoteTraceLevel"],0ULL); + + if (b.count("authorized")) { + const bool newAuth = OSUtils::jsonBool(b["authorized"],false); + if (newAuth != OSUtils::jsonBool(member["authorized"],false)) { + member["authorized"] = newAuth; + member[((newAuth) ? "lastAuthorizedTime" : "lastDeauthorizedTime")] = OSUtils::now(); + if (newAuth) { + member["lastAuthorizedCredentialType"] = "api"; + member["lastAuthorizedCredential"] = json(); + } + } + } + + if (b.count("ipAssignments")) { + json &ipa = b["ipAssignments"]; + if (ipa.is_array()) { + json mipa(json::array()); + for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + } + member["ipAssignments"] = mipa; + } + } + + if (b.count("tags")) { + json &tags = b["tags"]; + if (tags.is_array()) { + std::map mtags; + for(unsigned long i=0;i::iterator t(mtags.begin());t!=mtags.end();++t) { + json ta = json::array(); + ta.push_back(t->first); + ta.push_back(t->second); + mtagsa.push_back(ta); + if (mtagsa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + member["tags"] = mtagsa; + } + } + + if (b.count("capabilities")) { + json &capabilities = b["capabilities"]; + if (capabilities.is_array()) { + json mcaps = json::array(); + for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) + break; + } + std::sort(mcaps.begin(),mcaps.end()); + mcaps.erase(std::unique(mcaps.begin(),mcaps.end()),mcaps.end()); + member["capabilities"] = mcaps; + } + } + + member["id"] = memberID; + member["address"] = memberID; + member["nwid"] = networkID; + + DB::cleanMember(member); + _db.save(member, true); + + setContent(req, res, member.dump()); + }; + s.Put(memberPath, memberPost); + s.Post(memberPath, memberPost); + sv6.Put(memberPath, memberPost); + sv6.Post(memberPath, memberPost); + + auto memberDelete = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkID = req.matches[1].str(); + auto memberID = req.matches[2].str(); + + uint64_t nwid = Utils::hexStrToU64(networkID.c_str()); + uint64_t address = Utils::hexStrToU64(memberID.c_str()); + json network, member; + + if (!_db.get(nwid, network, address, member)) { + res.status = 404; + return; + } + + if (!member.size()) { + res.status = 404; + return; + } + + _db.eraseMember(nwid, address); + + setContent(req, res, member.dump()); + }; + s.Delete(memberPath, memberDelete); + sv6.Delete(memberPath, memberDelete); +} + +void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt) +{ + static volatile unsigned long idCounter = 0; + char id[128],tmp[128]; + std::string k,v; + + try { + // Convert Dictionary into JSON object + json d; + char *saveptr = (char *)0; + for(char *l=Utils::stok(rt.data,"\n",&saveptr);(l);l=Utils::stok((char *)0,"\n",&saveptr)) { + char *eq = strchr(l,'='); + if (eq > l) { + k.assign(l,(unsigned long)(eq - l)); + v.clear(); + ++eq; + while (*eq) { + if (*eq == '\\') { + ++eq; + if (*eq) { + switch(*eq) { + case 'r': v.push_back('\r'); break; + case 'n': v.push_back('\n'); break; + case '0': v.push_back((char)0); break; + case 'e': v.push_back('='); break; + default: v.push_back(*eq); break; + } + ++eq; + } + } else { + v.push_back(*(eq++)); + } + } + if ((k.length() > 0)&&(v.length() > 0)) + d[k] = v; + } + } + + const int64_t now = OSUtils::now(); + OSUtils::ztsnprintf(id,sizeof(id),"%.10llx-%.16llx-%.10llx-%.4x",_signingId.address().toInt(),now,rt.origin,(unsigned int)(idCounter++ & 0xffff)); + d["id"] = id; + d["objtype"] = "trace"; + d["ts"] = now; + d["nodeId"] = Utils::hex10(rt.origin,tmp); + _db.save(d,true); + } catch ( ... ) { + // drop invalid trace messages if an error occurs + } +} + +void EmbeddedNetworkController::onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network) +{ + // Send an update to all members of the network that are online + const int64_t now = OSUtils::now(); + std::lock_guard l(_memberStatus_l); + for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) { + if ((i->first.networkId == networkId)&&(i->second.online(now))&&(i->second.lastRequestMetaData)) + request(networkId,InetAddress(),0,i->second.identity,i->second.lastRequestMetaData); + } +} + +void EmbeddedNetworkController::onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member) +{ + // Push update to member if online + try { + std::lock_guard l(_memberStatus_l); + _MemberStatus &ms = _memberStatus[_MemberStatusKey(networkId,memberId)]; + if ((ms.online(OSUtils::now()))&&(ms.lastRequestMetaData)) + request(networkId,InetAddress(),0,ms.identity,ms.lastRequestMetaData); + } catch ( ... ) {} +} + +void EmbeddedNetworkController::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId) +{ + const int64_t now = OSUtils::now(); + Revocation rev((uint32_t)_node->prng(),networkId,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(memberId),Revocation::CREDENTIAL_TYPE_COM); + rev.sign(_signingId); + { + std::lock_guard l(_memberStatus_l); + for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) { + if ((i->first.networkId == networkId)&&(i->second.online(now))) + _node->ncSendRevocation(Address(i->first.nodeId),rev); + } + } +} + +void EmbeddedNetworkController::_request( + uint64_t nwid, + const InetAddress &fromAddr, + uint64_t requestPacketId, + const Identity &identity, + const Dictionary &metaData) +{ + Metrics::network_config_request++; + auto tid = std::this_thread::get_id(); + std::stringstream ss; ss << tid; + std::string threadID = ss.str(); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + auto b1 = _member_status_lookup.Add({{"thread", threadID}}); + auto c1 = _member_status_lookup_count.Add({{"thread", threadID}}); + c1++; + b1.start(); +#endif + + char nwids[24]; + DB::NetworkSummaryInfo ns; + json network,member; + + if (((!_signingId)||(!_signingId.hasPrivate()))||(_signingId.address().toInt() != (nwid >> 24))||(!_sender)) { + return; + } + + const int64_t now = OSUtils::now(); + +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b1.stop(); + auto b2 = _node_is_online.Add({{"thread",threadID}}); + auto c2 = _node_is_online_count.Add({{"thread",threadID}}); + c2++; + b2.start(); +#endif + _db.nodeIsOnline(nwid,identity.address().toInt(),fromAddr); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b2.stop(); + + auto b3 = _get_and_init_member.Add({{"thread", threadID}}); + auto c3 = _get_and_init_member_count.Add({{"thread",threadID}}); + c3++; + b3.start(); +#endif + Utils::hex(nwid,nwids); + _db.get(nwid,network,identity.address().toInt(),member,ns); + if ((!network.is_object())||(network.empty())) { + _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_OBJECT_NOT_FOUND, nullptr, 0); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b3.stop(); +#endif + return; + } + const bool newMember = ((!member.is_object())||(member.empty())); + DB::initMember(member); + _MemberStatusKey msk(nwid,identity.address().toInt()); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b3.stop(); +#endif + + { +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + auto b4 = _have_identity.Add({{"thread",threadID}}); + auto c4 = _have_identity_count.Add({{"thread",threadID}}); + c4++; + b4.start(); +#endif + const std::string haveIdStr(OSUtils::jsonString(member["identity"],"")); + if (haveIdStr.length() > 0) { + // If we already know this member's identity perform a full compare. This prevents + // a "collision" from being able to auth onto our network in place of an already + // known member. + try { + if (Identity(haveIdStr.c_str()) != identity) { + _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); + #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b4.stop(); + #endif + return; + } + } catch ( ... ) { + _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); + #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b4.stop(); + #endif + return; + } + } else { + // If we do not yet know this member's identity, learn it. + char idtmp[1024]; + member["identity"] = identity.toString(false,idtmp); + } +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b4.stop(); +#endif + } + + // These are always the same, but make sure they are set + { + char tmpid[128]; + const std::string addrs(identity.address().toString(tmpid)); + member["id"] = addrs; + member["address"] = addrs; + member["nwid"] = nwids; + } + + // Determine whether and how member is authorized +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + auto b5 = _determine_auth.Add({{"thread",threadID}}); + auto c5 = _determine_auth_count.Add({{"thread",threadID}}); + c5++; + b5.start(); +#endif + bool authorized = false; + bool autoAuthorized = false; + json autoAuthCredentialType,autoAuthCredential; + if (OSUtils::jsonBool(member["authorized"],false)) { + authorized = true; + } else if (!OSUtils::jsonBool(network["private"],true)) { + authorized = true; + autoAuthorized = true; + autoAuthCredentialType = "public"; + } else { + char presentedAuth[512]; + if (metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH,presentedAuth,sizeof(presentedAuth)) > 0) { + presentedAuth[511] = (char)0; // sanity check + if ((strlen(presentedAuth) > 6)&&(!strncmp(presentedAuth,"token:",6))) { + const char *const presentedToken = presentedAuth + 6; + json authTokens(network["authTokens"]); + json &tokenExpires = authTokens[presentedToken]; + if (tokenExpires.is_number()) { + if ((tokenExpires == 0)||(tokenExpires > now)) { + authorized = true; + autoAuthorized = true; + autoAuthCredentialType = "token"; + autoAuthCredential = presentedToken; + } + } + } + } + } + + // If we auto-authorized, update member record + if ((autoAuthorized)&&(authorized)) { + member["authorized"] = true; + member["lastAuthorizedTime"] = now; + member["lastAuthorizedCredentialType"] = autoAuthCredentialType; + member["lastAuthorizedCredential"] = autoAuthCredential; + } +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b5.stop(); +#endif + + // Should we check SSO Stuff? + // If network is configured with SSO, and the member is not marked exempt: yes + // Otherwise no, we use standard auth logic. +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + auto b6 = _sso_check.Add({{"thread",threadID}}); + auto c6 = _sso_check_count.Add({{"thread",threadID}}); + c6++; + b6.start(); +#endif + AuthInfo info; + int64_t authenticationExpiryTime = -1; + bool networkSSOEnabled = OSUtils::jsonBool(network["ssoEnabled"], false); + bool memberSSOExempt = OSUtils::jsonBool(member["ssoExempt"], false); + if (networkSSOEnabled && !memberSSOExempt) { + authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0); + info = _db.getSSOAuthInfo(member, _ssoRedirectURL); + assert(info.enabled == networkSSOEnabled); + if (authenticationExpiryTime <= now) { + if (info.version == 0) { + Dictionary<4096> authInfo; + authInfo.add(ZT_AUTHINFO_DICT_KEY_VERSION, (uint64_t)0ULL); + authInfo.add(ZT_AUTHINFO_DICT_KEY_AUTHENTICATION_URL, info.authenticationURL.c_str()); + _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes()); + } else if (info.version == 1) { + Dictionary<8192> authInfo; + authInfo.add(ZT_AUTHINFO_DICT_KEY_VERSION, info.version); + authInfo.add(ZT_AUTHINFO_DICT_KEY_ISSUER_URL, info.issuerURL.c_str()); + authInfo.add(ZT_AUTHINFO_DICT_KEY_CENTRAL_ENDPOINT_URL, info.centralAuthURL.c_str()); + authInfo.add(ZT_AUTHINFO_DICT_KEY_NONCE, info.ssoNonce.c_str()); + authInfo.add(ZT_AUTHINFO_DICT_KEY_STATE, info.ssoState.c_str()); + authInfo.add(ZT_AUTHINFO_DICT_KEY_CLIENT_ID, info.ssoClientID.c_str()); + _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes()); + } + DB::cleanMember(member); + _db.save(member,true); + #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b6.stop(); + #endif + return; + } + } +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b6.stop(); + + auto b7 = _auth_check.Add({{"thread",threadID}}); + auto c7 = _auth_check_count.Add({{"thread",threadID}}); + c7++; + b7.start(); +#endif + if (authorized) { + // Update version info and meta-data if authorized and if this is a genuine request + if (requestPacketId) { + const uint64_t vMajor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0); + const uint64_t vMinor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,0); + const uint64_t vRev = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,0); + const uint64_t vProto = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,0); + + member["vMajor"] = vMajor; + member["vMinor"] = vMinor; + member["vRev"] = vRev; + member["vProto"] = vProto; + + { + std::lock_guard l(_memberStatus_l); + _MemberStatus &ms = _memberStatus[msk]; + ms.authenticationExpiryTime = authenticationExpiryTime; + ms.vMajor = (int)vMajor; + ms.vMinor = (int)vMinor; + ms.vRev = (int)vRev; + ms.vProto = (int)vProto; + ms.lastRequestMetaData = metaData; + ms.identity = identity; + } + + if (authenticationExpiryTime > 0) { + std::lock_guard l(_expiringSoon_l); + _expiringSoon.insert(std::pair(authenticationExpiryTime, msk)); + } + } + } else { + // If they are not authorized, STOP! + DB::cleanMember(member); + _db.save(member,true); + _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); + #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b7.stop(); + #endif + return; + } +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b7.stop(); +#endif + + // ------------------------------------------------------------------------- + // If we made it this far, they are authorized (and authenticated). + // ------------------------------------------------------------------------- + + // Default timeout: 15 minutes. Maximum: two hours. Can be specified by an optional field in the network config + // if something longer than 15 minutes is desired. Minimum is 5 minutes since shorter than that would be flaky. +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + auto b8 = _json_schlep.Add({{"thread",threadID}}); + auto c8 = _json_schlep_count.Add({{"thread", threadID}}); + c8++; + b8.start(); +#endif + int64_t credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_DFL_MAX_DELTA; + if (network.contains("certificateTimeoutWindowSize")) { + credentialtmd = (int64_t)network["certificateTimeoutWindowSize"]; + } + credentialtmd = std::max(std::min(credentialtmd, ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA), ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MIN_MAX_DELTA); + + std::unique_ptr nc(new NetworkConfig()); + + nc->networkId = nwid; + nc->type = OSUtils::jsonBool(network["private"],true) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC; + nc->timestamp = now; + nc->credentialTimeMaxDelta = credentialtmd; + nc->revision = OSUtils::jsonInt(network["revision"],0ULL); + nc->issuedTo = identity.address(); + if (OSUtils::jsonBool(network["enableBroadcast"],true)) nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST; + Utils::scopy(nc->name,sizeof(nc->name),OSUtils::jsonString(network["name"],"").c_str()); + nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU); + nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL); + + nc->ssoEnabled = networkSSOEnabled; //OSUtils::jsonBool(network["ssoEnabled"], false); + nc->ssoVersion = info.version; + + if (info.version == 0) { + nc->authenticationExpiryTime = OSUtils::jsonInt(member["authenticationExpiryTime"], 0LL); + if (!info.authenticationURL.empty()) { + Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), info.authenticationURL.c_str()); + } + } + else if (info.version == 1) { + nc->authenticationExpiryTime = OSUtils::jsonInt(member["authenticationExpiryTime"], 0LL); + if (!info.authenticationURL.empty()) { + Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), info.authenticationURL.c_str()); + } + if (!info.centralAuthURL.empty()) { + Utils::scopy(nc->centralAuthURL, sizeof(nc->centralAuthURL), info.centralAuthURL.c_str()); + } + if (!info.issuerURL.empty()) { + #ifdef ZT_DEBUG + fprintf(stderr, "copying issuerURL to nc: %s\n", info.issuerURL.c_str()); + #endif + Utils::scopy(nc->issuerURL, sizeof(nc->issuerURL), info.issuerURL.c_str()); + } + if (!info.ssoNonce.empty()) { + Utils::scopy(nc->ssoNonce, sizeof(nc->ssoNonce), info.ssoNonce.c_str()); + } + if (!info.ssoState.empty()) { + Utils::scopy(nc->ssoState, sizeof(nc->ssoState), info.ssoState.c_str()); + } + if (!info.ssoClientID.empty()) { + Utils::scopy(nc->ssoClientID, sizeof(nc->ssoClientID), info.ssoClientID.c_str()); + } + } + + std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],"")); + if (rtt.length() == 10) { + nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str())); + nc->remoteTraceLevel = (Trace::Level)OSUtils::jsonInt(member["remoteTraceLevel"],0ULL); + } else { + rtt = OSUtils::jsonString(network["remoteTraceTarget"],""); + if (rtt.length() == 10) { + nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str())); + } else { + nc->remoteTraceTarget.zero(); + } + nc->remoteTraceLevel = (Trace::Level)OSUtils::jsonInt(network["remoteTraceLevel"],0ULL); + } + + for(std::vector
    ::const_iterator ab(ns.activeBridges.begin());ab!=ns.activeBridges.end();++ab) { + nc->addSpecialist(*ab,ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE); + } + + json &v4AssignMode = network["v4AssignMode"]; + json &v6AssignMode = network["v6AssignMode"]; + json &ipAssignmentPools = network["ipAssignmentPools"]; + json &routes = network["routes"]; + json &rules = network["rules"]; + json &capabilities = network["capabilities"]; + json &tags = network["tags"]; + json &memberCapabilities = member["capabilities"]; + json &memberTags = member["tags"]; + json &dns = network["dns"]; + + //fprintf(stderr, "IP Assignment Pools for Network %s: %s\n", nwids, OSUtils::jsonDump(ipAssignmentPools, 2).c_str()); + + if (metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,0) <= 0) { + // Old versions with no rules engine support get an allow everything rule. + // Since rules are enforced bidirectionally, newer versions *will* still + // enforce rules on the inbound side. + nc->ruleCount = 1; + nc->rules[0].t = ZT_NETWORK_RULE_ACTION_ACCEPT; + } else { + if (rules.is_array()) { + for(unsigned long i=0;iruleCount >= ZT_MAX_NETWORK_RULES) + break; + if (_parseRule(rules[i],nc->rules[nc->ruleCount])) + ++nc->ruleCount; + } + } + + std::map< uint64_t,json * > capsById; + if (!memberCapabilities.is_array()) + memberCapabilities = json::array(); + if (capabilities.is_array()) { + for(unsigned long i=0;i::const_iterator ctmp = capsById.find(capId); + if (ctmp != capsById.end()) { + json *cap = ctmp->second; + if ((cap)&&(cap->is_object())&&(!cap->empty())) { + ZT_VirtualNetworkRule capr[ZT_MAX_CAPABILITY_RULES]; + unsigned int caprc = 0; + json &caprj = (*cap)["rules"]; + if ((caprj.is_array())&&(!caprj.empty())) { + for(unsigned long j=0;j= ZT_MAX_CAPABILITY_RULES) + break; + if (_parseRule(caprj[j],capr[caprc])) + ++caprc; + } + } + nc->capabilities[nc->capabilityCount] = Capability((uint32_t)capId,nwid,now,1,capr,caprc); + if (nc->capabilities[nc->capabilityCount].sign(_signingId,identity.address())) + ++nc->capabilityCount; + if (nc->capabilityCount >= ZT_MAX_NETWORK_CAPABILITIES) + break; + } + } + } + + std::map< uint32_t,uint32_t > memberTagsById; + if (memberTags.is_array()) { + for(unsigned long i=0;i::const_iterator t(memberTagsById.begin());t!=memberTagsById.end();++t) { + if (nc->tagCount >= ZT_MAX_NETWORK_TAGS) + break; + nc->tags[nc->tagCount] = Tag(nwid,now,identity.address(),t->first,t->second); + if (nc->tags[nc->tagCount].sign(_signingId)) + ++nc->tagCount; + } + } + + if (routes.is_array()) { + for(unsigned long i=0;irouteCount >= ZT_MAX_NETWORK_ROUTES) + break; + json &route = routes[i]; + json &target = route["target"]; + json &via = route["via"]; + if (target.is_string()) { + const InetAddress t(target.get().c_str()); + InetAddress v; + if (via.is_string()) v.fromString(via.get().c_str()); + if ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) { + ZT_VirtualNetworkRoute *r = &(nc->routes[nc->routeCount]); + *(reinterpret_cast(&(r->target))) = t; + if (v.ss_family == t.ss_family) + *(reinterpret_cast(&(r->via))) = v; + ++nc->routeCount; + } + } + } + } + + const bool noAutoAssignIps = OSUtils::jsonBool(member["noAutoAssignIps"],false); + + if ((v6AssignMode.is_object())&&(!noAutoAssignIps)) { + if ((OSUtils::jsonBool(v6AssignMode["rfc4193"],false))&&(nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) { + nc->staticIps[nc->staticIpCount++] = InetAddress::makeIpv6rfc4193(nwid,identity.address().toInt()); + nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION; + } + if ((OSUtils::jsonBool(v6AssignMode["6plane"],false))&&(nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) { + nc->staticIps[nc->staticIpCount++] = InetAddress::makeIpv66plane(nwid,identity.address().toInt()); + nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION; + } + } + + bool haveManagedIpv4AutoAssignment = false; + bool haveManagedIpv6AutoAssignment = false; // "special" NDP-emulated address types do not count + json ipAssignments = member["ipAssignments"]; // we want to make a copy + if (ipAssignments.is_array()) { + for(unsigned long i=0;irouteCount;++rk) { + if (reinterpret_cast(&(nc->routes[rk].target))->containsAddress(ip)) { + const int nb = (int)(reinterpret_cast(&(nc->routes[rk].target))->netmaskBits()); + if (nb > routedNetmaskBits) + routedNetmaskBits = nb; + } + } + + if (routedNetmaskBits >= 0) { + if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) { + ip.setPort(routedNetmaskBits); + nc->staticIps[nc->staticIpCount++] = ip; + } + if (ip.ss_family == AF_INET) + haveManagedIpv4AutoAssignment = true; + else if (ip.ss_family == AF_INET6) + haveManagedIpv6AutoAssignment = true; + } + } + } + } else { + ipAssignments = json::array(); + } + + if ( (ipAssignmentPools.is_array()) && ((v6AssignMode.is_object())&&(OSUtils::jsonBool(v6AssignMode["zt"],false))) && (!haveManagedIpv6AutoAssignment) && (!noAutoAssignIps) ) { + for(unsigned long p=0;((p s[1])&&((e[1] - s[1]) >= 0xffffffffffULL)) { + // First see if we can just cram a ZeroTier ID into the higher 64 bits. If so do that. + xx[0] = Utils::hton(x[0]); + xx[1] = Utils::hton(x[1] + identity.address().toInt()); + } else { + // Otherwise pick random addresses -- this technically doesn't explore the whole range if the lower 64 bit range is >= 1 but that won't matter since that would be huge anyway + Utils::getSecureRandom((void *)xx,16); + if ((e[0] > s[0])) + xx[0] %= (e[0] - s[0]); + else xx[0] = 0; + if ((e[1] > s[1])) + xx[1] %= (e[1] - s[1]); + else xx[1] = 0; + xx[0] = Utils::hton(x[0] + xx[0]); + xx[1] = Utils::hton(x[1] + xx[1]); + } + + InetAddress ip6((const void *)xx,16,0); + + // Check if this IP is within a local-to-Ethernet routed network + int routedNetmaskBits = 0; + for(unsigned int rk=0;rkrouteCount;++rk) { + if ( (!nc->routes[rk].via.ss_family) && (nc->routes[rk].target.ss_family == AF_INET6) && (reinterpret_cast(&(nc->routes[rk].target))->containsAddress(ip6)) ) + routedNetmaskBits = reinterpret_cast(&(nc->routes[rk].target))->netmaskBits(); + } + + // If it's routed, then try to claim and assign it and if successful end loop + if ( (routedNetmaskBits > 0) && (!std::binary_search(ns.allocatedIps.begin(),ns.allocatedIps.end(),ip6)) ) { + char tmpip[64]; + const std::string ipStr(ip6.toIpString(tmpip)); + if (std::find(ipAssignments.begin(),ipAssignments.end(),ipStr) == ipAssignments.end()) { + ipAssignments.push_back(ipStr); + member["ipAssignments"] = ipAssignments; + ip6.setPort((unsigned int)routedNetmaskBits); + if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) + nc->staticIps[nc->staticIpCount++] = ip6; + haveManagedIpv6AutoAssignment = true; + break; + } + } + } + } + } + } + } + + if ( (ipAssignmentPools.is_array()) && ((v4AssignMode.is_object())&&(OSUtils::jsonBool(v4AssignMode["zt"],false))) && (!haveManagedIpv4AutoAssignment) && (!noAutoAssignIps) ) { + for(unsigned long p=0;((p(&ipRangeStartIA)->sin_addr.s_addr)); + uint32_t ipRangeEnd = Utils::ntoh((uint32_t)(reinterpret_cast(&ipRangeEndIA)->sin_addr.s_addr)); + + if ((ipRangeEnd < ipRangeStart)||(ipRangeStart == 0)) + continue; + uint32_t ipRangeLen = ipRangeEnd - ipRangeStart; + + // Start with the LSB of the member's address + uint32_t ipTrialCounter = (uint32_t)(identity.address().toInt() & 0xffffffff); + + for(uint32_t k=ipRangeStart,trialCount=0;((k<=ipRangeEnd)&&(trialCount < 1000));++k,++trialCount) { + uint32_t ip = (ipRangeLen > 0) ? (ipRangeStart + (ipTrialCounter % ipRangeLen)) : ipRangeStart; + ++ipTrialCounter; + if ((ip & 0x000000ff) == 0x000000ff) { + continue; // don't allow addresses that end in .255 + } + + // Check if this IP is within a local-to-Ethernet routed network + int routedNetmaskBits = -1; + for(unsigned int rk=0;rkrouteCount;++rk) { + if (nc->routes[rk].target.ss_family == AF_INET) { + uint32_t targetIp = Utils::ntoh((uint32_t)(reinterpret_cast(&(nc->routes[rk].target))->sin_addr.s_addr)); + int targetBits = Utils::ntoh((uint16_t)(reinterpret_cast(&(nc->routes[rk].target))->sin_port)); + if ((ip & (0xffffffff << (32 - targetBits))) == targetIp) { + routedNetmaskBits = targetBits; + break; + } + } + } + + // If it's routed, then try to claim and assign it and if successful end loop + const InetAddress ip4(Utils::hton(ip),0); + if ( (routedNetmaskBits > 0) && (!std::binary_search(ns.allocatedIps.begin(),ns.allocatedIps.end(),ip4)) ) { + char tmpip[64]; + const std::string ipStr(ip4.toIpString(tmpip)); + if (std::find(ipAssignments.begin(),ipAssignments.end(),ipStr) == ipAssignments.end()) { + ipAssignments.push_back(ipStr); + member["ipAssignments"] = ipAssignments; + if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) { + struct sockaddr_in *const v4ip = reinterpret_cast(&(nc->staticIps[nc->staticIpCount++])); + v4ip->sin_family = AF_INET; + v4ip->sin_port = Utils::hton((uint16_t)routedNetmaskBits); + v4ip->sin_addr.s_addr = Utils::hton(ip); + } + haveManagedIpv4AutoAssignment = true; + break; + } + } + } + } + } + } + } + + if(dns.is_object()) { + std::string domain = OSUtils::jsonString(dns["domain"],""); + memcpy(nc->dns.domain, domain.c_str(), domain.size()); + json &addrArray = dns["servers"]; + if (addrArray.is_array()) { + for(unsigned int j = 0; j < addrArray.size() && j < ZT_MAX_DNS_SERVERS; ++j) { + json &addr = addrArray[j]; + nc->dns.server_addr[j] = InetAddress(OSUtils::jsonString(addr,"").c_str()); + } + } + } else { + dns = json::object(); + } +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b8.stop(); +#endif + + // Issue a certificate of ownership for all static IPs +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + auto b9 = _issue_certificate.Add({{"thread",threadID}}); + auto c9 = _issue_certificate_count.Add({{"thread",threadID}}); + c9++; + b9.start(); +#endif + if (nc->staticIpCount) { + nc->certificatesOfOwnership[0] = CertificateOfOwnership(nwid,now,identity.address(),1); + for(unsigned int i=0;istaticIpCount;++i) { + nc->certificatesOfOwnership[0].addThing(nc->staticIps[i]); + } + nc->certificatesOfOwnership[0].sign(_signingId); + nc->certificateOfOwnershipCount = 1; + } + + CertificateOfMembership com(now,credentialtmd,nwid,identity); + if (com.sign(_signingId)) { + nc->com = com; + } else { + _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR, nullptr, 0); + #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b9.stop(); + #endif + return; + } +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b9.stop(); + + auto b10 = _save_member.Add({{"thread",threadID}}); + auto c10 = _save_member_count.Add({{"thread",threadID}}); + c10++; + b10.start(); +#endif + DB::cleanMember(member); + _db.save(member,true); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b10.stop(); + + auto b11 = _send_netconf.Add({{"thread",threadID}}); + auto c11 = _send_netconf_count.Add({{"thread",threadID}}); + c11++; + b11.start(); +#endif + _sender->ncSendConfig(nwid,requestPacketId,identity.address(),*(nc.get()),metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + b11.stop(); +#endif +} + +void EmbeddedNetworkController::_startThreads() +{ + std::lock_guard l(_threads_l); + if (!_threads.empty()) { + return; + } + const long hwc = std::max((long)std::thread::hardware_concurrency(),(long)1); + for(long t=0;t::STOP) { + break; + } else if (timedWaitResult == BlockingQueue<_RQEntry *>::OK) { + if (qe) { + try { + _request(qe->nwid,qe->fromAddr,qe->requestPacketId,qe->identity,qe->metaData); + } catch (std::exception &e) { + fprintf(stderr,"ERROR: exception in controller request handling thread: %s" ZT_EOL_S,e.what()); + } catch ( ... ) { + fprintf(stderr,"ERROR: exception in controller request handling thread: unknown exception" ZT_EOL_S); + } + delete qe; + qe = nullptr; + } + } + } + Metrics::network_config_request_threads--; + }); + } +} + +void EmbeddedNetworkController::_ssoExpiryThread() { + while(_ssoExpiryRunning) { + std::vector<_MemberStatusKey> expired; + nlohmann::json network, member; + int64_t now = OSUtils::now(); + { + std::lock_guard l(_expiringSoon_l); + for(auto s=_expiringSoon.begin();s!=_expiringSoon.end();) { + Metrics::sso_expiration_checks++; + const int64_t when = s->first; + if (when <= now) { + // The user may have re-authorized, so we must actually look it up and check. + network.clear(); + member.clear(); + if (_db.get(s->second.networkId, network, s->second.nodeId, member)) { + int64_t authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0); + if (authenticationExpiryTime <= now) { + expired.push_back(s->second); + } + } + s = _expiringSoon.erase(s); + } else { + // Don't bother going further into the future than necessary. + break; + } + } + } + for(auto e=expired.begin();e!=expired.end();++e) { + Metrics::sso_member_deauth++; + onNetworkMemberDeauthorize(nullptr, e->networkId, e->nodeId); + } + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } +} + +} // namespace ZeroTier diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp new file mode 100644 index 0000000..aa3f162 --- /dev/null +++ b/controller/EmbeddedNetworkController.hpp @@ -0,0 +1,183 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#ifndef ZT_SQLITENETWORKCONTROLLER_HPP +#define ZT_SQLITENETWORKCONTROLLER_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../node/Constants.hpp" +#include "../node/NetworkController.hpp" +#include "../node/Utils.hpp" +#include "../node/Address.hpp" +#include "../node/InetAddress.hpp" + +#include "../osdep/OSUtils.hpp" +#include "../osdep/Thread.hpp" +#include "../osdep/BlockingQueue.hpp" + +#include + +#include + +#include "DB.hpp" +#include "DBMirrorSet.hpp" + +namespace ZeroTier { + +class Node; +struct RedisConfig; + +class EmbeddedNetworkController : public NetworkController,public DB::ChangeListener +{ +public: + /** + * @param node Parent node + * @param dbPath Database path (file path or database credentials) + */ + EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, RedisConfig *rc); + virtual ~EmbeddedNetworkController(); + + virtual void init(const Identity &signingId,Sender *sender); + + void setSSORedirectURL(const std::string &url); + + virtual void request( + uint64_t nwid, + const InetAddress &fromAddr, + uint64_t requestPacketId, + const Identity &identity, + const Dictionary &metaData); + + void configureHTTPControlPlane( + httplib::Server &s, + httplib::Server &sV6, + const std::function); + + void handleRemoteTrace(const ZT_RemoteTrace &rt); + + virtual void onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network); + virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member); + virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId); + +private: + void _request(uint64_t nwid,const InetAddress &fromAddr,uint64_t requestPacketId,const Identity &identity,const Dictionary &metaData); + void _startThreads(); + void _ssoExpiryThread(); + + std::string networkUpdateFromPostData(uint64_t networkID, const std::string &body); + + struct _RQEntry + { + uint64_t nwid; + uint64_t requestPacketId; + InetAddress fromAddr; + Identity identity; + Dictionary metaData; + enum { + RQENTRY_TYPE_REQUEST = 0 + } type; + }; + + struct _MemberStatusKey + { + _MemberStatusKey() : networkId(0),nodeId(0) {} + _MemberStatusKey(const uint64_t nwid,const uint64_t nid) : networkId(nwid),nodeId(nid) {} + uint64_t networkId; + uint64_t nodeId; + inline bool operator==(const _MemberStatusKey &k) const { return ((k.networkId == networkId)&&(k.nodeId == nodeId)); } + inline bool operator<(const _MemberStatusKey &k) const { return (k.networkId < networkId) || ((k.networkId == networkId)&&(k.nodeId < nodeId)); } + }; + struct _MemberStatus + { + _MemberStatus() : lastRequestTime(0),authenticationExpiryTime(-1),vMajor(-1),vMinor(-1),vRev(-1),vProto(-1) {} + int64_t lastRequestTime; + int64_t authenticationExpiryTime; + int vMajor,vMinor,vRev,vProto; + Dictionary lastRequestMetaData; + Identity identity; + inline bool online(const int64_t now) const { return ((now - lastRequestTime) < (ZT_NETWORK_AUTOCONF_DELAY * 2)); } + }; + struct _MemberStatusHash + { + inline std::size_t operator()(const _MemberStatusKey &networkIdNodeId) const + { + return (std::size_t)(networkIdNodeId.networkId + networkIdNodeId.nodeId); + } + }; + + const int64_t _startTime; + int _listenPort; + Node *const _node; + std::string _ztPath; + std::string _path; + Identity _signingId; + std::string _signingIdAddressString; + NetworkController::Sender *_sender; + + DBMirrorSet _db; + BlockingQueue< _RQEntry * > _queue; + + std::vector _threads; + std::mutex _threads_l; + + std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus; + std::mutex _memberStatus_l; + + std::set< std::pair > _expiringSoon; + std::mutex _expiringSoon_l; + + RedisConfig *_rc; + std::string _ssoRedirectURL; + + bool _ssoExpiryRunning; + std::thread _ssoExpiry; + +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + prometheus::simpleapi::benchmark_family_t _member_status_lookup; + prometheus::simpleapi::counter_family_t _member_status_lookup_count; + prometheus::simpleapi::benchmark_family_t _node_is_online; + prometheus::simpleapi::counter_family_t _node_is_online_count; + prometheus::simpleapi::benchmark_family_t _get_and_init_member; + prometheus::simpleapi::counter_family_t _get_and_init_member_count; + prometheus::simpleapi::benchmark_family_t _have_identity; + prometheus::simpleapi::counter_family_t _have_identity_count; + prometheus::simpleapi::benchmark_family_t _determine_auth; + prometheus::simpleapi::counter_family_t _determine_auth_count; + prometheus::simpleapi::benchmark_family_t _sso_check; + prometheus::simpleapi::counter_family_t _sso_check_count; + prometheus::simpleapi::benchmark_family_t _auth_check; + prometheus::simpleapi::counter_family_t _auth_check_count; + prometheus::simpleapi::benchmark_family_t _json_schlep; + prometheus::simpleapi::counter_family_t _json_schlep_count; + prometheus::simpleapi::benchmark_family_t _issue_certificate; + prometheus::simpleapi::counter_family_t _issue_certificate_count; + prometheus::simpleapi::benchmark_family_t _save_member; + prometheus::simpleapi::counter_family_t _save_member_count; + prometheus::simpleapi::benchmark_family_t _send_netconf; + prometheus::simpleapi::counter_family_t _send_netconf_count; +#endif +}; + +} // namespace ZeroTier + +#endif diff --git a/controller/FileDB.cpp b/controller/FileDB.cpp new file mode 100644 index 0000000..e410c15 --- /dev/null +++ b/controller/FileDB.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#include "FileDB.hpp" + +#include "../node/Metrics.hpp" + +namespace ZeroTier +{ + +FileDB::FileDB(const char *path) : + DB(), + _path(path), + _networksPath(_path + ZT_PATH_SEPARATOR_S + "network"), + _tracePath(_path + ZT_PATH_SEPARATOR_S + "trace"), + _running(true) +{ + OSUtils::mkdir(_path.c_str()); + OSUtils::lockDownFile(_path.c_str(),true); + OSUtils::mkdir(_networksPath.c_str()); + OSUtils::mkdir(_tracePath.c_str()); + + std::vector networks(OSUtils::listDirectory(_networksPath.c_str(),false)); + std::string buf; + for(auto n=networks.begin();n!=networks.end();++n) { + buf.clear(); + if ((n->length() == 21)&&(OSUtils::readFile((_networksPath + ZT_PATH_SEPARATOR_S + *n).c_str(),buf))) { + try { + nlohmann::json network(OSUtils::jsonParse(buf)); + const std::string nwids = network["id"]; + if (nwids.length() == 16) { + nlohmann::json nullJson; + _networkChanged(nullJson,network,false); + Metrics::network_count++; + std::string membersPath(_networksPath + ZT_PATH_SEPARATOR_S + nwids + ZT_PATH_SEPARATOR_S "member"); + std::vector members(OSUtils::listDirectory(membersPath.c_str(),false)); + for(auto m=members.begin();m!=members.end();++m) { + buf.clear(); + if ((m->length() == 15)&&(OSUtils::readFile((membersPath + ZT_PATH_SEPARATOR_S + *m).c_str(),buf))) { + try { + nlohmann::json member(OSUtils::jsonParse(buf)); + const std::string addrs = member["id"]; + if (addrs.length() == 10) { + nlohmann::json nullJson2; + _memberChanged(nullJson2,member,false); + Metrics::member_count++; + } + } catch ( ... ) {} + } + } + } + } catch ( ... ) {} + } + } +} + +FileDB::~FileDB() +{ + try { + _online_l.lock(); + _running = false; + _online_l.unlock(); + _onlineUpdateThread.join(); + } catch ( ... ) {} +} + +bool FileDB::waitForReady() { return true; } +bool FileDB::isReady() { return true; } + +bool FileDB::save(nlohmann::json &record,bool notifyListeners) +{ + char p1[4096],p2[4096],pb[4096]; + bool modified = false; + try { + const std::string objtype = record["objtype"]; + if (objtype == "network") { + + const uint64_t nwid = OSUtils::jsonIntHex(record["id"],0ULL); + if (nwid) { + nlohmann::json old; + get(nwid,old); + if ((!old.is_object())||(!_compareRecords(old,record))) { + record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; + OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid); + if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) { + fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1); + } + _networkChanged(old,record,notifyListeners); + modified = true; + } + } + + } else if (objtype == "member") { + + const uint64_t id = OSUtils::jsonIntHex(record["id"],0ULL); + const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"],0ULL); + if ((id)&&(nwid)) { + nlohmann::json network,old; + get(nwid,network,id,old); + if ((!old.is_object())||(!_compareRecords(old,record))) { + record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; + OSUtils::ztsnprintf(pb,sizeof(pb),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)nwid); + OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json",pb,(unsigned long long)id); + if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) { + OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)nwid); + OSUtils::mkdir(p2); + OSUtils::mkdir(pb); + if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) { + fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1); + } + } + _memberChanged(old,record,notifyListeners); + modified = true; + } + } + + } + } catch ( ... ) {} // drop invalid records missing fields + return modified; +} + +void FileDB::eraseNetwork(const uint64_t networkId) +{ + nlohmann::json network,nullJson; + get(networkId,network); + char p[16384]; + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),networkId); + OSUtils::rm(p); + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)networkId); + OSUtils::rmDashRf(p); + _networkChanged(network,nullJson,true); + std::lock_guard l(this->_online_l); + this->_online.erase(networkId); +} + +void FileDB::eraseMember(const uint64_t networkId,const uint64_t memberId) +{ + nlohmann::json network,member,nullJson; + get(networkId,network,memberId,member); + char p[4096]; + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member" ZT_PATH_SEPARATOR_S "%.10llx.json",_networksPath.c_str(),networkId,memberId); + OSUtils::rm(p); + _memberChanged(member,nullJson,true); + std::lock_guard l(this->_online_l); + this->_online[networkId].erase(memberId); +} + +void FileDB::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) +{ + char mid[32],atmp[64]; + OSUtils::ztsnprintf(mid,sizeof(mid),"%.10llx",(unsigned long long)memberId); + physicalAddress.toString(atmp); + std::lock_guard l(this->_online_l); + this->_online[networkId][memberId][OSUtils::now()] = physicalAddress; +} + +} // namespace ZeroTier diff --git a/controller/FileDB.hpp b/controller/FileDB.hpp new file mode 100644 index 0000000..4e1bbe0 --- /dev/null +++ b/controller/FileDB.hpp @@ -0,0 +1,47 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#ifndef ZT_CONTROLLER_FILEDB_HPP +#define ZT_CONTROLLER_FILEDB_HPP + +#include "DB.hpp" + +namespace ZeroTier +{ + +class FileDB : public DB +{ +public: + FileDB(const char *path); + virtual ~FileDB(); + + virtual bool waitForReady(); + virtual bool isReady(); + virtual bool save(nlohmann::json &record,bool notifyListeners); + virtual void eraseNetwork(const uint64_t networkId); + virtual void eraseMember(const uint64_t networkId,const uint64_t memberId); + virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress); + +protected: + std::string _path; + std::string _networksPath; + std::string _tracePath; + std::thread _onlineUpdateThread; + std::map< uint64_t,std::map > > _online; + std::mutex _online_l; + bool _running; +}; + +} // namespace ZeroTier + +#endif diff --git a/controller/LFDB.cpp b/controller/LFDB.cpp new file mode 100644 index 0000000..efccff6 --- /dev/null +++ b/controller/LFDB.cpp @@ -0,0 +1,406 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#include "LFDB.hpp" + +#include +#include +#include +#include + +#include "../osdep/OSUtils.hpp" +#include "../ext/cpp-httplib/httplib.h" + +namespace ZeroTier +{ + +LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,const char *lfOwnerPublic,const char *lfNodeHost,int lfNodePort,bool storeOnlineState) : + DB(), + _myId(myId), + _lfOwnerPrivate((lfOwnerPrivate) ? lfOwnerPrivate : ""), + _lfOwnerPublic((lfOwnerPublic) ? lfOwnerPublic : ""), + _lfNodeHost((lfNodeHost) ? lfNodeHost : "127.0.0.1"), + _lfNodePort(((lfNodePort > 0)&&(lfNodePort < 65536)) ? lfNodePort : 9980), + _running(true), + _ready(false), + _storeOnlineState(storeOnlineState) +{ + _syncThread = std::thread([this]() { + char controllerAddress[24]; + const uint64_t controllerAddressInt = _myId.address().toInt(); + _myId.address().toString(controllerAddress); + std::string networksSelectorName("com.zerotier.controller.lfdb:"); networksSelectorName.append(controllerAddress); networksSelectorName.append("/network"); + + // LF record masking key is the first 32 bytes of SHA512(controller private key) in hex, + // hiding record values from anything but the controller or someone who has its key. + uint8_t sha512pk[64]; + _myId.sha512PrivateKey(sha512pk); + char maskingKey [128]; + Utils::hex(sha512pk,32,maskingKey); + + httplib::Client htcli(_lfNodeHost.c_str(),_lfNodePort); + int64_t timeRangeStart = 0; + while (_running.load()) { + { + std::lock_guard sl(_state_l); + for(auto ns=_state.begin();ns!=_state.end();++ns) { + if (ns->second.dirty) { + nlohmann::json network; + if (get(ns->first,network)) { + nlohmann::json newrec,selector0; + selector0["Name"] = networksSelectorName; + selector0["Ordinal"] = ns->first; + newrec["Selectors"].push_back(selector0); + newrec["Value"] = network.dump(); + newrec["OwnerPrivate"] = _lfOwnerPrivate; + newrec["MaskingKey"] = maskingKey; + newrec["PulseIfUnchanged"] = true; + try { + auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json"); + if (resp) { + if (resp->status == 200) { + ns->second.dirty = false; + //printf("SET network %.16llx %s\n",ns->first,resp->body.c_str()); + } else { + fprintf(stderr,"ERROR: LFDB: %d from node (create/update network): %s" ZT_EOL_S,resp->status,resp->body.c_str()); + } + } else { + fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); + } + } catch (std::exception &e) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update network): %s" ZT_EOL_S,e.what()); + } catch ( ... ) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update network): unknown exception" ZT_EOL_S); + } + } + } + + for(auto ms=ns->second.members.begin();ms!=ns->second.members.end();++ms) { + if ((_storeOnlineState)&&(ms->second.lastOnlineDirty)&&(ms->second.lastOnlineAddress)) { + nlohmann::json newrec,selector0,selector1,selectors,ip; + char tmp[1024],tmp2[128]; + OSUtils::ztsnprintf(tmp,sizeof(tmp),"com.zerotier.controller.lfdb:%s/network/%.16llx/online",controllerAddress,(unsigned long long)ns->first); + ms->second.lastOnlineAddress.toIpString(tmp2); + selector0["Name"] = tmp; + selector0["Ordinal"] = ms->first; + selector1["Name"] = tmp2; + selector1["Ordinal"] = 0; + selectors.push_back(selector0); + selectors.push_back(selector1); + newrec["Selectors"] = selectors; + const uint8_t *const rawip = (const uint8_t *)ms->second.lastOnlineAddress.rawIpData(); + switch(ms->second.lastOnlineAddress.ss_family) { + case AF_INET: + for(int j=0;j<4;++j) + ip.push_back((unsigned int)rawip[j]); + break; + case AF_INET6: + for(int j=0;j<16;++j) + ip.push_back((unsigned int)rawip[j]); + break; + default: + ip = tmp2; // should never happen since only IP transport is currently supported + break; + } + newrec["Value"] = ip; + newrec["OwnerPrivate"] = _lfOwnerPrivate; + newrec["MaskingKey"] = maskingKey; + newrec["Timestamp"] = ms->second.lastOnlineTime; + newrec["PulseIfUnchanged"] = true; + try { + auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json"); + if (resp) { + if (resp->status == 200) { + ms->second.lastOnlineDirty = false; + //printf("SET member online %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str()); + } else { + fprintf(stderr,"ERROR: LFDB: %d from node (create/update member online status): %s" ZT_EOL_S,resp->status,resp->body.c_str()); + } + } else { + fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); + } + } catch (std::exception &e) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member online status): %s" ZT_EOL_S,e.what()); + } catch ( ... ) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member online status): unknown exception" ZT_EOL_S); + } + } + + if (ms->second.dirty) { + nlohmann::json network,member; + if (get(ns->first,network,ms->first,member)) { + nlohmann::json newrec,selector0,selector1,selectors; + selector0["Name"] = networksSelectorName; + selector0["Ordinal"] = ns->first; + selector1["Name"] = "member"; + selector1["Ordinal"] = ms->first; + selectors.push_back(selector0); + selectors.push_back(selector1); + newrec["Selectors"] = selectors; + newrec["Value"] = member.dump(); + newrec["OwnerPrivate"] = _lfOwnerPrivate; + newrec["MaskingKey"] = maskingKey; + newrec["PulseIfUnchanged"] = true; + try { + auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json"); + if (resp) { + if (resp->status == 200) { + ms->second.dirty = false; + //printf("SET member %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str()); + } else { + fprintf(stderr,"ERROR: LFDB: %d from node (create/update member): %s" ZT_EOL_S,resp->status,resp->body.c_str()); + } + } else { + fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); + } + } catch (std::exception &e) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member): %s" ZT_EOL_S,e.what()); + } catch ( ... ) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member): unknown exception" ZT_EOL_S); + } + } + } + } + } + } + + try { + std::ostringstream query; + query << + "{" + "\"Ranges\":[{" + "\"Name\":\"" << networksSelectorName << "\"," + "\"Range\":[0,18446744073709551615]" + "}]," + "\"TimeRange\":[" << timeRangeStart << ",9223372036854775807]," + "\"MaskingKey\":\"" << maskingKey << "\"," + "\"Owners\":[\"" << _lfOwnerPublic << "\"]" + "}"; + auto resp = htcli.Post("/query",query.str(),"application/json"); + if (resp) { + if (resp->status == 200) { + nlohmann::json results(OSUtils::jsonParse(resp->body)); + if ((results.is_array())&&(!results.empty())) { + for(std::size_t ri=0;ri> 24) == controllerAddressInt) { // sanity check + + nlohmann::json oldNetwork; + if ((timeRangeStart > 0)&&(get(id,oldNetwork))) { + const uint64_t revision = network["revision"]; + const uint64_t prevRevision = oldNetwork["revision"]; + if (prevRevision < revision) { + _networkChanged(oldNetwork,network,timeRangeStart > 0); + } + } else { + nlohmann::json nullJson; + _networkChanged(nullJson,network,timeRangeStart > 0); + } + + } + } + } + } + + } + } + } + } else { + fprintf(stderr,"ERROR: LFDB: %d from node (check for network updates): %s" ZT_EOL_S,resp->status,resp->body.c_str()); + } + } else { + fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); + } + } catch (std::exception &e) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for network updates): %s" ZT_EOL_S,e.what()); + } catch ( ... ) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for network updates): unknown exception" ZT_EOL_S); + } + + try { + std::ostringstream query; + query << + "{" + "\"Ranges\":[{" + "\"Name\":\"" << networksSelectorName << "\"," + "\"Range\":[0,18446744073709551615]" + "},{" + "\"Name\":\"member\"," + "\"Range\":[0,18446744073709551615]" + "}]," + "\"TimeRange\":[" << timeRangeStart << ",9223372036854775807]," + "\"MaskingKey\":\"" << maskingKey << "\"," + "\"Owners\":[\"" << _lfOwnerPublic << "\"]" + "}"; + auto resp = htcli.Post("/query",query.str(),"application/json"); + if (resp) { + if (resp->status == 200) { + nlohmann::json results(OSUtils::jsonParse(resp->body)); + if ((results.is_array())&&(!results.empty())) { + for(std::size_t ri=0;ri> 24) == controllerAddressInt)) { // sanity check + + nlohmann::json network,oldMember; + if ((timeRangeStart > 0)&&(get(nwid,network,id,oldMember))) { + const uint64_t revision = member["revision"]; + const uint64_t prevRevision = oldMember["revision"]; + if (prevRevision < revision) + _memberChanged(oldMember,member,timeRangeStart > 0); + } else if (hasNetwork(nwid)) { + nlohmann::json nullJson; + _memberChanged(nullJson,member,timeRangeStart > 0); + } + + } + } + } + } + + } + } + } + } else { + fprintf(stderr,"ERROR: LFDB: %d from node (check for member updates): %s" ZT_EOL_S,resp->status,resp->body.c_str()); + } + } else { + fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); + } + } catch (std::exception &e) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for member updates): %s" ZT_EOL_S,e.what()); + } catch ( ... ) { + fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for member updates): unknown exception" ZT_EOL_S); + } + + timeRangeStart = time(nullptr) - 120; // start next query 2m before now to avoid losing updates + _ready.store(true); + + for(int k=0;k<4;++k) { // 2s delay between queries for remotely modified networks or members + if (!_running.load()) + return; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + } + }); +} + +LFDB::~LFDB() +{ + _running.store(false); + _syncThread.join(); +} + +bool LFDB::waitForReady() +{ + while (!_ready.load()) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + return true; +} + +bool LFDB::isReady() +{ + return (_ready.load()); +} + +bool LFDB::save(nlohmann::json &record,bool notifyListeners) +{ + bool modified = false; + const std::string objtype = record["objtype"]; + if (objtype == "network") { + const uint64_t nwid = OSUtils::jsonIntHex(record["id"],0ULL); + if (nwid) { + nlohmann::json old; + get(nwid,old); + if ((!old.is_object())||(!_compareRecords(old,record))) { + record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; + _networkChanged(old,record,notifyListeners); + { + std::lock_guard l(_state_l); + _state[nwid].dirty = true; + } + modified = true; + } + } + } else if (objtype == "member") { + const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"],0ULL); + const uint64_t id = OSUtils::jsonIntHex(record["id"],0ULL); + if ((id)&&(nwid)) { + nlohmann::json network,old; + get(nwid,network,id,old); + if ((!old.is_object())||(!_compareRecords(old,record))) { + record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; + _memberChanged(old,record,notifyListeners); + { + std::lock_guard l(_state_l); + _state[nwid].members[id].dirty = true; + } + modified = true; + } + } + } + return modified; +} + +void LFDB::eraseNetwork(const uint64_t networkId) +{ + // TODO +} + +void LFDB::eraseMember(const uint64_t networkId,const uint64_t memberId) +{ + // TODO +} + +void LFDB::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) +{ + std::lock_guard l(_state_l); + auto nw = _state.find(networkId); + if (nw != _state.end()) { + auto m = nw->second.members.find(memberId); + if (m != nw->second.members.end()) { + m->second.lastOnlineTime = OSUtils::now(); + if (physicalAddress) + m->second.lastOnlineAddress = physicalAddress; + m->second.lastOnlineDirty = true; + } + } +} + +} // namespace ZeroTier diff --git a/controller/LFDB.hpp b/controller/LFDB.hpp new file mode 100644 index 0000000..64933f7 --- /dev/null +++ b/controller/LFDB.hpp @@ -0,0 +1,89 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#ifndef ZT_CONTROLLER_LFDB_HPP +#define ZT_CONTROLLER_LFDB_HPP + +#include "DB.hpp" + +#include +#include +#include +#include + +namespace ZeroTier { + +/** + * DB implementation for controller that stores data in LF + */ +class LFDB : public DB +{ +public: + /** + * @param myId This controller's identity + * @param path Base path for ZeroTier node itself + * @param lfOwnerPrivate LF owner private in PEM format + * @param lfOwnerPublic LF owner public in @base62 format + * @param lfNodeHost LF node host + * @param lfNodePort LF node http (not https) port + * @param storeOnlineState If true, store online/offline state and IP info in LF (a lot of data, only for private networks!) + */ + LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,const char *lfOwnerPublic,const char *lfNodeHost,int lfNodePort,bool storeOnlineState); + virtual ~LFDB(); + + virtual bool waitForReady(); + virtual bool isReady(); + virtual bool save(nlohmann::json &record,bool notifyListeners); + virtual void eraseNetwork(const uint64_t networkId); + virtual void eraseMember(const uint64_t networkId,const uint64_t memberId); + virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress); + +protected: + const Identity _myId; + + std::string _lfOwnerPrivate,_lfOwnerPublic; + std::string _lfNodeHost; + int _lfNodePort; + + struct _MemberState + { + _MemberState() : + lastOnlineAddress(), + lastOnlineTime(0), + dirty(false), + lastOnlineDirty(false) {} + InetAddress lastOnlineAddress; + int64_t lastOnlineTime; + bool dirty; + bool lastOnlineDirty; + }; + struct _NetworkState + { + _NetworkState() : + members(), + dirty(false) {} + std::unordered_map members; + bool dirty; + }; + std::unordered_map _state; + std::mutex _state_l; + + std::atomic_bool _running; + std::atomic_bool _ready; + std::thread _syncThread; + bool _storeOnlineState; +}; + +} // namespace ZeroTier + +#endif diff --git a/controller/PostgreSQL.cpp b/controller/PostgreSQL.cpp new file mode 100644 index 0000000..e4a31ba --- /dev/null +++ b/controller/PostgreSQL.cpp @@ -0,0 +1,1956 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#include "PostgreSQL.hpp" + +#ifdef ZT_CONTROLLER_USE_LIBPQ + +#include "../node/Constants.hpp" +#include "../node/SHA512.hpp" +#include "EmbeddedNetworkController.hpp" +#include "../version.h" +#include "Redis.hpp" + +#include + +#include +#include +#include +#include +#include + + +// #define REDIS_TRACE 1 + +using json = nlohmann::json; + +namespace { + +static const int DB_MINIMUM_VERSION = 38; + +static const char *_timestr() +{ + + time_t t = time(0); + char *ts = ctime(&t); + char *p = ts; + if (!p) + return ""; + while (*p) { + if (*p == '\n') { + *p = (char)0; + break; + } + ++p; + } + return ts; +} + +/* +std::string join(const std::vector &elements, const char * const separator) +{ + switch(elements.size()) { + case 0: + return ""; + case 1: + return elements[0]; + default: + std::ostringstream os; + std::copy(elements.begin(), elements.end()-1, std::ostream_iterator(os, separator)); + os << *elements.rbegin(); + return os.str(); + } +} +*/ + +std::vector split(std::string str, char delim){ + std::istringstream iss(str); + std::vector tokens; + std::string item; + while(std::getline(iss, item, delim)) { + tokens.push_back(item); + } + return tokens; +} + +std::string url_encode(const std::string &value) { + std::ostringstream escaped; + escaped.fill('0'); + escaped << std::hex; + + for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) { + std::string::value_type c = (*i); + + // Keep alphanumeric and other accepted characters intact + if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { + escaped << c; + continue; + } + + // Any other characters are percent-encoded + escaped << std::uppercase; + escaped << '%' << std::setw(2) << int((unsigned char) c); + escaped << std::nouppercase; + } + + return escaped.str(); +} + +} // anonymous namespace + +using namespace ZeroTier; + + +MemberNotificationReceiver::MemberNotificationReceiver(PostgreSQL *p, pqxx::connection &c, const std::string &channel) + : pqxx::notification_receiver(c, channel) + , _psql(p) +{ + fprintf(stderr, "initialize MemberNotificationReceiver\n"); +} + + +void MemberNotificationReceiver::operator() (const std::string &payload, int packend_pid) { + fprintf(stderr, "Member Notification received: %s\n", payload.c_str()); + Metrics::pgsql_mem_notification++; + json tmp(json::parse(payload)); + json &ov = tmp["old_val"]; + json &nv = tmp["new_val"]; + json oldConfig, newConfig; + if (ov.is_object()) oldConfig = ov; + if (nv.is_object()) newConfig = nv; + if (oldConfig.is_object() || newConfig.is_object()) { + _psql->_memberChanged(oldConfig,newConfig,(_psql->_ready>=2)); + fprintf(stderr, "payload sent\n"); + } +} + + +NetworkNotificationReceiver::NetworkNotificationReceiver(PostgreSQL *p, pqxx::connection &c, const std::string &channel) + : pqxx::notification_receiver(c, channel) + , _psql(p) +{ + fprintf(stderr, "initialize NetworkNotificationReceiver\n"); +} + +void NetworkNotificationReceiver::operator() (const std::string &payload, int packend_pid) { + fprintf(stderr, "Network Notification received: %s\n", payload.c_str()); + Metrics::pgsql_net_notification++; + json tmp(json::parse(payload)); + json &ov = tmp["old_val"]; + json &nv = tmp["new_val"]; + json oldConfig, newConfig; + if (ov.is_object()) oldConfig = ov; + if (nv.is_object()) newConfig = nv; + if (oldConfig.is_object() || newConfig.is_object()) { + _psql->_networkChanged(oldConfig,newConfig,(_psql->_ready>=2)); + fprintf(stderr, "payload sent\n"); + } +} + +using Attrs = std::vector>; +using Item = std::pair; +using ItemStream = std::vector; + + + +PostgreSQL::PostgreSQL(const Identity &myId, const char *path, int listenPort, RedisConfig *rc) + : DB() + , _pool() + , _myId(myId) + , _myAddress(myId.address()) + , _ready(0) + , _connected(1) + , _run(1) + , _waitNoticePrinted(false) + , _listenPort(listenPort) + , _rc(rc) + , _redis(NULL) + , _cluster(NULL) + , _redisMemberStatus(false) + , _smee(NULL) +{ + char myAddress[64]; + _myAddressStr = myId.address().toString(myAddress); + _connString = std::string(path); + auto f = std::make_shared(_connString); + _pool = std::make_shared >( + 15, 5, std::static_pointer_cast(f)); + + memset(_ssoPsk, 0, sizeof(_ssoPsk)); + char *const ssoPskHex = getenv("ZT_SSO_PSK"); +#ifdef ZT_TRACE + fprintf(stderr, "ZT_SSO_PSK: %s\n", ssoPskHex); +#endif + if (ssoPskHex) { + // SECURITY: note that ssoPskHex will always be null-terminated if libc actually + // returns something non-NULL. If the hex encodes something shorter than 48 bytes, + // it will be padded at the end with zeroes. If longer, it'll be truncated. + Utils::unhex(ssoPskHex, _ssoPsk, sizeof(_ssoPsk)); + } + const char *redisMemberStatus = getenv("ZT_REDIS_MEMBER_STATUS"); + if (redisMemberStatus && (strcmp(redisMemberStatus, "true") == 0)) { + _redisMemberStatus = true; + fprintf(stderr, "Using redis for member status\n"); + } + + auto c = _pool->borrow(); + pqxx::work txn{*c->c}; + + pqxx::row r{txn.exec1("SELECT version FROM ztc_database")}; + int dbVersion = r[0].as(); + txn.commit(); + + if (dbVersion < DB_MINIMUM_VERSION) { + fprintf(stderr, "Central database schema version too low. This controller version requires a minimum schema version of %d. Please upgrade your Central instance", DB_MINIMUM_VERSION); + exit(1); + } + _pool->unborrow(c); + + if (_rc != NULL) { + sw::redis::ConnectionOptions opts; + sw::redis::ConnectionPoolOptions poolOpts; + opts.host = _rc->hostname; + opts.port = _rc->port; + opts.password = _rc->password; + opts.db = 0; + opts.keep_alive = true; + opts.connect_timeout = std::chrono::seconds(3); + poolOpts.size = 25; + poolOpts.wait_timeout = std::chrono::seconds(5); + poolOpts.connection_lifetime = std::chrono::minutes(3); + poolOpts.connection_idle_time = std::chrono::minutes(1); + if (_rc->clusterMode) { + fprintf(stderr, "Using Redis in Cluster Mode\n"); + _cluster = std::make_shared(opts, poolOpts); + } else { + fprintf(stderr, "Using Redis in Standalone Mode\n"); + _redis = std::make_shared(opts, poolOpts); + } + } + + _readyLock.lock(); + + fprintf(stderr, "[%s] NOTICE: %.10llx controller PostgreSQL waiting for initial data download..." ZT_EOL_S, ::_timestr(), (unsigned long long)_myAddress.toInt()); + _waitNoticePrinted = true; + + initializeNetworks(); + initializeMembers(); + + _heartbeatThread = std::thread(&PostgreSQL::heartbeat, this); + _membersDbWatcher = std::thread(&PostgreSQL::membersDbWatcher, this); + _networksDbWatcher = std::thread(&PostgreSQL::networksDbWatcher, this); + for (int i = 0; i < ZT_CENTRAL_CONTROLLER_COMMIT_THREADS; ++i) { + _commitThread[i] = std::thread(&PostgreSQL::commitThread, this); + } + _onlineNotificationThread = std::thread(&PostgreSQL::onlineNotificationThread, this); + + configureSmee(); +} + +PostgreSQL::~PostgreSQL() +{ + if (_smee != NULL) { + smeeclient::smee_client_delete(_smee); + _smee = NULL; + } + + _run = 0; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + _heartbeatThread.join(); + _membersDbWatcher.join(); + _networksDbWatcher.join(); + _commitQueue.stop(); + for (int i = 0; i < ZT_CENTRAL_CONTROLLER_COMMIT_THREADS; ++i) { + _commitThread[i].join(); + } + _onlineNotificationThread.join(); +} + +void PostgreSQL::configureSmee() +{ + const char *TEMPORAL_SCHEME = "ZT_TEMPORAL_SCHEME"; + const char *TEMPORAL_HOST = "ZT_TEMPORAL_HOST"; + const char *TEMPORAL_PORT = "ZT_TEMPORAL_PORT"; + const char *TEMPORAL_NAMESPACE = "ZT_TEMPORAL_NAMESPACE"; + const char *SMEE_TASK_QUEUE = "ZT_SMEE_TASK_QUEUE"; + + const char *scheme = getenv(TEMPORAL_SCHEME); + if (scheme == NULL) { + scheme = "http"; + } + const char *host = getenv(TEMPORAL_HOST); + const char *port = getenv(TEMPORAL_PORT); + const char *ns = getenv(TEMPORAL_NAMESPACE); + const char *task_queue = getenv(SMEE_TASK_QUEUE); + + if (scheme != NULL && host != NULL && port != NULL && ns != NULL && task_queue != NULL) { + fprintf(stderr, "creating smee client\n"); + std::string hostPort = std::string(scheme) + std::string("://") + std::string(host) + std::string(":") + std::string(port); + this->_smee = smeeclient::smee_client_new(hostPort.c_str(), ns, task_queue); + } else { + fprintf(stderr, "Smee client not configured\n"); + } +} + +bool PostgreSQL::waitForReady() +{ + while (_ready < 2) { + _readyLock.lock(); + _readyLock.unlock(); + } + return true; +} + +bool PostgreSQL::isReady() +{ + return ((_ready == 2)&&(_connected)); +} + +bool PostgreSQL::save(nlohmann::json &record,bool notifyListeners) +{ + bool modified = false; + try { + if (!record.is_object()) { + fprintf(stderr, "record is not an object?!?\n"); + return false; + } + const std::string objtype = record["objtype"]; + if (objtype == "network") { + //fprintf(stderr, "network save\n"); + const uint64_t nwid = OSUtils::jsonIntHex(record["id"],0ULL); + if (nwid) { + nlohmann::json old; + get(nwid,old); + if ((!old.is_object())||(!_compareRecords(old,record))) { + record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; + _commitQueue.post(std::pair(record,notifyListeners)); + modified = true; + } + } + } else if (objtype == "member") { + std::string networkId = record["nwid"]; + std::string memberId = record["id"]; + const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"],0ULL); + const uint64_t id = OSUtils::jsonIntHex(record["id"],0ULL); + //fprintf(stderr, "member save %s-%s\n", networkId.c_str(), memberId.c_str()); + if ((id)&&(nwid)) { + nlohmann::json network,old; + get(nwid,network,id,old); + if ((!old.is_object())||(!_compareRecords(old,record))) { + //fprintf(stderr, "commit queue post\n"); + record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; + _commitQueue.post(std::pair(record,notifyListeners)); + modified = true; + } else { + //fprintf(stderr, "no change\n"); + } + } + } else { + fprintf(stderr, "uhh waaat\n"); + } + } catch (std::exception &e) { + fprintf(stderr, "Error on PostgreSQL::save: %s\n", e.what()); + } catch (...) { + fprintf(stderr, "Unknown error on PostgreSQL::save\n"); + } + return modified; +} + +void PostgreSQL::eraseNetwork(const uint64_t networkId) +{ + fprintf(stderr, "PostgreSQL::eraseNetwork\n"); + char tmp2[24]; + waitForReady(); + Utils::hex(networkId, tmp2); + std::pair tmp; + tmp.first["id"] = tmp2; + tmp.first["objtype"] = "_delete_network"; + tmp.second = true; + _commitQueue.post(tmp); + nlohmann::json nullJson; + _networkChanged(tmp.first, nullJson, true); +} + +void PostgreSQL::eraseMember(const uint64_t networkId, const uint64_t memberId) +{ + fprintf(stderr, "PostgreSQL::eraseMember\n"); + char tmp2[24]; + waitForReady(); + std::pair tmp, nw; + Utils::hex(networkId, tmp2); + tmp.first["nwid"] = tmp2; + Utils::hex(memberId, tmp2); + tmp.first["id"] = tmp2; + tmp.first["objtype"] = "_delete_member"; + tmp.second = true; + _commitQueue.post(tmp); + nlohmann::json nullJson; + _memberChanged(tmp.first, nullJson, true); +} + +void PostgreSQL::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress) +{ + std::lock_guard l(_lastOnline_l); + std::pair &i = _lastOnline[std::pair(networkId, memberId)]; + i.first = OSUtils::now(); + if (physicalAddress) { + i.second = physicalAddress; + } +} + +AuthInfo PostgreSQL::getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL) +{ + Metrics::db_get_sso_info++; + // NONCE is just a random character string. no semantic meaning + // state = HMAC SHA384 of Nonce based on shared sso key + // + // need nonce timeout in database? make sure it's used within X time + // X is 5 minutes for now. Make configurable later? + // + // how do we tell when a nonce is used? if auth_expiration_time is set + std::string networkId = member["nwid"]; + std::string memberId = member["id"]; + + + char authenticationURL[4096] = {0}; + AuthInfo info; + info.enabled = true; + + //if (memberId == "a10dccea52" && networkId == "8056c2e21c24673d") { + // fprintf(stderr, "invalid authinfo for grant's machine\n"); + // info.version=1; + // return info; + //} + // fprintf(stderr, "PostgreSQL::updateMemberOnLoad: %s-%s\n", networkId.c_str(), memberId.c_str()); + std::shared_ptr c; + try { + c = _pool->borrow(); + pqxx::work w(*c->c); + + char nonceBytes[16] = {0}; + std::string nonce = ""; + + // check if the member exists first. + pqxx::row count = w.exec_params1("SELECT count(id) FROM ztc_member WHERE id = $1 AND network_id = $2 AND deleted = false", memberId, networkId); + if (count[0].as() == 1) { + // get active nonce, if exists. + pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry " + "WHERE network_id = $1 AND member_id = $2 " + "AND ((NOW() AT TIME ZONE 'UTC') <= authentication_expiry_time) AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiration)", + networkId, memberId); + + if (r.size() == 0) { + // no active nonce. + // find an unused nonce, if one exists. + pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry " + "WHERE network_id = $1 AND member_id = $2 " + "AND authentication_expiry_time IS NULL AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiration)", + networkId, memberId); + + if (r.size() == 1) { + // we have an existing nonce. Use it + nonce = r.at(0)[0].as(); + Utils::unhex(nonce.c_str(), nonceBytes, sizeof(nonceBytes)); + } else if (r.empty()) { + // create a nonce + Utils::getSecureRandom(nonceBytes, 16); + char nonceBuf[64] = {0}; + Utils::hex(nonceBytes, sizeof(nonceBytes), nonceBuf); + nonce = std::string(nonceBuf); + + pqxx::result ir = w.exec_params0("INSERT INTO ztc_sso_expiry " + "(nonce, nonce_expiration, network_id, member_id) VALUES " + "($1, TO_TIMESTAMP($2::double precision/1000), $3, $4)", + nonce, OSUtils::now() + 300000, networkId, memberId); + + w.commit(); + } else { + // > 1 ?!? Thats an error! + fprintf(stderr, "> 1 unused nonce!\n"); + exit(6); + } + } else if (r.size() == 1) { + nonce = r.at(0)[0].as(); + Utils::unhex(nonce.c_str(), nonceBytes, sizeof(nonceBytes)); + } else { + // more than 1 nonce in use? Uhhh... + fprintf(stderr, "> 1 nonce in use for network member?!?\n"); + exit(7); + } + + r = w.exec_params( + "SELECT oc.client_id, oc.authorization_endpoint, oc.issuer, oc.provider, oc.sso_impl_version " + "FROM ztc_network AS n " + "INNER JOIN ztc_org o " + " ON o.owner_id = n.owner_id " + "LEFT OUTER JOIN ztc_network_oidc_config noc " + " ON noc.network_id = n.id " + "LEFT OUTER JOIN ztc_oidc_config oc " + " ON noc.client_id = oc.client_id AND oc.org_id = o.org_id " + "WHERE n.id = $1 AND n.sso_enabled = true", networkId); + + std::string client_id = ""; + std::string authorization_endpoint = ""; + std::string issuer = ""; + std::string provider = ""; + uint64_t sso_version = 0; + + if (r.size() == 1) { + client_id = r.at(0)[0].as>().value_or(""); + authorization_endpoint = r.at(0)[1].as>().value_or(""); + issuer = r.at(0)[2].as>().value_or(""); + provider = r.at(0)[3].as>().value_or(""); + sso_version = r.at(0)[4].as>().value_or(1); + } else if (r.size() > 1) { + fprintf(stderr, "ERROR: More than one auth endpoint for an organization?!?!? NetworkID: %s\n", networkId.c_str()); + } else { + fprintf(stderr, "No client or auth endpoint?!?\n"); + } + + info.version = sso_version; + + // no catch all else because we don't actually care if no records exist here. just continue as normal. + if ((!client_id.empty())&&(!authorization_endpoint.empty())) { + + uint8_t state[48]; + HMACSHA384(_ssoPsk, nonceBytes, sizeof(nonceBytes), state); + char state_hex[256]; + Utils::hex(state, 48, state_hex); + + if (info.version == 0) { + char url[2048] = {0}; + OSUtils::ztsnprintf(url, sizeof(authenticationURL), + "%s?response_type=id_token&response_mode=form_post&scope=openid+email+profile&redirect_uri=%s&nonce=%s&state=%s&client_id=%s", + authorization_endpoint.c_str(), + url_encode(redirectURL).c_str(), + nonce.c_str(), + state_hex, + client_id.c_str()); + info.authenticationURL = std::string(url); + } else if (info.version == 1) { + info.ssoClientID = client_id; + info.issuerURL = issuer; + info.ssoProvider = provider; + info.ssoNonce = nonce; + info.ssoState = std::string(state_hex) + "_" +networkId; + info.centralAuthURL = redirectURL; +#ifdef ZT_DEBUG + fprintf( + stderr, + "ssoClientID: %s\nissuerURL: %s\nssoNonce: %s\nssoState: %s\ncentralAuthURL: %s\nprovider: %s\n", + info.ssoClientID.c_str(), + info.issuerURL.c_str(), + info.ssoNonce.c_str(), + info.ssoState.c_str(), + info.centralAuthURL.c_str(), + provider.c_str()); +#endif + } + } else { + fprintf(stderr, "client_id: %s\nauthorization_endpoint: %s\n", client_id.c_str(), authorization_endpoint.c_str()); + } + } + + _pool->unborrow(c); + } catch (std::exception &e) { + fprintf(stderr, "ERROR: Error updating member on load for network %s: %s\n", networkId.c_str(), e.what()); + } + + return info; //std::string(authenticationURL); +} + +void PostgreSQL::initializeNetworks() +{ + try { + std::string setKey = "networks:{" + _myAddressStr + "}"; + + fprintf(stderr, "Initializing Networks...\n"); + + if (_redisMemberStatus) { + fprintf(stderr, "Init Redis for networks...\n"); + try { + if (_rc->clusterMode) { + _cluster->del(setKey); + } else { + _redis->del(setKey); + } + } catch (sw::redis::Error &e) { + // ignore. if this key doesn't exist, there's no reason to delete it + } + } + + std::unordered_set networkSet; + + char qbuf[2048] = {0}; + sprintf(qbuf, + "SELECT n.id, (EXTRACT(EPOCH FROM n.creation_time AT TIME ZONE 'UTC')*1000)::bigint as creation_time, n.capabilities, " + "n.enable_broadcast, (EXTRACT(EPOCH FROM n.last_modified AT TIME ZONE 'UTC')*1000)::bigint AS last_modified, n.mtu, n.multicast_limit, n.name, n.private, n.remote_trace_level, " + "n.remote_trace_target, n.revision, n.rules, n.tags, n.v4_assign_mode, n.v6_assign_mode, n.sso_enabled, (CASE WHEN n.sso_enabled THEN noc.client_id ELSE NULL END) as client_id, " + "(CASE WHEN n.sso_enabled THEN oc.authorization_endpoint ELSE NULL END) as authorization_endpoint, " + "(CASE WHEN n.sso_enabled THEN oc.provider ELSE NULL END) as provider, d.domain, d.servers, " + "ARRAY(SELECT CONCAT(host(ip_range_start),'|', host(ip_range_end)) FROM ztc_network_assignment_pool WHERE network_id = n.id) AS assignment_pool, " + "ARRAY(SELECT CONCAT(host(address),'/',bits::text,'|',COALESCE(host(via), 'NULL'))FROM ztc_network_route WHERE network_id = n.id) AS routes " + "FROM ztc_network n " + "LEFT OUTER JOIN ztc_org o " + " ON o.owner_id = n.owner_id " + "LEFT OUTER JOIN ztc_network_oidc_config noc " + " ON noc.network_id = n.id " + "LEFT OUTER JOIN ztc_oidc_config oc " + " ON noc.client_id = oc.client_id AND oc.org_id = o.org_id " + "LEFT OUTER JOIN ztc_network_dns d " + " ON d.network_id = n.id " + "WHERE deleted = false AND controller_id = '%s'", _myAddressStr.c_str()); + auto c = _pool->borrow(); + auto c2 = _pool->borrow(); + pqxx::work w{*c->c}; + + fprintf(stderr, "Load networks from psql...\n"); + auto stream = pqxx::stream_from::query(w, qbuf); + + std::tuple< + std::string // network ID + , std::optional // creationTime + , std::optional // capabilities + , std::optional // enableBroadcast + , std::optional // lastModified + , std::optional // mtu + , std::optional // multicastLimit + , std::optional // name + , bool // private + , std::optional // remoteTraceLevel + , std::optional // remoteTraceTarget + , std::optional // revision + , std::optional // rules + , std::optional // tags + , std::optional // v4AssignMode + , std::optional // v6AssignMode + , std::optional // ssoEnabled + , std::optional // clientId + , std::optional // authorizationEndpoint + , std::optional // ssoProvider + , std::optional // domain + , std::optional // servers + , std::string // assignmentPoolString + , std::string // routeString + > row; + + uint64_t count = 0; + auto tmp = std::chrono::high_resolution_clock::now(); + uint64_t total = 0; + while (stream >> row) { + auto start = std::chrono::high_resolution_clock::now(); + + json empty; + json config; + + initNetwork(config); + + std::string nwid = std::get<0>(row); + std::optional creationTime = std::get<1>(row); + std::optional capabilities = std::get<2>(row); + std::optional enableBroadcast = std::get<3>(row); + std::optional lastModified = std::get<4>(row); + std::optional mtu = std::get<5>(row); + std::optional multicastLimit = std::get<6>(row); + std::optional name = std::get<7>(row); + bool isPrivate = std::get<8>(row); + std::optional remoteTraceLevel = std::get<9>(row); + std::optional remoteTraceTarget = std::get<10>(row); + std::optional revision = std::get<11>(row); + std::optional rules = std::get<12>(row); + std::optional tags = std::get<13>(row); + std::optional v4AssignMode = std::get<14>(row); + std::optional v6AssignMode = std::get<15>(row); + std::optional ssoEnabled = std::get<16>(row); + std::optional clientId = std::get<17>(row); + std::optional authorizationEndpoint = std::get<18>(row); + std::optional ssoProvider = std::get<19>(row); + std::optional dnsDomain = std::get<20>(row); + std::optional dnsServers = std::get<21>(row); + std::string assignmentPoolString = std::get<22>(row); + std::string routesString = std::get<23>(row); + + config["id"] = nwid; + config["nwid"] = nwid; + config["creationTime"] = creationTime.value_or(0); + config["capabilities"] = json::parse(capabilities.value_or("[]")); + config["enableBroadcast"] = enableBroadcast.value_or(false); + config["lastModified"] = lastModified.value_or(0); + config["mtu"] = mtu.value_or(2800); + config["multicastLimit"] = multicastLimit.value_or(64); + config["name"] = name.value_or(""); + config["private"] = isPrivate; + config["remoteTraceLevel"] = remoteTraceLevel.value_or(0); + config["remoteTraceTarget"] = remoteTraceTarget.value_or(""); + config["revision"] = revision.value_or(0); + config["rules"] = json::parse(rules.value_or("[]")); + config["tags"] = json::parse(tags.value_or("[]")); + config["v4AssignMode"] = json::parse(v4AssignMode.value_or("{}")); + config["v6AssignMode"] = json::parse(v6AssignMode.value_or("{}")); + config["ssoEnabled"] = ssoEnabled.value_or(false); + config["objtype"] = "network"; + config["ipAssignmentPools"] = json::array(); + config["routes"] = json::array(); + config["clientId"] = clientId.value_or(""); + config["authorizationEndpoint"] = authorizationEndpoint.value_or(""); + config["provider"] = ssoProvider.value_or(""); + + networkSet.insert(nwid); + + if (dnsDomain.has_value()) { + std::string serverList = dnsServers.value(); + json obj; + auto servers = json::array(); + if (serverList.rfind("{",0) != std::string::npos) { + serverList = serverList.substr(1, serverList.size()-2); + std::stringstream ss(serverList); + while(ss.good()) { + std::string server; + std::getline(ss, server, ','); + servers.push_back(server); + } + } + obj["domain"] = dnsDomain.value(); + obj["servers"] = servers; + config["dns"] = obj; + } + + config["ipAssignmentPools"] = json::array(); + if (assignmentPoolString != "{}") { + std::string tmp = assignmentPoolString.substr(1, assignmentPoolString.size()-2); + std::vector assignmentPools = split(tmp, ','); + for (auto it = assignmentPools.begin(); it != assignmentPools.end(); ++it) { + std::vector r = split(*it, '|'); + json ip; + ip["ipRangeStart"] = r[0]; + ip["ipRangeEnd"] = r[1]; + config["ipAssignmentPools"].push_back(ip); + } + } + + config["routes"] = json::array(); + if (routesString != "{}") { + std::string tmp = routesString.substr(1, routesString.size()-2); + std::vector routes = split(tmp, ','); + for (auto it = routes.begin(); it != routes.end(); ++it) { + std::vector r = split(*it, '|'); + json route; + route["target"] = r[0]; + route["via"] = ((route["via"] == "NULL")? nullptr : r[1]); + config["routes"].push_back(route); + } + } + + Metrics::network_count++; + + _networkChanged(empty, config, false); + + auto end = std::chrono::high_resolution_clock::now(); + auto dur = std::chrono::duration_cast(end - start);; + total += dur.count(); + ++count; + if (count > 0 && count % 10000 == 0) { + fprintf(stderr, "Averaging %llu us per network\n", (total/count)); + } + } + + if (count > 0) { + fprintf(stderr, "Took %llu us per network to load\n", (total/count)); + } + stream.complete(); + + w.commit(); + _pool->unborrow(c2); + _pool->unborrow(c); + fprintf(stderr, "done.\n"); + + if (!networkSet.empty()) { + if (_redisMemberStatus) { + fprintf(stderr, "adding networks to redis...\n"); + if (_rc->clusterMode) { + auto tx = _cluster->transaction(_myAddressStr, true, false); + uint64_t count = 0; + for (std::string nwid : networkSet) { + tx.sadd(setKey, nwid); + if (++count % 30000 == 0) { + tx.exec(); + tx = _cluster->transaction(_myAddressStr, true, false); + } + } + tx.exec(); + } else { + auto tx = _redis->transaction(true, false); + uint64_t count = 0; + for (std::string nwid : networkSet) { + tx.sadd(setKey, nwid); + if (++count % 30000 == 0) { + tx.exec(); + tx = _redis->transaction(true, false); + } + } + tx.exec(); + } + fprintf(stderr, "done.\n"); + } + } + + if (++this->_ready == 2) { + if (_waitNoticePrinted) { + fprintf(stderr,"[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S,_timestr(),(unsigned long long)_myAddress.toInt()); + } + _readyLock.unlock(); + } + fprintf(stderr, "network init done.\n"); + } catch (sw::redis::Error &e) { + fprintf(stderr, "ERROR: Error initializing networks in Redis: %s\n", e.what()); + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + exit(-1); + } catch (std::exception &e) { + fprintf(stderr, "ERROR: Error initializing networks: %s\n", e.what()); + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + exit(-1); + } +} + +void PostgreSQL::initializeMembers() +{ + std::string memberId; + std::string networkId; + try { + std::unordered_map networkMembers; + fprintf(stderr, "Initializing Members...\n"); + + std::string setKeyBase = "network-nodes-all:{" + _myAddressStr + "}:"; + + if (_redisMemberStatus) { + fprintf(stderr, "Initialize Redis for members...\n"); + std::unique_lock l(_networks_l); + std::unordered_set deletes; + for ( auto it : _networks) { + uint64_t nwid_i = it.first; + char nwidTmp[64] = {0}; + OSUtils::ztsnprintf(nwidTmp, sizeof(nwidTmp), "%.16llx", nwid_i); + std::string nwid(nwidTmp); + std::string key = setKeyBase + nwid; + deletes.insert(key); + } + + if (!deletes.empty()) { + try { + if (_rc->clusterMode) { + auto tx = _cluster->transaction(_myAddressStr, true, false); + for (std::string k : deletes) { + tx.del(k); + } + tx.exec(); + } else { + auto tx = _redis->transaction(true, false); + for (std::string k : deletes) { + tx.del(k); + } + tx.exec(); + } + } catch (sw::redis::Error &e) { + // ignore + } + } + } + + char qbuf[2048]; + sprintf(qbuf, + "SELECT m.id, m.network_id, m.active_bridge, m.authorized, m.capabilities, " + "(EXTRACT(EPOCH FROM m.creation_time AT TIME ZONE 'UTC')*1000)::bigint, m.identity, " + "(EXTRACT(EPOCH FROM m.last_authorized_time AT TIME ZONE 'UTC')*1000)::bigint, " + "(EXTRACT(EPOCH FROM m.last_deauthorized_time AT TIME ZONE 'UTC')*1000)::bigint, " + "m.remote_trace_level, m.remote_trace_target, m.tags, m.v_major, m.v_minor, m.v_rev, m.v_proto, " + "m.no_auto_assign_ips, m.revision, m.sso_exempt, " + "(CASE WHEN n.sso_enabled = TRUE AND m.sso_exempt = FALSE THEN " + " ( " + " SELECT (EXTRACT(EPOCH FROM e.authentication_expiry_time)*1000)::bigint " + " FROM ztc_sso_expiry e " + " INNER JOIN ztc_network n1 " + " ON n1.id = e.network_id AND n1.deleted = TRUE " + " WHERE e.network_id = m.network_id AND e.member_id = m.id AND n.sso_enabled = TRUE AND e.authentication_expiry_time IS NOT NULL " + " ORDER BY e.authentication_expiry_time DESC LIMIT 1 " + " ) " + " ELSE NULL " + " END) AS authentication_expiry_time, " + "ARRAY(SELECT DISTINCT address FROM ztc_member_ip_assignment WHERE member_id = m.id AND network_id = m.network_id) AS assigned_addresses " + "FROM ztc_member m " + "INNER JOIN ztc_network n " + " ON n.id = m.network_id " + "WHERE n.controller_id = '%s' AND n.deleted = FALSE AND m.deleted = FALSE", _myAddressStr.c_str()); + auto c = _pool->borrow(); + auto c2 = _pool->borrow(); + pqxx::work w{*c->c}; + + fprintf(stderr, "Load members from psql...\n"); + auto stream = pqxx::stream_from::query(w, qbuf); + + std::tuple< + std::string // memberId + , std::string // memberId + , std::optional // activeBridge + , std::optional // authorized + , std::optional // capabilities + , std::optional // creationTime + , std::optional // identity + , std::optional // lastAuthorizedTime + , std::optional // lastDeauthorizedTime + , std::optional // remoteTraceLevel + , std::optional // remoteTraceTarget + , std::optional // tags + , std::optional // vMajor + , std::optional // vMinor + , std::optional // vRev + , std::optional // vProto + , std::optional // noAutoAssignIps + , std::optional // revision + , std::optional // ssoExempt + , std::optional // authenticationExpiryTime + , std::string // assignedAddresses + > row; + + uint64_t count = 0; + auto tmp = std::chrono::high_resolution_clock::now(); + uint64_t total = 0; + while (stream >> row) { + auto start = std::chrono::high_resolution_clock::now(); + json empty; + json config; + + initMember(config); + + memberId = std::get<0>(row); + networkId = std::get<1>(row); + std::optional activeBridge = std::get<2>(row); + std::optional authorized = std::get<3>(row); + std::optional capabilities = std::get<4>(row); + std::optional creationTime = std::get<5>(row); + std::optional identity = std::get<6>(row); + std::optional lastAuthorizedTime = std::get<7>(row); + std::optional lastDeauthorizedTime = std::get<8>(row); + std::optional remoteTraceLevel = std::get<9>(row); + std::optional remoteTraceTarget = std::get<10>(row); + std::optional tags = std::get<11>(row); + std::optional vMajor = std::get<12>(row); + std::optional vMinor = std::get<13>(row); + std::optional vRev = std::get<14>(row); + std::optional vProto = std::get<15>(row); + std::optional noAutoAssignIps = std::get<16>(row); + std::optional revision = std::get<17>(row); + std::optional ssoExempt = std::get<18>(row); + std::optional authenticationExpiryTime = std::get<19>(row); + std::string assignedAddresses = std::get<20>(row); + + networkMembers.insert(std::pair(setKeyBase+networkId, memberId)); + + config["id"] = memberId; + config["address"] = memberId; + config["nwid"] = networkId; + config["activeBridge"] = activeBridge.value_or(false); + config["authorized"] = authorized.value_or(false); + config["capabilities"] = json::parse(capabilities.value_or("[]")); + config["creationTime"] = creationTime.value_or(0); + config["identity"] = identity.value_or(""); + config["lastAuthorizedTime"] = lastAuthorizedTime.value_or(0); + config["lastDeauthorizedTime"] = lastDeauthorizedTime.value_or(0); + config["remoteTraceLevel"] = remoteTraceLevel.value_or(0); + config["remoteTraceTarget"] = remoteTraceTarget.value_or(""); + config["tags"] = json::parse(tags.value_or("[]")); + config["vMajor"] = vMajor.value_or(-1); + config["vMinor"] = vMinor.value_or(-1); + config["vRev"] = vRev.value_or(-1); + config["vProto"] = vProto.value_or(-1); + config["noAutoAssignIps"] = noAutoAssignIps.value_or(false); + config["revision"] = revision.value_or(0); + config["ssoExempt"] = ssoExempt.value_or(false); + config["authenticationExpiryTime"] = authenticationExpiryTime.value_or(0); + config["objtype"] = "member"; + config["ipAssignments"] = json::array(); + + if (assignedAddresses != "{}") { + std::string tmp = assignedAddresses.substr(1, assignedAddresses.size()-2); + std::vector addrs = split(tmp, ','); + for (auto it = addrs.begin(); it != addrs.end(); ++it) { + config["ipAssignments"].push_back(*it); + } + } + + Metrics::member_count++; + + _memberChanged(empty, config, false); + + memberId = ""; + networkId = ""; + + auto end = std::chrono::high_resolution_clock::now(); + auto dur = std::chrono::duration_cast(end - start); + total += dur.count(); + ++count; + if (count > 0 && count % 10000 == 0) { + fprintf(stderr, "Averaging %llu us per member\n", (total/count)); + } + } + if (count > 0) { + fprintf(stderr, "Took %llu us per member to load\n", (total/count)); + } + + stream.complete(); + + w.commit(); + _pool->unborrow(c2); + _pool->unborrow(c); + fprintf(stderr, "done.\n"); + + if (!networkMembers.empty()) { + if (_redisMemberStatus) { + fprintf(stderr, "Load member data into redis...\n"); + if (_rc->clusterMode) { + auto tx = _cluster->transaction(_myAddressStr, true, false); + uint64_t count = 0; + for (auto it : networkMembers) { + tx.sadd(it.first, it.second); + if (++count % 30000 == 0) { + tx.exec(); + tx = _cluster->transaction(_myAddressStr, true, false); + } + } + tx.exec(); + } else { + auto tx = _redis->transaction(true, false); + uint64_t count = 0; + for (auto it : networkMembers) { + tx.sadd(it.first, it.second); + if (++count % 30000 == 0) { + tx.exec(); + tx = _redis->transaction(true, false); + } + } + tx.exec(); + } + fprintf(stderr, "done.\n"); + } + } + + fprintf(stderr, "Done loading members...\n"); + + if (++this->_ready == 2) { + if (_waitNoticePrinted) { + fprintf(stderr,"[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S,_timestr(),(unsigned long long)_myAddress.toInt()); + } + _readyLock.unlock(); + } + } catch (sw::redis::Error &e) { + fprintf(stderr, "ERROR: Error initializing members (redis): %s\n", e.what()); + exit(-1); + } catch (std::exception &e) { + fprintf(stderr, "ERROR: Error initializing member: %s-%s %s\n", networkId.c_str(), memberId.c_str(), e.what()); + exit(-1); + } +} + +void PostgreSQL::heartbeat() +{ + char publicId[1024]; + char hostnameTmp[1024]; + _myId.toString(false,publicId); + if (gethostname(hostnameTmp, sizeof(hostnameTmp))!= 0) { + hostnameTmp[0] = (char)0; + } else { + for (int i = 0; i < (int)sizeof(hostnameTmp); ++i) { + if ((hostnameTmp[i] == '.')||(hostnameTmp[i] == 0)) { + hostnameTmp[i] = (char)0; + break; + } + } + } + const char *controllerId = _myAddressStr.c_str(); + const char *publicIdentity = publicId; + const char *hostname = hostnameTmp; + + while (_run == 1) { + // fprintf(stderr, "%s: heartbeat\n", controllerId); + auto c = _pool->borrow(); + int64_t ts = OSUtils::now(); + + if(c->c) { + std::string major = std::to_string(ZEROTIER_ONE_VERSION_MAJOR); + std::string minor = std::to_string(ZEROTIER_ONE_VERSION_MINOR); + std::string rev = std::to_string(ZEROTIER_ONE_VERSION_REVISION); + std::string build = std::to_string(ZEROTIER_ONE_VERSION_BUILD); + std::string now = std::to_string(ts); + std::string host_port = std::to_string(_listenPort); + std::string use_redis = (_rc != NULL) ? "true" : "false"; + std::string redis_mem_status = (_redisMemberStatus) ? "true" : "false"; + + try { + pqxx::work w{*c->c}; + + pqxx::result res = + w.exec0("INSERT INTO ztc_controller (id, cluster_host, last_alive, public_identity, v_major, v_minor, v_rev, v_build, host_port, use_redis, redis_member_status) " + "VALUES ("+w.quote(controllerId)+", "+w.quote(hostname)+", TO_TIMESTAMP("+now+"::double precision/1000), "+ + w.quote(publicIdentity)+", "+major+", "+minor+", "+rev+", "+build+", "+host_port+", "+use_redis+", "+redis_mem_status+") " + "ON CONFLICT (id) DO UPDATE SET cluster_host = EXCLUDED.cluster_host, last_alive = EXCLUDED.last_alive, " + "public_identity = EXCLUDED.public_identity, v_major = EXCLUDED.v_major, v_minor = EXCLUDED.v_minor, " + "v_rev = EXCLUDED.v_rev, v_build = EXCLUDED.v_rev, host_port = EXCLUDED.host_port, " + "use_redis = EXCLUDED.use_redis, redis_member_status = EXCLUDED.redis_member_status"); + w.commit(); + } catch (std::exception &e) { + fprintf(stderr, "%s: Heartbeat update failed: %s\n", controllerId, e.what()); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + continue; + } + + } + _pool->unborrow(c); + + try { + if (_redisMemberStatus) { + if (_rc->clusterMode) { + _cluster->zadd("controllers", "controllerId", ts); + } else { + _redis->zadd("controllers", "controllerId", ts); + } + } + } catch (sw::redis::Error &e) { + fprintf(stderr, "ERROR: Redis error in heartbeat thread: %s\n", e.what()); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + fprintf(stderr, "Exited heartbeat thread\n"); +} + +void PostgreSQL::membersDbWatcher() +{ + if (_rc) { + _membersWatcher_Redis(); + } else { + _membersWatcher_Postgres(); + } + + if (_run == 1) { + fprintf(stderr, "ERROR: %s membersDbWatcher should still be running! Exiting Controller.\n", _myAddressStr.c_str()); + exit(9); + } + fprintf(stderr, "Exited membersDbWatcher\n"); +} + +void PostgreSQL::_membersWatcher_Postgres() { + auto c = _pool->borrow(); + + std::string stream = "member_" + _myAddressStr; + + fprintf(stderr, "Listening to member stream: %s\n", stream.c_str()); + MemberNotificationReceiver m(this, *c->c, stream); + + while(_run == 1) { + c->c->await_notification(5, 0); + } + + _pool->unborrow(c); +} + +void PostgreSQL::_membersWatcher_Redis() { + char buf[11] = {0}; + std::string key = "member-stream:{" + std::string(_myAddress.toString(buf)) + "}"; + std::string lastID = "0"; + fprintf(stderr, "Listening to member stream: %s\n", key.c_str()); + while (_run == 1) { + try { + json tmp; + std::unordered_map result; + if (_rc->clusterMode) { + _cluster->xread(key, lastID, std::chrono::seconds(1), 0, std::inserter(result, result.end())); + } else { + _redis->xread(key, lastID, std::chrono::seconds(1), 0, std::inserter(result, result.end())); + } + if (!result.empty()) { + for (auto element : result) { + #ifdef REDIS_TRACE + fprintf(stdout, "Received notification from: %s\n", element.first.c_str()); + #endif + for (auto rec : element.second) { + std::string id = rec.first; + auto attrs = rec.second; + #ifdef REDIS_TRACE + fprintf(stdout, "Record ID: %s\n", id.c_str()); + fprintf(stdout, "attrs len: %lu\n", attrs.size()); + #endif + for (auto a : attrs) { + #ifdef REDIS_TRACE + fprintf(stdout, "key: %s\nvalue: %s\n", a.first.c_str(), a.second.c_str()); + #endif + try { + tmp = json::parse(a.second); + json &ov = tmp["old_val"]; + json &nv = tmp["new_val"]; + json oldConfig, newConfig; + if (ov.is_object()) oldConfig = ov; + if (nv.is_object()) newConfig = nv; + if (oldConfig.is_object()||newConfig.is_object()) { + _memberChanged(oldConfig,newConfig,(this->_ready >= 2)); + } + } catch (...) { + fprintf(stderr, "json parse error in _membersWatcher_Redis: %s\n", a.second.c_str()); + } + } + if (_rc->clusterMode) { + _cluster->xdel(key, id); + } else { + _redis->xdel(key, id); + } + lastID = id; + Metrics::redis_mem_notification++; + } + } + } + } catch (sw::redis::Error &e) { + fprintf(stderr, "Error in Redis members watcher: %s\n", e.what()); + } + } + fprintf(stderr, "membersWatcher ended\n"); +} + +void PostgreSQL::networksDbWatcher() +{ + if (_rc) { + _networksWatcher_Redis(); + } else { + _networksWatcher_Postgres(); + } + + if (_run == 1) { + fprintf(stderr, "ERROR: %s networksDbWatcher should still be running! Exiting Controller.\n", _myAddressStr.c_str()); + exit(8); + } + fprintf(stderr, "Exited networksDbWatcher\n"); +} + +void PostgreSQL::_networksWatcher_Postgres() { + std::string stream = "network_" + _myAddressStr; + + fprintf(stderr, "Listening to member stream: %s\n", stream.c_str()); + + auto c = _pool->borrow(); + + NetworkNotificationReceiver n(this, *c->c, stream); + + while(_run == 1) { + c->c->await_notification(5,0); + } +} + +void PostgreSQL::_networksWatcher_Redis() { + char buf[11] = {0}; + std::string key = "network-stream:{" + std::string(_myAddress.toString(buf)) + "}"; + std::string lastID = "0"; + while (_run == 1) { + try { + json tmp; + std::unordered_map result; + if (_rc->clusterMode) { + _cluster->xread(key, lastID, std::chrono::seconds(1), 0, std::inserter(result, result.end())); + } else { + _redis->xread(key, lastID, std::chrono::seconds(1), 0, std::inserter(result, result.end())); + } + + if (!result.empty()) { + for (auto element : result) { +#ifdef REDIS_TRACE + fprintf(stdout, "Received notification from: %s\n", element.first.c_str()); +#endif + for (auto rec : element.second) { + std::string id = rec.first; + auto attrs = rec.second; +#ifdef REDIS_TRACE + fprintf(stdout, "Record ID: %s\n", id.c_str()); + fprintf(stdout, "attrs len: %lu\n", attrs.size()); +#endif + for (auto a : attrs) { +#ifdef REDIS_TRACE + fprintf(stdout, "key: %s\nvalue: %s\n", a.first.c_str(), a.second.c_str()); +#endif + try { + tmp = json::parse(a.second); + json &ov = tmp["old_val"]; + json &nv = tmp["new_val"]; + json oldConfig, newConfig; + if (ov.is_object()) oldConfig = ov; + if (nv.is_object()) newConfig = nv; + if (oldConfig.is_object()||newConfig.is_object()) { + _networkChanged(oldConfig,newConfig,(this->_ready >= 2)); + } + } catch (std::exception &e) { + fprintf(stderr, "json parse error in networkWatcher_Redis: what: %s json: %s\n", e.what(), a.second.c_str()); + } + } + if (_rc->clusterMode) { + _cluster->xdel(key, id); + } else { + _redis->xdel(key, id); + } + lastID = id; + } + Metrics::redis_net_notification++; + } + } + } catch (sw::redis::Error &e) { + fprintf(stderr, "Error in Redis networks watcher: %s\n", e.what()); + } + } + fprintf(stderr, "networksWatcher ended\n"); +} + +void PostgreSQL::commitThread() +{ + fprintf(stderr, "%s: commitThread start\n", _myAddressStr.c_str()); + std::pair qitem; + while(_commitQueue.get(qitem)&(_run == 1)) { + //fprintf(stderr, "commitThread tick\n"); + if (!qitem.first.is_object()) { + fprintf(stderr, "not an object\n"); + continue; + } + + std::shared_ptr c; + try { + c = _pool->borrow(); + } catch (std::exception &e) { + fprintf(stderr, "ERROR: %s\n", e.what()); + continue; + } + + if (!c) { + fprintf(stderr, "Error getting database connection\n"); + continue; + } + + Metrics::pgsql_commit_ticks++; + try { + nlohmann::json &config = (qitem.first); + const std::string objtype = config["objtype"]; + if (objtype == "member") { + // fprintf(stderr, "%s: commitThread: member\n", _myAddressStr.c_str()); + std::string memberId; + std::string networkId; + try { + pqxx::work w(*c->c); + + memberId = config["id"]; + networkId = config["nwid"]; + + std::string target = "NULL"; + if (!config["remoteTraceTarget"].is_null()) { + target = config["remoteTraceTarget"]; + } + + pqxx::row nwrow = w.exec_params1("SELECT COUNT(id) FROM ztc_network WHERE id = $1", networkId); + int nwcount = nwrow[0].as(); + + if (nwcount != 1) { + fprintf(stderr, "network %s does not exist. skipping member upsert\n", networkId.c_str()); + w.abort(); + _pool->unborrow(c); + continue; + } + + + pqxx::row mrow = w.exec_params1("SELECT COUNT(id) FROM ztc_member WHERE id = $1 AND network_id = $2", memberId, networkId); + int membercount = mrow[0].as(); + + bool isNewMember = false; + if (membercount == 0) { + // new member + isNewMember = true; + pqxx::result res = w.exec_params0( + "INSERT INTO ztc_member (id, network_id, active_bridge, authorized, capabilities, " + "identity, last_authorized_time, last_deauthorized_time, no_auto_assign_ips, " + "remote_trace_level, remote_trace_target, revision, tags, v_major, v_minor, v_rev, v_proto) " + "VALUES ($1, $2, $3, $4, $5, $6, " + "TO_TIMESTAMP($7::double precision/1000), TO_TIMESTAMP($8::double precision/1000), " + "$9, $10, $11, $12, $13, $14, $15, $16, $17)", + memberId, + networkId, + (bool)config["activeBridge"], + (bool)config["authorized"], + OSUtils::jsonDump(config["capabilities"], -1), + OSUtils::jsonString(config["identity"], ""), + (uint64_t)config["lastAuthorizedTime"], + (uint64_t)config["lastDeauthorizedTime"], + (bool)config["noAutoAssignIps"], + (int)config["remoteTraceLevel"], + target, + (uint64_t)config["revision"], + OSUtils::jsonDump(config["tags"], -1), + (int)config["vMajor"], + (int)config["vMinor"], + (int)config["vRev"], + (int)config["vProto"]); + } else { + // existing member + pqxx::result res = w.exec_params0( + "UPDATE ztc_member " + "SET active_bridge = $3, authorized = $4, capabilities = $5, identity = $6, " + "last_authorized_time = TO_TIMESTAMP($7::double precision/1000), " + "last_deauthorized_time = TO_TIMESTAMP($8::double precision/1000), " + "no_auto_assign_ips = $9, remote_trace_level = $10, remote_trace_target= $11, " + "revision = $12, tags = $13, v_major = $14, v_minor = $15, v_rev = $16, v_proto = $17 " + "WHERE id = $1 AND network_id = $2", + memberId, + networkId, + (bool)config["activeBridge"], + (bool)config["authorized"], + OSUtils::jsonDump(config["capabilities"], -1), + OSUtils::jsonString(config["identity"], ""), + (uint64_t)config["lastAuthorizedTime"], + (uint64_t)config["lastDeauthorizedTime"], + (bool)config["noAutoAssignIps"], + (int)config["remoteTraceLevel"], + target, + (uint64_t)config["revision"], + OSUtils::jsonDump(config["tags"], -1), + (int)config["vMajor"], + (int)config["vMinor"], + (int)config["vRev"], + (int)config["vProto"] + ); + } + + if (!isNewMember) { + pqxx::result res = w.exec_params0("DELETE FROM ztc_member_ip_assignment WHERE member_id = $1 AND network_id = $2", + memberId, networkId); + } + + std::vector assignments; + bool ipAssignError = false; + for (auto i = config["ipAssignments"].begin(); i != config["ipAssignments"].end(); ++i) { + std::string addr = *i; + + if (std::find(assignments.begin(), assignments.end(), addr) != assignments.end()) { + continue; + } + + pqxx::result res = w.exec_params0( + "INSERT INTO ztc_member_ip_assignment (member_id, network_id, address) VALUES ($1, $2, $3) ON CONFLICT (network_id, member_id, address) DO NOTHING", + memberId, networkId, addr); + + assignments.push_back(addr); + } + if (ipAssignError) { + fprintf(stderr, "%s: ipAssignError\n", _myAddressStr.c_str()); + w.abort(); + _pool->unborrow(c); + c.reset(); + continue; + } + + w.commit(); + + if (_smee != NULL && isNewMember) { + pqxx::row row = w.exec_params1( + "SELECT " + " count(h.hook_id) " + "FROM " + " ztc_hook h " + " INNER JOIN ztc_org o ON o.org_id = h.org_id " + " INNER JOIN ztc_network n ON n.owner_id = o.owner_id " + " WHERE " + "n.id = $1 ", + networkId + ); + int64_t hookCount = row[0].as(); + if (hookCount > 0) { + notifyNewMember(networkId, memberId); + } + } + + const uint64_t nwidInt = OSUtils::jsonIntHex(config["nwid"], 0ULL); + const uint64_t memberidInt = OSUtils::jsonIntHex(config["id"], 0ULL); + if (nwidInt && memberidInt) { + nlohmann::json nwOrig; + nlohmann::json memOrig; + + nlohmann::json memNew(config); + + get(nwidInt, nwOrig, memberidInt, memOrig); + + _memberChanged(memOrig, memNew, qitem.second); + } else { + fprintf(stderr, "%s: Can't notify of change. Error parsing nwid or memberid: %llu-%llu\n", _myAddressStr.c_str(), (unsigned long long)nwidInt, (unsigned long long)memberidInt); + } + } catch (std::exception &e) { + fprintf(stderr, "%s ERROR: Error updating member %s-%s: %s\n", _myAddressStr.c_str(), networkId.c_str(), memberId.c_str(), e.what()); + } + } else if (objtype == "network") { + try { + // fprintf(stderr, "%s: commitThread: network\n", _myAddressStr.c_str()); + pqxx::work w(*c->c); + + std::string id = config["id"]; + std::string remoteTraceTarget = ""; + if(!config["remoteTraceTarget"].is_null()) { + remoteTraceTarget = config["remoteTraceTarget"]; + } + std::string rulesSource = ""; + if (config["rulesSource"].is_string()) { + rulesSource = config["rulesSource"]; + } + + // This ugly query exists because when we want to mirror networks to/from + // another data store (e.g. FileDB or LFDB) it is possible to get a network + // that doesn't exist in Central's database. This does an upsert and sets + // the owner_id to the "first" global admin in the user DB if the record + // did not previously exist. If the record already exists owner_id is left + // unchanged, so owner_id should be left out of the update clause. + pqxx::result res = w.exec_params0( + "INSERT INTO ztc_network (id, creation_time, owner_id, controller_id, capabilities, enable_broadcast, " + "last_modified, mtu, multicast_limit, name, private, " + "remote_trace_level, remote_trace_target, rules, rules_source, " + "tags, v4_assign_mode, v6_assign_mode, sso_enabled) VALUES (" + "$1, TO_TIMESTAMP($5::double precision/1000), " + "(SELECT user_id AS owner_id FROM ztc_global_permissions WHERE authorize = true AND del = true AND modify = true AND read = true LIMIT 1)," + "$2, $3, $4, TO_TIMESTAMP($5::double precision/1000), " + "$6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) " + "ON CONFLICT (id) DO UPDATE set controller_id = EXCLUDED.controller_id, " + "capabilities = EXCLUDED.capabilities, enable_broadcast = EXCLUDED.enable_broadcast, " + "last_modified = EXCLUDED.last_modified, mtu = EXCLUDED.mtu, " + "multicast_limit = EXCLUDED.multicast_limit, name = EXCLUDED.name, " + "private = EXCLUDED.private, remote_trace_level = EXCLUDED.remote_trace_level, " + "remote_trace_target = EXCLUDED.remote_trace_target, rules = EXCLUDED.rules, " + "rules_source = EXCLUDED.rules_source, tags = EXCLUDED.tags, " + "v4_assign_mode = EXCLUDED.v4_assign_mode, v6_assign_mode = EXCLUDED.v6_assign_mode, " + "sso_enabled = EXCLUDED.sso_enabled", + id, + _myAddressStr, + OSUtils::jsonDump(config["capabilities"], -1), + (bool)config["enableBroadcast"], + OSUtils::now(), + (int)config["mtu"], + (int)config["multicastLimit"], + OSUtils::jsonString(config["name"],""), + (bool)config["private"], + (int)config["remoteTraceLevel"], + remoteTraceTarget, + OSUtils::jsonDump(config["rules"], -1), + rulesSource, + OSUtils::jsonDump(config["tags"], -1), + OSUtils::jsonDump(config["v4AssignMode"],-1), + OSUtils::jsonDump(config["v6AssignMode"], -1), + OSUtils::jsonBool(config["ssoEnabled"], false)); + + res = w.exec_params0("DELETE FROM ztc_network_assignment_pool WHERE network_id = $1", 0); + + auto pool = config["ipAssignmentPools"]; + bool err = false; + for (auto i = pool.begin(); i != pool.end(); ++i) { + std::string start = (*i)["ipRangeStart"]; + std::string end = (*i)["ipRangeEnd"]; + + res = w.exec_params0( + "INSERT INTO ztc_network_assignment_pool (network_id, ip_range_start, ip_range_end) " + "VALUES ($1, $2, $3)", id, start, end); + } + + res = w.exec_params0("DELETE FROM ztc_network_route WHERE network_id = $1", id); + + auto routes = config["routes"]; + err = false; + for (auto i = routes.begin(); i != routes.end(); ++i) { + std::string t = (*i)["target"]; + std::vector target; + std::istringstream f(t); + std::string s; + while(std::getline(f, s, '/')) { + target.push_back(s); + } + if (target.empty() || target.size() != 2) { + continue; + } + std::string targetAddr = target[0]; + std::string targetBits = target[1]; + std::string via = "NULL"; + if (!(*i)["via"].is_null()) { + via = (*i)["via"]; + } + + res = w.exec_params0("INSERT INTO ztc_network_route (network_id, address, bits, via) VALUES ($1, $2, $3, $4)", + id, targetAddr, targetBits, (via == "NULL" ? NULL : via.c_str())); + } + if (err) { + fprintf(stderr, "%s: route add error\n", _myAddressStr.c_str()); + w.abort(); + _pool->unborrow(c); + continue; + } + + auto dns = config["dns"]; + std::string domain = dns["domain"]; + std::stringstream servers; + servers << "{"; + for (auto j = dns["servers"].begin(); j < dns["servers"].end(); ++j) { + servers << *j; + if ( (j+1) != dns["servers"].end()) { + servers << ","; + } + } + servers << "}"; + + std::string s = servers.str(); + + res = w.exec_params0("INSERT INTO ztc_network_dns (network_id, domain, servers) VALUES ($1, $2, $3) ON CONFLICT (network_id) DO UPDATE SET domain = EXCLUDED.domain, servers = EXCLUDED.servers", + id, domain, s); + + w.commit(); + + const uint64_t nwidInt = OSUtils::jsonIntHex(config["nwid"], 0ULL); + if (nwidInt) { + nlohmann::json nwOrig; + nlohmann::json nwNew(config); + + get(nwidInt, nwOrig); + + _networkChanged(nwOrig, nwNew, qitem.second); + } else { + fprintf(stderr, "%s: Can't notify network changed: %llu\n", _myAddressStr.c_str(), (unsigned long long)nwidInt); + } + } catch (std::exception &e) { + fprintf(stderr, "%s ERROR: Error updating network: %s\n", _myAddressStr.c_str(), e.what()); + } + if (_redisMemberStatus) { + try { + std::string id = config["id"]; + std::string controllerId = _myAddressStr.c_str(); + std::string key = "networks:{" + controllerId + "}"; + if (_rc->clusterMode) { + _cluster->sadd(key, id); + } else { + _redis->sadd(key, id); + } + } catch (sw::redis::Error &e) { + fprintf(stderr, "ERROR: Error adding network to Redis: %s\n", e.what()); + } + } + } else if (objtype == "_delete_network") { + // fprintf(stderr, "%s: commitThread: delete network\n", _myAddressStr.c_str()); + try { + pqxx::work w(*c->c); + + std::string networkId = config["nwid"]; + + pqxx::result res = w.exec_params0("UPDATE ztc_network SET deleted = true WHERE id = $1", + networkId); + + w.commit(); + } catch (std::exception &e) { + fprintf(stderr, "%s ERROR: Error deleting network: %s\n", _myAddressStr.c_str(), e.what()); + } + if (_redisMemberStatus) { + try { + std::string id = config["id"]; + std::string controllerId = _myAddressStr.c_str(); + std::string key = "networks:{" + controllerId + "}"; + if (_rc->clusterMode) { + _cluster->srem(key, id); + _cluster->del("network-nodes-online:{"+controllerId+"}:"+id); + } else { + _redis->srem(key, id); + _redis->del("network-nodes-online:{"+controllerId+"}:"+id); + } + } catch (sw::redis::Error &e) { + fprintf(stderr, "ERROR: Error adding network to Redis: %s\n", e.what()); + } + } + + } else if (objtype == "_delete_member") { + // fprintf(stderr, "%s commitThread: delete member\n", _myAddressStr.c_str()); + try { + pqxx::work w(*c->c); + + std::string memberId = config["id"]; + std::string networkId = config["nwid"]; + + pqxx::result res = w.exec_params0( + "UPDATE ztc_member SET hidden = true, deleted = true WHERE id = $1 AND network_id = $2", + memberId, networkId); + + w.commit(); + } catch (std::exception &e) { + fprintf(stderr, "%s ERROR: Error deleting member: %s\n", _myAddressStr.c_str(), e.what()); + } + if (_redisMemberStatus) { + try { + std::string memberId = config["id"]; + std::string networkId = config["nwid"]; + std::string controllerId = _myAddressStr.c_str(); + std::string key = "network-nodes-all:{" + controllerId + "}:" + networkId; + if (_rc->clusterMode) { + _cluster->srem(key, memberId); + _cluster->del("member:{"+controllerId+"}:"+networkId+":"+memberId); + } else { + _redis->srem(key, memberId); + _redis->del("member:{"+controllerId+"}:"+networkId+":"+memberId); + } + } catch (sw::redis::Error &e) { + fprintf(stderr, "ERROR: Error deleting member from Redis: %s\n", e.what()); + } + } + } else { + fprintf(stderr, "%s ERROR: unknown objtype\n", _myAddressStr.c_str()); + } + } catch (std::exception &e) { + fprintf(stderr, "%s ERROR: Error getting objtype: %s\n", _myAddressStr.c_str(), e.what()); + } + _pool->unborrow(c); + c.reset(); + } + + fprintf(stderr, "%s commitThread finished\n", _myAddressStr.c_str()); +} + +void PostgreSQL::notifyNewMember(const std::string &networkID, const std::string &memberID) { + smeeclient::smee_client_notify_network_joined( + _smee, + networkID.c_str(), + memberID.c_str()); +} + +void PostgreSQL::onlineNotificationThread() +{ + waitForReady(); + if (_redisMemberStatus) { + onlineNotification_Redis(); + } else { + onlineNotification_Postgres(); + } +} + +/** + * ONLY UNCOMMENT FOR TEMPORARY DB MAINTENANCE + * + * This define temporarily turns off writing to the member status table + * so it can be reindexed when the indexes get too large. + */ + +// #define DISABLE_MEMBER_STATUS 1 + +void PostgreSQL::onlineNotification_Postgres() +{ + _connected = 1; + + nlohmann::json jtmp1, jtmp2; + while (_run == 1) { + auto c = _pool->borrow(); + auto c2 = _pool->borrow(); + try { + fprintf(stderr, "%s onlineNotification_Postgres\n", _myAddressStr.c_str()); + std::unordered_map< std::pair,std::pair,_PairHasher > lastOnline; + { + std::lock_guard l(_lastOnline_l); + lastOnline.swap(_lastOnline); + } + +#ifndef DISABLE_MEMBER_STATUS + pqxx::work w(*c->c); + pqxx::work w2(*c2->c); + + fprintf(stderr, "online notification tick\n"); + + bool firstRun = true; + bool memberAdded = false; + int updateCount = 0; + + pqxx::pipeline pipe(w); + + for (auto i=lastOnline.begin(); i != lastOnline.end(); ++i) { + updateCount += 1; + uint64_t nwid_i = i->first.first; + char nwidTmp[64]; + char memTmp[64]; + char ipTmp[64]; + OSUtils::ztsnprintf(nwidTmp,sizeof(nwidTmp), "%.16llx", nwid_i); + OSUtils::ztsnprintf(memTmp,sizeof(memTmp), "%.10llx", i->first.second); + + if(!get(nwid_i, jtmp1, i->first.second, jtmp2)) { + continue; // skip non existent networks/members + } + + std::string networkId(nwidTmp); + std::string memberId(memTmp); + + try { + pqxx::row r = w2.exec_params1("SELECT id, network_id FROM ztc_member WHERE network_id = $1 AND id = $2", + networkId, memberId); + } catch (pqxx::unexpected_rows &e) { + continue; + } + + int64_t ts = i->second.first; + std::string ipAddr = i->second.second.toIpString(ipTmp); + std::string timestamp = std::to_string(ts); + + std::stringstream memberUpdate; + memberUpdate << "INSERT INTO ztc_member_status (network_id, member_id, address, last_updated) VALUES " + << "('" << networkId << "', '" << memberId << "', "; + if (ipAddr.empty()) { + memberUpdate << "NULL, "; + } else { + memberUpdate << "'" << ipAddr << "', "; + } + memberUpdate << "TO_TIMESTAMP(" << timestamp << "::double precision/1000)) " + << " ON CONFLICT (network_id, member_id) DO UPDATE SET address = EXCLUDED.address, last_updated = EXCLUDED.last_updated"; + + pipe.insert(memberUpdate.str()); + Metrics::pgsql_node_checkin++; + } + while(!pipe.empty()) { + pipe.retrieve(); + } + + pipe.complete(); + w.commit(); + fprintf(stderr, "%s: Updated online status of %d members\n", _myAddressStr.c_str(), updateCount); +#endif + } catch (std::exception &e) { + fprintf(stderr, "%s: error in onlinenotification thread: %s\n", _myAddressStr.c_str(), e.what()); + } + _pool->unborrow(c2); + _pool->unborrow(c); + + ConnectionPoolStats stats = _pool->get_stats(); + fprintf(stderr, "%s pool stats: in use size: %llu, available size: %llu, total: %llu\n", + _myAddressStr.c_str(), stats.borrowed_size, stats.pool_size, (stats.borrowed_size + stats.pool_size)); + + std::this_thread::sleep_for(std::chrono::seconds(10)); + } + fprintf(stderr, "%s: Fell out of run loop in onlineNotificationThread\n", _myAddressStr.c_str()); + if (_run == 1) { + fprintf(stderr, "ERROR: %s onlineNotificationThread should still be running! Exiting Controller.\n", _myAddressStr.c_str()); + exit(6); + } +} + +void PostgreSQL::onlineNotification_Redis() +{ + _connected = 1; + + char buf[11] = {0}; + std::string controllerId = std::string(_myAddress.toString(buf)); + + while (_run == 1) { + fprintf(stderr, "onlineNotification tick\n"); + auto start = std::chrono::high_resolution_clock::now(); + uint64_t count = 0; + + std::unordered_map< std::pair,std::pair,_PairHasher > lastOnline; + { + std::lock_guard l(_lastOnline_l); + lastOnline.swap(_lastOnline); + } + try { + if (!lastOnline.empty()) { + if (_rc->clusterMode) { + auto tx = _cluster->transaction(controllerId, true, false); + count = _doRedisUpdate(tx, controllerId, lastOnline); + } else { + auto tx = _redis->transaction(true, false); + count = _doRedisUpdate(tx, controllerId, lastOnline); + } + } + } catch (sw::redis::Error &e) { + fprintf(stderr, "Error in online notification thread (redis): %s\n", e.what()); + } + + auto end = std::chrono::high_resolution_clock::now(); + auto dur = std::chrono::duration_cast(end - start); + auto total = dur.count(); + + fprintf(stderr, "onlineNotification ran in %llu ms\n", total); + + std::this_thread::sleep_for(std::chrono::seconds(5)); + } +} + +uint64_t PostgreSQL::_doRedisUpdate(sw::redis::Transaction &tx, std::string &controllerId, + std::unordered_map< std::pair,std::pair,_PairHasher > &lastOnline) + +{ + nlohmann::json jtmp1, jtmp2; + uint64_t count = 0; + for (auto i=lastOnline.begin(); i != lastOnline.end(); ++i) { + uint64_t nwid_i = i->first.first; + uint64_t memberid_i = i->first.second; + char nwidTmp[64]; + char memTmp[64]; + char ipTmp[64]; + OSUtils::ztsnprintf(nwidTmp,sizeof(nwidTmp), "%.16llx", nwid_i); + OSUtils::ztsnprintf(memTmp,sizeof(memTmp), "%.10llx", memberid_i); + + if (!get(nwid_i, jtmp1, memberid_i, jtmp2)){ + continue; // skip non existent members/networks + } + + std::string networkId(nwidTmp); + std::string memberId(memTmp); + + int64_t ts = i->second.first; + std::string ipAddr = i->second.second.toIpString(ipTmp); + std::string timestamp = std::to_string(ts); + + std::unordered_map record = { + {"id", memberId}, + {"address", ipAddr}, + {"last_updated", std::to_string(ts)} + }; + tx.zadd("nodes-online:{"+controllerId+"}", memberId, ts) + .zadd("nodes-online2:{"+controllerId+"}", networkId+"-"+memberId, ts) + .zadd("network-nodes-online:{"+controllerId+"}:"+networkId, memberId, ts) + .zadd("active-networks:{"+controllerId+"}", networkId, ts) + .sadd("network-nodes-all:{"+controllerId+"}:"+networkId, memberId) + .hmset("member:{"+controllerId+"}:"+networkId+":"+memberId, record.begin(), record.end()); + ++count; + Metrics::redis_node_checkin++; + } + + // expire records from all-nodes and network-nodes member list + uint64_t expireOld = OSUtils::now() - 300000; + + tx.zremrangebyscore("nodes-online:{"+controllerId+"}", + sw::redis::RightBoundedInterval(expireOld, + sw::redis::BoundType::LEFT_OPEN)); + tx.zremrangebyscore("nodes-online2:{"+controllerId+"}", + sw::redis::RightBoundedInterval(expireOld, + sw::redis::BoundType::LEFT_OPEN)); + tx.zremrangebyscore("active-networks:{"+controllerId+"}", + sw::redis::RightBoundedInterval(expireOld, + sw::redis::BoundType::LEFT_OPEN)); + { + std::shared_lock l(_networks_l); + for (const auto &it : _networks) { + uint64_t nwid_i = it.first; + char nwidTmp[64]; + OSUtils::ztsnprintf(nwidTmp,sizeof(nwidTmp), "%.16llx", nwid_i); + tx.zremrangebyscore("network-nodes-online:{"+controllerId+"}:"+nwidTmp, + sw::redis::RightBoundedInterval(expireOld, sw::redis::BoundType::LEFT_OPEN)); + } + } + tx.exec(); + fprintf(stderr, "%s: Updated online status of %d members\n", _myAddressStr.c_str(), count); + + return count; +} + + +#endif //ZT_CONTROLLER_USE_LIBPQ diff --git a/controller/PostgreSQL.hpp b/controller/PostgreSQL.hpp new file mode 100644 index 0000000..b583bd6 --- /dev/null +++ b/controller/PostgreSQL.hpp @@ -0,0 +1,196 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2026-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#include "DB.hpp" + +#ifdef ZT_CONTROLLER_USE_LIBPQ + +#ifndef ZT_CONTROLLER_LIBPQ_HPP +#define ZT_CONTROLLER_LIBPQ_HPP + +#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4 + +#include "ConnectionPool.hpp" +#include + +#include +#include + +#include "../node/Metrics.hpp" + +extern "C" { +typedef struct pg_conn PGconn; +} + +namespace smeeclient { + struct SmeeClient; +} + +namespace ZeroTier { + +struct RedisConfig; + + +class PostgresConnection : public Connection { +public: + virtual ~PostgresConnection() { + } + + std::shared_ptr c; + int a; +}; + + +class PostgresConnFactory : public ConnectionFactory { +public: + PostgresConnFactory(std::string &connString) + : m_connString(connString) + { + } + + virtual std::shared_ptr create() { + Metrics::conn_counter++; + auto c = std::shared_ptr(new PostgresConnection()); + c->c = std::make_shared(m_connString); + return std::static_pointer_cast(c); + } +private: + std::string m_connString; +}; + +class PostgreSQL; + +class MemberNotificationReceiver : public pqxx::notification_receiver { +public: + MemberNotificationReceiver(PostgreSQL *p, pqxx::connection &c, const std::string &channel); + virtual ~MemberNotificationReceiver() { + fprintf(stderr, "MemberNotificationReceiver destroyed\n"); + } + + virtual void operator() (const std::string &payload, int backendPid); +private: + PostgreSQL *_psql; +}; + +class NetworkNotificationReceiver : public pqxx::notification_receiver { +public: + NetworkNotificationReceiver(PostgreSQL *p, pqxx::connection &c, const std::string &channel); + virtual ~NetworkNotificationReceiver() { + fprintf(stderr, "NetworkNotificationReceiver destroyed\n"); + }; + + virtual void operator() (const std::string &payload, int packend_pid); +private: + PostgreSQL *_psql; +}; + +/** + * A controller database driver that talks to PostgreSQL + * + * This is for use with ZeroTier Central. Others are free to build and use it + * but be aware that we might change it at any time. + */ +class PostgreSQL : public DB +{ + friend class MemberNotificationReceiver; + friend class NetworkNotificationReceiver; +public: + PostgreSQL(const Identity &myId, const char *path, int listenPort, RedisConfig *rc); + virtual ~PostgreSQL(); + + virtual bool waitForReady(); + virtual bool isReady(); + virtual bool save(nlohmann::json &record,bool notifyListeners); + virtual void eraseNetwork(const uint64_t networkId); + virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress); + virtual AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL); + +protected: + struct _PairHasher + { + inline std::size_t operator()(const std::pair &p) const { return (std::size_t)(p.first ^ p.second); } + }; + virtual void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners) { + DB::_memberChanged(old, memberConfig, notifyListeners); + } + + virtual void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners) { + DB::_networkChanged(old, networkConfig, notifyListeners); + } + +private: + void initializeNetworks(); + void initializeMembers(); + void heartbeat(); + void membersDbWatcher(); + void _membersWatcher_Postgres(); + void networksDbWatcher(); + void _networksWatcher_Postgres(); + + void _membersWatcher_Redis(); + void _networksWatcher_Redis(); + + void commitThread(); + void onlineNotificationThread(); + void onlineNotification_Postgres(); + void onlineNotification_Redis(); + uint64_t _doRedisUpdate(sw::redis::Transaction &tx, std::string &controllerId, + std::unordered_map< std::pair,std::pair,_PairHasher > &lastOnline); + + void configureSmee(); + void notifyNewMember(const std::string &networkID, const std::string &memberID); + + enum OverrideMode { + ALLOW_PGBOUNCER_OVERRIDE = 0, + NO_OVERRIDE = 1 + }; + + std::shared_ptr > _pool; + + const Identity _myId; + const Address _myAddress; + std::string _myAddressStr; + std::string _connString; + + BlockingQueue< std::pair > _commitQueue; + + std::thread _heartbeatThread; + std::thread _membersDbWatcher; + std::thread _networksDbWatcher; + std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS]; + std::thread _onlineNotificationThread; + + std::unordered_map< std::pair,std::pair,_PairHasher > _lastOnline; + + mutable std::mutex _lastOnline_l; + mutable std::mutex _readyLock; + std::atomic _ready, _connected, _run; + mutable volatile bool _waitNoticePrinted; + + int _listenPort; + uint8_t _ssoPsk[48]; + + RedisConfig *_rc; + std::shared_ptr _redis; + std::shared_ptr _cluster; + bool _redisMemberStatus; + + smeeclient::SmeeClient *_smee; +}; + +} // namespace ZeroTier + +#endif // ZT_CONTROLLER_LIBPQ_HPP + +#endif // ZT_CONTROLLER_USE_LIBPQ diff --git a/controller/README.md b/controller/README.md new file mode 100644 index 0000000..41cfd3f --- /dev/null +++ b/controller/README.md @@ -0,0 +1,55 @@ +Network Controller Microservice +====== + +Every ZeroTier virtual network has a *network controller* responsible for admitting members to the network, issuing certificates, and issuing default configuration information. + +This is our reference controller implementation and is almost the same as the one we use to power our own hosted services at [my.zerotier.com](https://my.zerotier.com/). The only difference is the database backend used. + +Controller data is stored in JSON format under `controller.d` in the ZeroTier working directory. It can be copied, rsync'd, placed in `git`, etc. The files under `controller.d` should not be modified in place while the controller is running or data loss may result, and if they are edited directly take care not to save corrupt JSON since that can also lead to data loss when the controller is restarted. Going through the API is strongly preferred to directly modifying these files. + +See the API section below for information about controlling the controller. + +### Scalability and Reliability + +Controllers can in theory host up to 2^24 networks and serve many millions of devices (or more), but we recommend spreading large numbers of networks across many controllers for load balancing and fault tolerance reasons. Since the controller uses the filesystem as its data store we recommend fast filesystems and fast SSD drives for heavily loaded controllers. + +Since ZeroTier nodes are mobile and do not need static IPs, implementing high availability fail-over for controllers is easy. Just replicate their working directories from master to backup and have something automatically fire up the backup if the master goes down. Modern orchestration tools like Nomad and Kubernetes can be of help here. + +### Dockerizing Controllers + +ZeroTier network controllers can easily be run in Docker or other container systems. Since containers do not need to actually join networks, extra privilege options like "--device=/dev/net/tun --privileged" are not needed. You'll just need to map the local JSON API port of the running controller and allow it to access the Internet (over UDP/9993 at a minimum) so things can reach and query it. + +### Upgrading from Older (1.1.14 or earlier) Versions + +Older versions of this code used a SQLite database instead of in-filesystem JSON. A migration utility called `migrate-sqlite` is included here and *must* be used to migrate this data to the new format. If the controller is started with an old `controller.db` in its working directory it will terminate after printing an error to *stderr*. This is done to prevent "surprises" for those running DIY controllers using the old code. + +The migration tool is written in nodeJS and can be used like this: + + cd migrate-sqlite + npm install + node migrate.js + +### Network Controller API + +The controller API is hosted via the same JSON API endpoint that ZeroTier One uses for local control (usually at 127.0.0.1 port 9993). All controller options are routed under the `/controller` base path. + +The controller microservice itself does not implement any fine-grained access control. Access control is via the ZeroTier control interface itself and `authtoken.secret`. This can be sent as the `X-ZT1-Auth` HTTP header field or appended to the URL as `?auth=`. Take care when doing the latter that request URLs are not being logged. + +While networks with any valid ID can be added to the controller's database, it will only actually work to control networks whose first 10 hex digits correspond with the network controller's ZeroTier ID. See [section 2.2.1 of the ZeroTier manual](https://zerotier.com/manual.shtml#2_2_1). + +The controller JSON API is *very* sensitive about types. Integers must be integers and strings strings, etc. Incorrect types may be ignored, set to default values, or set to undefined values. + +Full documentation of the Controller API can be found on our [documentation site](https://docs.zerotier.com/service/v1#tag/controller) + +### Prometheus Metrics + +Controller specific metrics are available from the `/metrics` endpoint. + +| Metric Name | Type | Description | +| --- | --- | --- | +| controller_network_count | Gauge | number of networks the controller is serving | +| controller_member_count | Gauge | number of network members the controller is serving | +| controller_network_change_count | Counter | number of times a network configuration is changed | +| controller_member_change_count | Counter | number of times a network member configuration is changed | +| controller_member_auth_count | Counter | number of network member auths | +| controller_member_deauth_count | Counter | number of network member deauths| diff --git a/controller/Redis.hpp b/controller/Redis.hpp new file mode 100644 index 0000000..095419b --- /dev/null +++ b/controller/Redis.hpp @@ -0,0 +1,15 @@ +#ifndef ZT_CONTROLLER_REDIS_HPP +#define ZT_CONTROLLER_REDIS_HPP + +#include + +namespace ZeroTier { +struct RedisConfig { + std::string hostname; + int port; + std::string password; + bool clusterMode; +}; +} + +#endif \ No newline at end of file diff --git a/cycle_controllers.sh b/cycle_controllers.sh new file mode 100755 index 0000000..34acacf --- /dev/null +++ b/cycle_controllers.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +CONTROLLERS=`kubectl get pods -o=name | grep controller | sed "s/^.\{4\}//"` + +for c in ${CONTROLLERS[@]} +do + kubectl delete pod ${c} + sleep 30 +done diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..660562f --- /dev/null +++ b/debian/changelog @@ -0,0 +1,312 @@ +zerotier-one (1.14.1) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Wed, 11 Sep 2024 01:00:00 -0700 + +zerotier-one (1.14.0) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Tue, 19 Mar 2024 01:00:00 -0700 + +zerotier-one (1.12.2) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Tue, 12 Sep 2023 01:00:00 -0700 + +zerotier-one (1.12.1) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Fri, 25 Aug 2023 01:00:00 -0700 + +zerotier-one (1.12.0) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Thu, 17 Aug 2023 01:00:00 -0700 + +zerotier-one (1.10.6) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Tue, 21 Mar 2023 01:00:00 -0700 + +zerotier-one (1.10.5) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Fri, 10 Mar 2023 01:00:00 -0700 + +zerotier-one (1.10.4) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 06 Mar 2023 01:00:00 -0700 + +zerotier-one (1.10.3) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Sat, 21 Jan 2023 01:00:00 -0700 + +zerotier-one (1.10.2) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Thu, 13 Oct 2022 01:00:00 -0700 + +zerotier-one (1.10.1) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 27 Jun 2022 01:00:00 -0700 + +zerotier-one (1.10.0) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Fri, 03 Jun 2022 01:00:00 -0700 + +zerotier-one (1.8.10) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Tue, 10 May 2022 01:00:00 -0700 + +zerotier-one (1.8.9) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 25 Apr 2022 01:00:00 -0700 + +zerotier-one (1.8.8) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 11 Apr 2022 01:00:00 -0700 + +zerotier-one (1.8.7) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 21 Mar 2022 01:00:00 -0700 + +zerotier-one (1.8.6) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 07 Mar 2022 01:00:00 -0700 + +zerotier-one (1.8.5) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Fri, 17 Dec 2021 01:00:00 -0700 + +zerotier-one (1.8.4) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 23 Nov 2021 01:00:00 -0700 + +zerotier-one (1.8.3) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 15 Nov 2021 01:00:00 -0700 + +zerotier-one (1.8.2) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 08 Nov 2021 01:00:00 -0700 + +zerotier-one (1.8.1) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Wed, 20 Oct 2021 01:00:00 -0700 + +zerotier-one (1.8.0) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Wed, 15 Sep 2021 01:00:00 -0700 + +zerotier-one (1.6.6) unstable; urgency=medium + + * Backport endpoint mitigation against address collision attack. + + -- Adam Ierymenko Tue, 21 Sep 2021 01:00:00 -0700 + +zerotier-one (1.6.5) unstable; urgency=medium + + * Fix path filtering bug that could cause "software laser" effect. + * Fix printf overflow in CLI (not exploitable or security related) + * Fix Windows device enumeration issue. + + -- Adam Ierymenko Tue, 13 Apr 2021 01:00:00 -0700 + +zerotier-one (1.6.4) unstable; urgency=medium + + * REALLY fix a problem causing nodes to go into a "coma" with some network configurations. + + -- Adam Ierymenko Tue, 15 Feb 2021 01:00:00 -0700 + +zerotier-one (1.6.3-1) unstable; urgency=medium + + * Fix a problem causing nodes to go into a "coma" with some network configurations. + + -- Adam Ierymenko Tue, 02 Feb 2021 01:00:00 -0700 + +zerotier-one (1.6.2-2) unstable; urgency=medium + + * This is a minor update to the 1.6.2 package to address issues with + running on ARMv6 CPUs like the Raspberry Pi Zero and original v1 Pi. + + -- Adam Ierymenko Tue, 31 Nov 2020 01:00:00 -0700 + +zerotier-one (1.6.2) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 30 Nov 2020 01:00:00 -0700 + +zerotier-one (1.6.1) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Tue, 24 Nov 2020 01:00:00 -0700 + +zerotier-one (1.6.0) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Thu, 19 Nov 2020 01:00:00 -0700 + +zerotier-one (1.5.0) unstable; urgency=medium + + * Version 1.5.0 is actually 1.6.0-beta1 + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Mon, 05 Aug 2020 01:00:00 -0700 + +zerotier-one (1.4.6) unstable; urgency=medium + + * Update default root server list + * Fix build flags on "armhf" (32-bit ARM) platforms for better + compatibility with Pi Zero and other devices. + * Fix license text in one.cpp. + * Add a clarification to LICENSE.txt. + + -- Adam Ierymenko Fri, 30 Aug 2019 01:00:00 -0700 + +zerotier-one (1.4.4) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + * License changed to BSL 1.1 + + -- Adam Ierymenko Fri, 23 Aug 2019 01:00:00 -0700 + +zerotier-one (1.4.2-2) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + * This is a new build that fixes a binary build issue with containers and SELinux + + -- Adam Ierymenko Thu, 04 Aug 2019 01:00:00 -0700 + +zerotier-one (1.4.2) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Thu, 04 Aug 2019 01:00:00 -0700 + +zerotier-one (1.4.0) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Thu, 29 Jul 2019 01:00:00 -0700 + +zerotier-one (1.2.12) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Tue, 25 Jul 2018 01:00:00 -0700 + +zerotier-one (1.2.10) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Tue, 08 May 2018 01:00:00 -0700 + +zerotier-one (1.2.8) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Tue, 27 Apr 2018 01:00:00 -0700 + +zerotier-one (1.2.6) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Tue, 17 Apr 2018 01:00:00 -0700 + +zerotier-one (1.2.4) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Mon, 24 Mar 2017 01:00:00 -0700 + +zerotier-one (1.2.2) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Fri, 17 Mar 2017 01:00:00 -0700 + +zerotier-one (1.2.0) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Tue, 14 Mar 2017 09:08:00 -0700 + +zerotier-one (1.1.14) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Tue, 21 Jul 2016 07:14:12 -0700 + +zerotier-one (1.1.12) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Tue, 12 Jul 2016 03:02:22 -0700 + +zerotier-one (1.1.10) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + * ZeroTier Debian packages no longer depend on http-parser since its ABI is too unstable. + + -- Adam Ierymenko Tue, 12 Jul 2016 12:29:00 -0700 + +zerotier-one (1.1.8) unstable; urgency=low + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Fri, 08 Jul 2016 01:56:00 -0700 + +zerotier-one (1.1.6) unstable; urgency=medium + + * First Debian release on ZeroTier, Inc. private apt repository. + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Fri, 24 Jun 2016 10:00:00 -0700 + +zerotier-one (1.1.5) UNRELEASED; urgency=medium + + * Development package -- first clean Debian packaging test. + + -- Adam Ierymenko Wed, 08 Jun 2016 10:05:01 -0700 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..9a03714 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..b0c178a --- /dev/null +++ b/debian/control @@ -0,0 +1,19 @@ +Source: zerotier-one +Maintainer: Adam Ierymenko +Section: net +Priority: optional +Standards-Version: 3.9.6 +Build-Depends: debhelper +Vcs-Git: git://github.com/zerotier/ZeroTierOne +Vcs-Browser: https://github.com/zerotier/ZeroTierOne +Homepage: https://www.zerotier.com/ + +Package: zerotier-one +Architecture: any +Depends: adduser, libstdc++6 (>= 5), openssl +Homepage: https://www.zerotier.com/ +Description: ZeroTier network virtualization service + ZeroTier One lets you join ZeroTier virtual networks and + have them appear as tun/tap ports on your system. See + https://www.zerotier.com/ for instructions and + documentation. diff --git a/debian/control.wheezy b/debian/control.wheezy new file mode 100644 index 0000000..fbbc40d --- /dev/null +++ b/debian/control.wheezy @@ -0,0 +1,19 @@ +Source: zerotier-one +Maintainer: Adam Ierymenko +Section: net +Priority: optional +Standards-Version: 3.9.4 +Build-Depends: debhelper +Vcs-Git: git://github.com/zerotier/ZeroTierOne +Vcs-Browser: https://github.com/zerotier/ZeroTierOne +Homepage: https://www.zerotier.com/ + +Package: zerotier-one +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libstdc++6 +Homepage: https://www.zerotier.com/ +Description: ZeroTier network virtualization service + ZeroTier One lets you join ZeroTier virtual networks and + have them appear as tun/tap ports on your system. See + https://www.zerotier.com/ for instructions and + documentation. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..da3678d --- /dev/null +++ b/debian/copyright @@ -0,0 +1,18 @@ +Format: http://dep.debian.net/deps/dep5 +Upstream-Name: zerotier-one +Source: https://github.com/zerotier/ZeroTierOne + +Files: * +Copyright: 2011-2016 ZeroTier, Inc. +License: ZeroTier BSL 1.1 + +License: ZeroTier BSL 1.1 + Copyright (c)2019 ZeroTier, Inc. + + Use of this software is governed by the Business Source License included + in the LICENSE.TXT file in the project's root directory. + + Change Date: 2026-01-01 + + On the date above, in accordance with the Business Source License, use + of this software will be governed by version 2.0 of the Apache License. diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 0000000..b6e7471 --- /dev/null +++ b/debian/postinst @@ -0,0 +1,11 @@ +#!/bin/sh -e + +case "$1" in + configure) + if ! id zerotier-one >>/dev/null 2>&1; then + useradd --system --user-group --home-dir /var/lib/zerotier-one --shell /usr/sbin/nologin --no-create-home zerotier-one + fi + ;; +esac + +#DEBHELPER# diff --git a/debian/rules b/debian/rules new file mode 100644 index 0000000..81fde68 --- /dev/null +++ b/debian/rules @@ -0,0 +1,16 @@ +#!/usr/bin/make -f + +CFLAGS=-O3 -fstack-protector-strong +CXXFLAGS=-O3 -fstack-protector-strong + +%: + dh $@ --with systemd + +override_dh_auto_build: + make + +override_dh_systemd_start: + dh_systemd_start --restart-after-upgrade + +override_dh_installinit: + dh_installinit --name=zerotier-one -- defaults diff --git a/debian/rules.static b/debian/rules.static new file mode 100644 index 0000000..72c5295 --- /dev/null +++ b/debian/rules.static @@ -0,0 +1,16 @@ +#!/usr/bin/make -f + +CFLAGS=-O3 -fstack-protector-strong +CXXFLAGS=-O3 -fstack-protector-strong + +%: + dh $@ --with systemd + +override_dh_auto_build: +# make -j 2 + +override_dh_systemd_start: + dh_systemd_start --restart-after-upgrade + +override_dh_installinit: + dh_installinit --name=zerotier-one -- defaults diff --git a/debian/rules.wheezy b/debian/rules.wheezy new file mode 100644 index 0000000..55e2647 --- /dev/null +++ b/debian/rules.wheezy @@ -0,0 +1,11 @@ +#!/usr/bin/make -f + +CFLAGS=-O3 -fstack-protector +CXXFLAGS=-O3 -fstack-protector + +%: + dh $@ + +override_dh_auto_build: + make -j 2 + diff --git a/debian/rules.wheezy.static b/debian/rules.wheezy.static new file mode 100644 index 0000000..0165be3 --- /dev/null +++ b/debian/rules.wheezy.static @@ -0,0 +1,11 @@ +#!/usr/bin/make -f + +CFLAGS=-O3 -fstack-protector +CXXFLAGS=-O3 -fstack-protector + +%: + dh $@ + +override_dh_auto_build: +# make -j 2 + diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..46ebe02 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) \ No newline at end of file diff --git a/debian/ufw-zerotier-one b/debian/ufw-zerotier-one new file mode 100644 index 0000000..7c29089 --- /dev/null +++ b/debian/ufw-zerotier-one @@ -0,0 +1,4 @@ +[zerotier-one] +title=ZeroTier One +description=A planetary Ethernet switch +ports=9993/udp diff --git a/debian/zerotier-one.init b/debian/zerotier-one.init new file mode 100644 index 0000000..41a22a5 --- /dev/null +++ b/debian/zerotier-one.init @@ -0,0 +1,49 @@ +#!/bin/sh + +### BEGIN INIT INFO +# Provides: zerotier-one +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: +# Short-Description: ZeroTier One network virtualization service +### END INIT INFO + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +DESC="zerotier-one daemon" +NAME=zerotier-one +DAEMON=/usr/sbin/zerotier-one +PIDFILE=/var/lib/zerotier-one/zerotier-one.pid +SCRIPTNAME=/etc/init.d/"$NAME" +EXTRA_OPTS=-d + +test -f $DAEMON || exit 0 + +. /lib/lsb/init-functions + +case "$1" in +start) log_daemon_msg "Starting ZeroTier One" "zerotier-one" + start_daemon -p $PIDFILE $DAEMON $EXTRA_OPTS + log_end_msg $? + ;; +stop) log_daemon_msg "Stopping ZeroTier One" "zerotier-one" + killproc -p $PIDFILE $DAEMON + RETVAL=$? + [ $RETVAL -eq 0 ] && [ -e "$PIDFILE" ] && rm -f $PIDFILE + log_end_msg $RETVAL + ;; +restart) log_daemon_msg "Restarting ZeroTier One" "zerotier-one" + $0 stop + $0 start + ;; +reload|force-reload) log_daemon_msg "Reloading ZeroTier One" "zerotier-one" + log_end_msg 0 + ;; +status) + status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $? + ;; +*) log_action_msg "Usage: /etc/init.d/cron {start|stop|status|restart|reload|force-reload}" + exit 2 + ;; +esac +exit 0 diff --git a/debian/zerotier-one.service b/debian/zerotier-one.service new file mode 100644 index 0000000..9d6a21b --- /dev/null +++ b/debian/zerotier-one.service @@ -0,0 +1,12 @@ +[Unit] +Description=ZeroTier One +After=network-online.target network.target +Wants=network-online.target + +[Service] +ExecStart=/usr/sbin/zerotier-one +Restart=always +KillMode=process + +[Install] +WantedBy=multi-user.target diff --git a/debian/zerotier-one.upstart b/debian/zerotier-one.upstart new file mode 100644 index 0000000..7753580 --- /dev/null +++ b/debian/zerotier-one.upstart @@ -0,0 +1,14 @@ +description "ZeroTier One upstart startup script" + +author "Adam Ierymenko " + +start on (local-filesystems and net-device-up IFACE!=lo) +stop on runlevel [!2345] + +respawn +respawn limit 2 300 + +#pre-start script +#end script + +exec /usr/sbin/zerotier-one diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..681954c --- /dev/null +++ b/doc/README.md @@ -0,0 +1,6 @@ +Manual Pages and Other Documentation +===== + +Use "./build.sh" to build the manual pages. + +You'll need either Node.js/npm installed (script will then automatically install the npm *marked-man* package) or */usr/bin/ronn*. The latter is a Ruby program packaged on some distributions as *rubygem-ronn* or *ruby-ronn* or installable as *gem install ronn*. The Node *marked-man* package and *ronn* from RubyGems are two roughly equivalent alternatives for compiling Markdown into roff/man format. diff --git a/doc/build.sh b/doc/build.sh new file mode 100755 index 0000000..9df72a3 --- /dev/null +++ b/doc/build.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin + +if [ ! -f zerotier-cli.1.md ]; then + echo 'This script must be run from the doc/ subfolder of the ZeroTier tree.' +fi + +rm -f *.1 *.2 *.8 + +if [ -e /usr/bin/ronn -o -e /usr/local/bin/ronn ]; then + # Use 'ronn' which is available as a package on many distros including Debian + ronn -r zerotier-cli.1.md + ronn -r zerotier-idtool.1.md + ronn -r zerotier-one.8.md +else + # Use 'marked-man' from npm + NODE=/usr/bin/node + if [ ! -e $NODE ]; then + if [ -e /usr/bin/nodejs ]; then + NODE=/usr/bin/nodejs + elif [ -e /usr/local/bin/node ]; then + NODE=/usr/local/bin/node + elif [ -e /usr/local/bin/nodejs ]; then + NODE=/usr/local/bin/nodejs + else + echo 'Unable to find ronn or node/npm -- cannot build man pages!' + exit 1 + fi + fi + + if [ ! -f node_modules/marked-man/bin/marked-man ]; then + echo 'Installing npm package "marked-man" -- MarkDown to ROFF converter...' + npm install marked-man + fi + + $NODE node_modules/marked-man/bin/marked-man zerotier-cli.1.md >zerotier-cli.1 + $NODE node_modules/marked-man/bin/marked-man zerotier-idtool.1.md >zerotier-idtool.1 + $NODE node_modules/marked-man/bin/marked-man zerotier-one.8.md >zerotier-one.8 +fi + +exit 0 diff --git a/doc/contact@zerotier.com.gpg b/doc/contact@zerotier.com.gpg new file mode 100644 index 0000000..dc7d645 --- /dev/null +++ b/doc/contact@zerotier.com.gpg @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: GPGTools - https://gpgtools.org + +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 +=JgAv +-----END PGP PUBLIC KEY BLOCK----- diff --git a/doc/manpage_encoding_declaration.UTF-8 b/doc/manpage_encoding_declaration.UTF-8 new file mode 100644 index 0000000..991db0a --- /dev/null +++ b/doc/manpage_encoding_declaration.UTF-8 @@ -0,0 +1 @@ +'\" -*- coding: utf-8 -*- diff --git a/doc/zerotier-cli.1 b/doc/zerotier-cli.1 new file mode 100644 index 0000000..167109e --- /dev/null +++ b/doc/zerotier-cli.1 @@ -0,0 +1,83 @@ +.TH "ZEROTIER\-CLI" "1" "December 2016" "" "" +.SH "NAME" +\fBzerotier-cli\fR \- control local ZeroTier virtual network service +.SH SYNOPSIS +.P +\fBzerotier\-cli\fP [\-switches] [arguments] +.SH DESCRIPTION +.P +\fBzerotier\-cli\fR provides a simple command line interface to the local JSON API of the ZeroTier virtual network endpoint service zerotier\-one(8)\. +.P +By default \fBzerotier\-cli\fR must be run as root or with \fBsudo\fP\|\. If you want to allow an unprivileged user to use \fBzerotier\-cli\fR to control the system ZeroTier service, you can create a local copy of the ZeroTier service authorization token in the user's home directory: +.P +.RS 2 +.nf +sudo cp /var/lib/zerotier\-one/authtoken\.secret /home/user/\.zeroTierOneAuthToken +chown user /home/user/\.zeroTierOneAuthToken +chmod 0600 /home/user/\.zeroTierOneAuthToken +.fi +.RE +.P +(The location of ZeroTier's service home may differ by platform\. See zerotier\-one(8)\.) +.P +Note that this gives the user the power to connect or disconnect the system to or from any virtual network, which is a significant permission\. +.P +\fBzerotier\-cli\fR has several command line arguments that are visible in \fBhelp\fP output\. The two most commonly used are \fB\-j\fP for raw JSON output and \fB\-D\fP to specify an alternative ZeroTier service working directory\. Raw JSON output is easier to parse in scripts and also contains verbose details not present in the tabular output\. The \fB\-D\fP option specifies where the service's zerotier\-one\.port and authtoken\.secret files are located if the service is not running at the default location for your system\. +.SH COMMANDS +.RS 0 +.IP \(bu 2 +\fBhelp\fP: +Displays \fBzerotier\-cli\fR help\. +.IP \(bu 2 +\fBinfo\fP: +Shows information about this device including its 10\-digit ZeroTier address and apparent connection status\. Use \fB\-j\fP for more verbose output\. +.IP \(bu 2 +\fBlistpeers\fP: +This command lists the ZeroTier VL1 (virtual layer 1, the peer to peer network) peers this service knows about and has recently (within the past 30 minutes or so) communicated with\. These are not necessarily all the devices on your virtual network(s), and may also include a few devices not on any virtual network you've joined\. These are typically either root servers or network controllers\. +.IP \(bu 2 +\fBlistnetworks\fP: +This lists the networks your system belongs to and some information about them, such as any ZeroTier\-managed IP addresses you have been assigned\. (IP addresses assigned manually to ZeroTier interfaces will not be listed here\. Use the standard network interface commands to see these\.) +.IP \(bu 2 +\fBjoin\fP: +To join a network just use \fBjoin\fP and its 16\-digit hex network ID\. That's it\. Then use \fBlistnetworks\fP to see the status\. You'll either get a reply from the network controller with a certificate and other info such as IP assignments, or you'll get "access denied\." In this case you'll need the administrator of this network to authorize your device by its 10\-digit device ID (visible with \fBinfo\fP) on the network's controller\. +.IP \(bu 2 +\fBleave\fP: +Leaving a network is as easy as joining it\. This disconnects from the network and deletes its interface from the system\. Note that peers on the network may hang around in \fBlistpeers\fP for up to 30 minutes until they time out due to lack of traffic\. But if they no longer share a network with you, they can't actually communicate with you in any meaningful way\. + +.RE +.SH EXAMPLES +.P +Join "Earth," ZeroTier's big public party line network: +.P +.RS 2 +.nf +$ sudo zerotier\-cli join 8056c2e21c000001 +$ sudo zerotier\-cli listnetworks +( wait until you get an Earth IP ) +$ ping earth\.zerotier\.net +( you should now be able to ping our Earth test IP ) +.fi +.RE +.P +Leave "Earth": +.P +.RS 2 +.nf +$ sudo zerotier\-cli leave 8056c2e21c000001 +.fi +.RE +.P +List VL1 peers: +.P +.RS 2 +.nf +$ sudo zerotier\-cli listpeers +.fi +.RE +.SH COPYRIGHT +.P +(c)2011\-2016 ZeroTier, Inc\. \-\- https://www\.zerotier\.com/ \-\- https://github\.com/zerotier +.SH SEE ALSO +.P +zerotier\-one(8), zerotier\-idtool(1) + diff --git a/doc/zerotier-cli.1.md b/doc/zerotier-cli.1.md new file mode 100644 index 0000000..6252d45 --- /dev/null +++ b/doc/zerotier-cli.1.md @@ -0,0 +1,68 @@ +zerotier-cli(1) -- control local ZeroTier virtual network service +================================================================= + +## SYNOPSIS + +`zerotier-cli` [-switches] [arguments] + +## DESCRIPTION + +**zerotier-cli** provides a simple command line interface to the local JSON API of the ZeroTier virtual network endpoint service zerotier-one(8). + +By default **zerotier-cli** must be run as root or with `sudo`. If you want to allow an unprivileged user to use **zerotier-cli** to control the system ZeroTier service, you can create a local copy of the ZeroTier service authorization token in the user's home directory: + + sudo cp /var/lib/zerotier-one/authtoken.secret /home/user/.zeroTierOneAuthToken + chown user /home/user/.zeroTierOneAuthToken + chmod 0600 /home/user/.zeroTierOneAuthToken + +(The location of ZeroTier's service home may differ by platform. See zerotier-one(8).) + +Note that this gives the user the power to connect or disconnect the system to or from any virtual network, which is a significant permission. + +**zerotier-cli** has several command line arguments that are visible in `help` output. The two most commonly used are `-j` for raw JSON output and `-D` to specify an alternative ZeroTier service working directory. Raw JSON output is easier to parse in scripts and also contains verbose details not present in the tabular output. The `-D` option specifies where the service's zerotier-one.port and authtoken.secret files are located if the service is not running at the default location for your system. + +## COMMANDS + + * `help`: + Displays **zerotier-cli** help. + + * `info`: + Shows information about this device including its 10-digit ZeroTier address and apparent connection status. Use `-j` for more verbose output. + + * `listpeers`: + This command lists the ZeroTier VL1 (virtual layer 1, the peer to peer network) peers this service knows about and has recently (within the past 30 minutes or so) communicated with. These are not necessarily all the devices on your virtual network(s), and may also include a few devices not on any virtual network you've joined. These are typically either root servers or network controllers. + + * `listnetworks`: + This lists the networks your system belongs to and some information about them, such as any ZeroTier-managed IP addresses you have been assigned. (IP addresses assigned manually to ZeroTier interfaces will not be listed here. Use the standard network interface commands to see these.) + + * `join`: + To join a network just use `join` and its 16-digit hex network ID. That's it. Then use `listnetworks` to see the status. You'll either get a reply from the network controller with a certificate and other info such as IP assignments, or you'll get "access denied." In this case you'll need the administrator of this network to authorize your device by its 10-digit device ID (visible with `info`) on the network's controller. + + * `leave`: + Leaving a network is as easy as joining it. This disconnects from the network and deletes its interface from the system. Note that peers on the network may hang around in `listpeers` for up to 30 minutes until they time out due to lack of traffic. But if they no longer share a network with you, they can't actually communicate with you in any meaningful way. + +## EXAMPLES + +Join "Earth," ZeroTier's big public party line network: + + $ sudo zerotier-cli join 8056c2e21c000001 + $ sudo zerotier-cli listnetworks + ( wait until you get an Earth IP ) + $ ping earth.zerotier.net + ( you should now be able to ping our Earth test IP ) + +Leave "Earth": + + $ sudo zerotier-cli leave 8056c2e21c000001 + +List VL1 peers: + + $ sudo zerotier-cli listpeers + +## COPYRIGHT + +(c)2011-2016 ZeroTier, Inc. -- https://www.zerotier.com/ -- https://github.com/zerotier + +## SEE ALSO + +zerotier-one(8), zerotier-idtool(1) diff --git a/doc/zerotier-idtool.1 b/doc/zerotier-idtool.1 new file mode 100644 index 0000000..fbc367a --- /dev/null +++ b/doc/zerotier-idtool.1 @@ -0,0 +1,84 @@ +.TH "ZEROTIER\-IDTOOL" "1" "December 2016" "" "" +.SH "NAME" +\fBzerotier-idtool\fR \- tool for creating and manipulating ZeroTier identities +.SH SYNOPSIS +.P +\fBzerotier\-idtool\fP [args] +.SH DESCRIPTION +.P +\fBzerotier\-idtool\fR is a command line utility for doing things with ZeroTier identities\. A ZeroTier identity consists of a public/private key pair (or just the public if it's only an identity\.public) and a 10\-digit hexadecimal ZeroTier address derived from the public key by way of a proof of work based hash function\. +.SH COMMANDS +.P +When command arguments call for a public or secret (full) identity, the identity can be specified as a path to a file or directly on the command line\. +.RS 0 +.IP \(bu 2 +\fBhelp\fP: +Display help\. (Also running with no command does this\.) +.IP \(bu 2 +\fBgenerate\fP [secret file] [public file] [vanity]: +Generate a new ZeroTier identity\. If a secret file is specified, the full identity including the private key will be written to this file\. If the public file is specified, the public portion will be written there\. If no file paths are specified the full secret identity is output to STDOUT\. The vanity prefix is a series of hexadecimal digits that the generated identity's address should start with\. Typically this isn't used, and if it's specified generation can take a very long time due to the intrinsic cost of generating identities with their proof of work function\. Generating an identity with a known 16\-bit (4 digit) prefix on a 2\.8ghz Core i5 (using one core) takes an average of two hours\. +.IP \(bu 2 +\fBvalidate\fP : +Locally validate an identity's key and proof of work function correspondence\. +.IP \(bu 2 +\fBgetpublic\fP : +Extract the public portion of an identity\.secret and print to STDOUT\. +.IP \(bu 2 +\fBsign\fP : +Sign a file's contents with SHA512+ECC\-256 (ed25519)\. The signature is output in hex to STDOUT\. +.IP \(bu 2 +\fBverify\fP : +Verify a signature created with \fBsign\fP\|\. +.IP \(bu 2 +\fBmkcom\fP [id,value,maxdelta] [\|\.\.\.]: +Create and sign a network membership certificate\. This is not generally useful since network controllers do this automatically and is included mostly for testing purposes\. + +.RE +.SH EXAMPLES +.P +Generate and dump a new identity: +.P +.RS 2 +.nf +$ zerotier\-idtool generate +.fi +.RE +.P +Generate and write a new identity, both secret and public parts: +.P +.RS 2 +.nf +$ zerotier\-idtool generate identity\.secret identity\.public +.fi +.RE +.P +Generate a vanity address that begins with the hex digits "beef" (this will take a while!): +.P +.RS 2 +.nf +$ zerotier\-idtool generate beef\.secret beef\.public beef +.fi +.RE +.P +Sign a file with an identity's secret key: +.P +.RS 2 +.nf +$ zerotier\-idtool sign identity\.secret last_will_and_testament\.txt +.fi +.RE +.P +Verify a file's signature with a public key: +.P +.RS 2 +.nf +$ zerotier\-idtool verify identity\.public last_will_and_testament\.txt +.fi +.RE +.SH COPYRIGHT +.P +(c)2011\-2016 ZeroTier, Inc\. \-\- https://www\.zerotier\.com/ \-\- https://github\.com/zerotier +.SH SEE ALSO +.P +zerotier\-one(8), zerotier\-cli(1) + diff --git a/doc/zerotier-idtool.1.md b/doc/zerotier-idtool.1.md new file mode 100644 index 0000000..52a586c --- /dev/null +++ b/doc/zerotier-idtool.1.md @@ -0,0 +1,65 @@ +zerotier-idtool(1) -- tool for creating and manipulating ZeroTier identities +============================================================================ + +## SYNOPSIS + +`zerotier-idtool` [args] + +## DESCRIPTION + +**zerotier-idtool** is a command line utility for doing things with ZeroTier identities. A ZeroTier identity consists of a public/private key pair (or just the public if it's only an identity.public) and a 10-digit hexadecimal ZeroTier address derived from the public key by way of a proof of work based hash function. + +## COMMANDS + +When command arguments call for a public or secret (full) identity, the identity can be specified as a path to a file or directly on the command line. + + * `help`: + Display help. (Also running with no command does this.) + + * `generate` [secret file] [public file] [vanity]: + Generate a new ZeroTier identity. If a secret file is specified, the full identity including the private key will be written to this file. If the public file is specified, the public portion will be written there. If no file paths are specified the full secret identity is output to STDOUT. The vanity prefix is a series of hexadecimal digits that the generated identity's address should start with. Typically this isn't used, and if it's specified generation can take a very long time due to the intrinsic cost of generating identities with their proof of work function. Generating an identity with a known 16-bit (4 digit) prefix on a 2.8ghz Core i5 (using one core) takes an average of two hours. + + * `validate` : + Locally validate an identity's key and proof of work function correspondence. + + * `getpublic` : + Extract the public portion of an identity.secret and print to STDOUT. + + * `sign` : + Sign a file's contents with SHA512+ECC-256 (ed25519). The signature is output in hex to STDOUT. + + * `verify` : + Verify a signature created with `sign`. + + * `mkcom` [id,value,maxdelta] [...]: + Create and sign a network membership certificate. This is not generally useful since network controllers do this automatically and is included mostly for testing purposes. + +## EXAMPLES + +Generate and dump a new identity: + + $ zerotier-idtool generate + +Generate and write a new identity, both secret and public parts: + + $ zerotier-idtool generate identity.secret identity.public + +Generate a vanity address that begins with the hex digits "beef" (this will take a while!): + + $ zerotier-idtool generate beef.secret beef.public beef + +Sign a file with an identity's secret key: + + $ zerotier-idtool sign identity.secret last_will_and_testament.txt + +Verify a file's signature with a public key: + + $ zerotier-idtool verify identity.public last_will_and_testament.txt + +## COPYRIGHT + +(c)2011-2016 ZeroTier, Inc. -- https://www.zerotier.com/ -- https://github.com/zerotier + +## SEE ALSO + +zerotier-one(8), zerotier-cli(1) diff --git a/doc/zerotier-one.8 b/doc/zerotier-one.8 new file mode 100644 index 0000000..4ad7a15 --- /dev/null +++ b/doc/zerotier-one.8 @@ -0,0 +1,104 @@ +.TH "ZEROTIER\-ONE" "8" "December 2016" "" "" +.SH "NAME" +\fBzerotier-one\fR \- ZeroTier virtual network endpoint service +.SH SYNOPSIS +.P +\fBzerotier\-one\fP [\-switches] [working directory] +.SH DESCRIPTION +.P +\fBzerotier\-one\fR is the service/daemon responsible for connecting a Unix (Linux/BSD/OSX) system to one or more ZeroTier virtual networks and presenting those networks to the system as virtual network ports\. You can think of it as a peer to peer VPN client\. +.P +It's typically run by init systems like systemd (Linux) or launchd (Mac) rather than directly by the user, and it must be run as root unless you give it the \fB\-U\fP switch and don't plan on actually joining networks (e\.g\. to run a network controller microservice only)\. +.P +The \fBzerotier\-one\fR service keeps its state and other files in a working directory\. If this directory is not specified at launch it defaults to "/var/lib/zerotier\-one" on Linux, "/Library/Application Support/ZeroTier/One" on Mac, and "/var/db/zerotier\-one" on FreeBSD and other similar BSDs\. The working directory should persist\. It shouldn't be automatically cleaned by system cleanup daemons or stored in a volatile location\. Loss of its identity\.secret file results in loss of this system's unique 10\-digit ZeroTier address and key\. +.P +Multiple instances of \fBzerotier\-one\fR can be run on the same system as long as they are run with different primary ports (see switches) and a different working directory\. But since a single service can join any number of networks, typically there's no point in doing this\. +.P +The \fBzerotier\-one\fR service is controlled via a JSON API available at 127\.0\.0\.1: with the default primary port being 9993\. Access to this API requires an authorization token normally found in the authtoken\.secret file in the service's working directory\. On some platforms access may be guarded by other measures such as socket peer UID/GID lookup if additional security options are enabled (this is not the default)\. +.P +The first time the service is started in a fresh working directory, it generates a ZeroTier identity\. On slow systems this process can take ten seconds or more due to an anti\-DDOS/anti\-counterfeit proof of work function used by ZeroTier in address generation\. This only happens once, and once generated the result is saved in identity\.secret in the working directory\. This file represents and defines/claims your ZeroTier address and associated ECC\-256 key pair\. +.SH SWITCHES +.RS 0 +.IP \(bu 2 +\fB\-h\fP: +Display help\. +.IP \(bu 2 +\fB\-v\fP: +Display ZeroTier One version\. +.IP \(bu 2 +\fB\-U\fP: +Skip privilege check and allow to be run by non\-privileged user\. This is typically used when \fBzerotier\-one\fR is built with the network controller option included\. In this case the ZeroTier service might only be acting as a network controller and might never actually join networks, in which case it does not require elevated system permissions\. +.IP \(bu 2 +\fB\-p\fP: +Specify a different primary port\. If this is not given the default is 9993\. If zero is given a random port is chosen each time\. +.IP \(bu 2 +\fB\-d\fP: +Fork and run as a daemon\. +.IP \(bu 2 +\fB\-i\fP: +Invoke the \fBzerotier\-idtool\fR personality, in which case the binary behaves like zerotier\-idtool(1)\. This happens automatically if the name of the binary (or a symlink to it) is zerotier\-idtool\. +.IP \(bu 2 +\fB\-q\fP: +Invoke the \fBzerotier\-cli\fR personality, in which case the binary behaves like zerotier\-cli(1)\. This happens automatically if the name of the binary (or a symlink to it) is zerotier\-cli\. + +.RE +.SH EXAMPLES +.P +Run as daemon with OS default working directory and default port: +.P +.RS 2 +.nf +$ sudo zerotier\-one \-d +.fi +.RE +.P +Run as daemon with a different working directory and port: +.P +.RS 2 +.nf +$ sudo zerotier\-one \-d \-p12345 /tmp/zerotier\-working\-directory\-test +.fi +.RE +.SH FILES +.P +These are found in the service's working directory\. +.RS 0 +.IP \(bu 2 +\fBidentity\.public\fP: +The public portion of your ZeroTier identity, which is your 10\-digit hex address and the associated public key\. +.IP \(bu 2 +\fBidentity\.secret\fP: +Your full ZeroTier identity including its private key\. This file identifies the system on the network, which means you can move a ZeroTier address around by copying this file and you should back up this file if you want to save your system's static ZeroTier address\. This file must be protected, since theft of its secret key will allow anyone to impersonate your device on any network and decrypt traffic\. For network controllers this file is particularly sensitive since it constitutes the private key for a certificate authority for the controller's networks\. +.IP \(bu 2 +\fBauthtoken\.secret\fP: +The secret token used to authenticate requests to the service's local JSON API\. If it does not exist it is generated from a secure random source on service start\. To use, send it in the "X\-ZT1\-Auth" header with HTTP requests to 127\.0\.0\.1:\|\. +.IP \(bu 2 +\fBdevicemap\fP: +Remembers mappings of zt# interface numbers to ZeroTier networks so they'll persist across restarts\. On some systems that support longer interface names that can encode the network ID (such as FreeBSD) this file may not be present\. +.IP \(bu 2 +\fBzerotier\-one\.pid\fP: +ZeroTier's PID\. This file is deleted on normal shutdown\. +.IP \(bu 2 +\fBzerotier\-one\.port\fP: +ZeroTier's primary port, which is also where its JSON API is found at 127\.0\.0\.1:\|\. This file is created on startup and is read by zerotier\-cli(1) to determine where it should find the control API\. +.IP \(bu 2 +\fBcontroller\.db\fP: +If the ZeroTier One service is built with the network controller enabled, this file contains the controller's SQLite3 database\. +.IP \(bu 2 +\fBcontroller\.db\.backup\fP: +If the ZeroTier One service is built with the network controller enabled, it periodically backs up its controller\.db database in this file (currently every 5 minutes if there have been changes)\. Since this file is not a currently in use SQLite3 database it's safer to back up without corruption\. On new backups the file is rotated out rather than being rewritten in place\. +.IP \(bu 2 +\fBiddb\.d/\fP (directory): +Caches the public identity of every peer ZeroTier has spoken with in the last 60 days\. This directory and its contents can be deleted, but this may result in slower connection initations since it will require that we go out and re\-fetch full identities for peers we're speaking to\. +.IP \(bu 2 +\fBnetworks\.d\fP (directory): +This caches network configurations and certificate information for networks you belong to\. ZeroTier scans this directory for \|\.conf files on startup to recall its networks, so "touch"ing an empty \|\.conf file in this directory is a way of pre\-configuring ZeroTier to join a specific network on startup without using the API\. If the config file is empty ZeroTIer will just fetch it from the network's controller\. + +.RE +.SH COPYRIGHT +.P +(c)2011\-2016 ZeroTier, Inc\. \-\- https://www\.zerotier\.com/ \-\- https://github\.com/zerotier +.SH SEE ALSO +.P +zerotier\-cli(1), zerotier\-idtool(1) + diff --git a/doc/zerotier-one.8.md b/doc/zerotier-one.8.md new file mode 100644 index 0000000..4f46550 --- /dev/null +++ b/doc/zerotier-one.8.md @@ -0,0 +1,95 @@ +zerotier-one(8) -- ZeroTier virtual network endpoint service +============================================================ + +## SYNOPSIS + +`zerotier-one` [-switches] [working directory] + +## DESCRIPTION + +**zerotier-one** is the service/daemon responsible for connecting a Unix (Linux/BSD/OSX) system to one or more ZeroTier virtual networks and presenting those networks to the system as virtual network ports. You can think of it as a peer to peer VPN client. + +It's typically run by init systems like systemd (Linux) or launchd (Mac) rather than directly by the user, and it must be run as root unless you give it the `-U` switch and don't plan on actually joining networks (e.g. to run a network controller microservice only). + +The **zerotier-one** service keeps its state and other files in a working directory. If this directory is not specified at launch it defaults to "/var/lib/zerotier-one" on Linux, "/Library/Application Support/ZeroTier/One" on Mac, and "/var/db/zerotier-one" on FreeBSD and other similar BSDs. The working directory should persist. It shouldn't be automatically cleaned by system cleanup daemons or stored in a volatile location. Loss of its identity.secret file results in loss of this system's unique 10-digit ZeroTier address and key. + +Multiple instances of **zerotier-one** can be run on the same system as long as they are run with different primary ports (see switches) and a different working directory. But since a single service can join any number of networks, typically there's no point in doing this. + +The **zerotier-one** service is controlled via a JSON API available at 127.0.0.1: with the default primary port being 9993. Access to this API requires an authorization token normally found in the authtoken.secret file in the service's working directory. On some platforms access may be guarded by other measures such as socket peer UID/GID lookup if additional security options are enabled (this is not the default). + +The first time the service is started in a fresh working directory, it generates a ZeroTier identity. On slow systems this process can take ten seconds or more due to an anti-DDOS/anti-counterfeit proof of work function used by ZeroTier in address generation. This only happens once, and once generated the result is saved in identity.secret in the working directory. This file represents and defines/claims your ZeroTier address and associated ECC-256 key pair. + +## SWITCHES + + * `-h`: + Display help. + + * `-v`: + Display ZeroTier One version. + + * `-U`: + Skip privilege check and allow to be run by non-privileged user. This is typically used when **zerotier-one** is built with the network controller option included. In this case the ZeroTier service might only be acting as a network controller and might never actually join networks, in which case it does not require elevated system permissions. + + * `-p`: + Specify a different primary port. If this is not given the default is 9993. If zero is given a random port is chosen each time. + + * `-d`: + Fork and run as a daemon. + + * `-i`: + Invoke the **zerotier-idtool** personality, in which case the binary behaves like zerotier-idtool(1). This happens automatically if the name of the binary (or a symlink to it) is zerotier-idtool. + + * `-q`: + Invoke the **zerotier-cli** personality, in which case the binary behaves like zerotier-cli(1). This happens automatically if the name of the binary (or a symlink to it) is zerotier-cli. + +## EXAMPLES + +Run as daemon with OS default working directory and default port: + + $ sudo zerotier-one -d + +Run as daemon with a different working directory and port: + + $ sudo zerotier-one -d -p12345 /tmp/zerotier-working-directory-test + +## FILES + +These are found in the service's working directory. + + * `identity.public`: + The public portion of your ZeroTier identity, which is your 10-digit hex address and the associated public key. + + * `identity.secret`: + Your full ZeroTier identity including its private key. This file identifies the system on the network, which means you can move a ZeroTier address around by copying this file and you should back up this file if you want to save your system's static ZeroTier address. This file must be protected, since theft of its secret key will allow anyone to impersonate your device on any network and decrypt traffic. For network controllers this file is particularly sensitive since it constitutes the private key for a certificate authority for the controller's networks. + + * `authtoken.secret`: + The secret token used to authenticate requests to the service's local JSON API. If it does not exist it is generated from a secure random source on service start. To use, send it in the "X-ZT1-Auth" header with HTTP requests to 127.0.0.1:. + + * `devicemap`: + Remembers mappings of zt# interface numbers to ZeroTier networks so they'll persist across restarts. On some systems that support longer interface names that can encode the network ID (such as FreeBSD) this file may not be present. + + * `zerotier-one.pid`: + ZeroTier's PID. This file is deleted on normal shutdown. + + * `zerotier-one.port`: + ZeroTier's primary port, which is also where its JSON API is found at 127.0.0.1:. This file is created on startup and is read by zerotier-cli(1) to determine where it should find the control API. + + * `controller.db`: + If the ZeroTier One service is built with the network controller enabled, this file contains the controller's SQLite3 database. + + * `controller.db.backup`: + If the ZeroTier One service is built with the network controller enabled, it periodically backs up its controller.db database in this file (currently every 5 minutes if there have been changes). Since this file is not a currently in use SQLite3 database it's safer to back up without corruption. On new backups the file is rotated out rather than being rewritten in place. + + * `iddb.d/` (directory): + Caches the public identity of every peer ZeroTier has spoken with in the last 60 days. This directory and its contents can be deleted, but this may result in slower connection initiations since it will require that we go out and re-fetch full identities for peers we're speaking to. + + * `networks.d` (directory): + This caches network configurations and certificate information for networks you belong to. ZeroTier scans this directory for .conf files on startup to recall its networks, so "touch"ing an empty .conf file in this directory is a way of pre-configuring ZeroTier to join a specific network on startup without using the API. If the config file is empty ZeroTIer will just fetch it from the network's controller. + +## COPYRIGHT + +(c)2011-2016 ZeroTier, Inc. -- https://www.zerotier.com/ -- https://github.com/zerotier + +## SEE ALSO + +zerotier-cli(1), zerotier-idtool(1) diff --git a/entrypoint.sh.release b/entrypoint.sh.release new file mode 100644 index 0000000..284a3d4 --- /dev/null +++ b/entrypoint.sh.release @@ -0,0 +1,124 @@ +#!/bin/sh + +grepzt() { + [ -f /var/lib/zerotier-one/zerotier-one.pid -a -n "$(cat /var/lib/zerotier-one/zerotier-one.pid 2>/dev/null)" -a -d "/proc/$(cat /var/lib/zerotier-one/zerotier-one.pid 2>/dev/null)" ] + return $? +} + +mkztfile() { + file=$1 + mode=$2 + content=$3 + + mkdir -p /var/lib/zerotier-one + echo "$content" > "/var/lib/zerotier-one/$file" + chmod "$mode" "/var/lib/zerotier-one/$file" +} + +if [ "x$ZEROTIER_API_SECRET" != "x" ] +then + mkztfile authtoken.secret 0600 "$ZEROTIER_API_SECRET" +fi + +if [ "x$ZEROTIER_IDENTITY_PUBLIC" != "x" ] +then + mkztfile identity.public 0644 "$ZEROTIER_IDENTITY_PUBLIC" +fi + +if [ "x$ZEROTIER_IDENTITY_SECRET" != "x" ] +then + mkztfile identity.secret 0600 "$ZEROTIER_IDENTITY_SECRET" +fi + +mkztfile zerotier-one.port 0600 "9993" + +killzerotier() { + log "Killing zerotier" + kill $(cat /var/lib/zerotier-one/zerotier-one.pid 2>/dev/null) + exit 0 +} + +log_header() { + echo -n "\r=>" +} + +log_detail_header() { + echo -n "\r===>" +} + +log() { + echo "$(log_header)" "$@" +} + +log_params() { + title=$1 + shift + log "$title" "[$@]" +} + +log_detail() { + echo "$(log_detail_header)" "$@" +} + +log_detail_params() { + title=$1 + shift + log_detail "$title" "[$@]" +} + +trap killzerotier INT TERM + +log "Configuring networks to join" +mkdir -p /var/lib/zerotier-one/networks.d + +log_params "Joining networks from command line:" $@ +for i in "$@" +do + log_detail_params "Configuring join:" "$i" + touch "/var/lib/zerotier-one/networks.d/${i}.conf" +done + +if [ "x$ZEROTIER_JOIN_NETWORKS" != "x" ] +then + log_params "Joining networks from environment:" $ZEROTIER_JOIN_NETWORKS + for i in $ZEROTIER_JOIN_NETWORKS + do + log_detail_params "Configuring join:" "$i" + touch "/var/lib/zerotier-one/networks.d/${i}.conf" + done +fi + +log "Starting ZeroTier" +nohup /usr/sbin/zerotier-one & + +while ! grepzt +do + log_detail "ZeroTier hasn't started, waiting a second" + + if [ -f nohup.out ] + then + tail -n 10 nohup.out + fi + + sleep 1 +done + +log_params "Writing healthcheck for networks:" $@ + +cat >/healthcheck.sh < +#include +#define zt_arm_has_neon() ((getauxval(AT_HWCAP) & HWCAP_NEON) != 0) +#elif defined(__ARM_NEON__) || defined(__ARM_NEON) +#define zt_arm_has_neon() (true) +#else +#define zt_arm_has_neon() (false) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// ciphertext buffer, message/NULL, length, nonce (8 bytes), key (32 bytes) +extern int zt_salsa2012_armneon3_xor(unsigned char *c,const unsigned char *m,unsigned long long len,const unsigned char *n,const unsigned char *k); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/arm32-neon-salsa2012-asm/salsa2012.s b/ext/arm32-neon-salsa2012-asm/salsa2012.s new file mode 100644 index 0000000..9e5989c --- /dev/null +++ b/ext/arm32-neon-salsa2012-asm/salsa2012.s @@ -0,0 +1,2231 @@ + +# qhasm: int32 input_0 + +# qhasm: int32 input_1 + +# qhasm: int32 input_2 + +# qhasm: int32 input_3 + +# qhasm: stack32 input_4 + +# qhasm: stack32 input_5 + +# qhasm: stack32 input_6 + +# qhasm: stack32 input_7 + +# qhasm: int32 caller_r4 + +# qhasm: int32 caller_r5 + +# qhasm: int32 caller_r6 + +# qhasm: int32 caller_r7 + +# qhasm: int32 caller_r8 + +# qhasm: int32 caller_r9 + +# qhasm: int32 caller_r10 + +# qhasm: int32 caller_r11 + +# qhasm: int32 caller_r14 + +# qhasm: reg128 caller_q4 + +# qhasm: reg128 caller_q5 + +# qhasm: reg128 caller_q6 + +# qhasm: reg128 caller_q7 + +# qhasm: startcode +.fpu neon +.text + +# qhasm: constant sigma: +.align 2 +sigma: + +# qhasm: const32 1634760805 +.word 1634760805 + +# qhasm: const32 857760878 +.word 857760878 + +# qhasm: const32 2036477234 +.word 2036477234 + +# qhasm: const32 1797285236 +.word 1797285236 + +# qhasm: int128 abab + +# qhasm: int128 diag0 + +# qhasm: int128 diag1 + +# qhasm: int128 diag2 + +# qhasm: int128 diag3 + +# qhasm: int128 a0 + +# qhasm: int128 a1 + +# qhasm: int128 a2 + +# qhasm: int128 a3 + +# qhasm: int128 b0 + +# qhasm: int128 b1 + +# qhasm: int128 b2 + +# qhasm: int128 b3 + +# qhasm: int128 next_diag0 + +# qhasm: int128 next_diag1 + +# qhasm: int128 next_diag2 + +# qhasm: int128 next_diag3 + +# qhasm: int128 next_a0 + +# qhasm: int128 next_a1 + +# qhasm: int128 next_a2 + +# qhasm: int128 next_a3 + +# qhasm: int128 next_b0 + +# qhasm: int128 next_b1 + +# qhasm: int128 next_b2 + +# qhasm: int128 next_b3 + +# qhasm: int128 x0x5x10x15 + +# qhasm: int128 x12x1x6x11 + +# qhasm: int128 x8x13x2x7 + +# qhasm: int128 x4x9x14x3 + +# qhasm: int128 x0x1x10x11 + +# qhasm: int128 x12x13x6x7 + +# qhasm: int128 x8x9x2x3 + +# qhasm: int128 x4x5x14x15 + +# qhasm: int128 x0x1x2x3 + +# qhasm: int128 x4x5x6x7 + +# qhasm: int128 x8x9x10x11 + +# qhasm: int128 x12x13x14x15 + +# qhasm: int128 m0m1m2m3 + +# qhasm: int128 m4m5m6m7 + +# qhasm: int128 m8m9m10m11 + +# qhasm: int128 m12m13m14m15 + +# qhasm: int128 start0 + +# qhasm: int128 start1 + +# qhasm: int128 start2 + +# qhasm: int128 start3 + +# qhasm: stack128 stack_start3 + +# qhasm: stack128 next_start2 + +# qhasm: stack128 next_start3 + +# qhasm: int128 k0k1k2k3 + +# qhasm: int128 k4k5k6k7 + +# qhasm: int128 k1n1k7k2 + +# qhasm: int128 n2n3n3n2 + +# qhasm: int128 k2k3k6k7 + +# qhasm: int128 nextblock + +# qhasm: stack128 stack_q4 + +# qhasm: stack128 stack_q5 + +# qhasm: stack128 stack_q6 + +# qhasm: stack128 stack_q7 + +# qhasm: stack32 stack_r4 + +# qhasm: stack128 k2k3k6k7_stack + +# qhasm: stack128 k1n1k7k2_stack + +# qhasm: stack512 tmp + +# qhasm: stack32 savec + +# qhasm: int32 i + +# qhasm: int32 ci + +# qhasm: int32 mi + +# qhasm: enter zt_salsa2012_armneon3_xor +.align 2 +.global _zt_salsa2012_armneon3_xor +.global zt_salsa2012_armneon3_xor +.type _zt_salsa2012_armneon3_xor STT_FUNC +.type zt_salsa2012_armneon3_xor STT_FUNC +_zt_salsa2012_armneon3_xor: +zt_salsa2012_armneon3_xor: +sub sp,sp,#256 + +# qhasm: new stack_q4 + +# qhasm: new stack_q5 + +# qhasm: new stack_q6 + +# qhasm: new stack_q7 + +# qhasm: stack_q4 bot = caller_q4 bot +# asm 1: vstr stack_r4=stack32#2 +# asm 2: str stack_r4=[sp,#68] +str r4,[sp,#68] + +# qhasm: int32 c + +# qhasm: c = input_0 +# asm 1: mov >c=int32#1,c=r0,m=int32#2,m=r1,mlenlow=int32#3,mlenlow=r2,mlenhigh=int32#4,mlenhigh=r3,n=int32#5,n=r4,k=int32#13,k=r12,k0k1k2k3=reg128#1%bot->k0k1k2k3=reg128#1%top},[k0k1k2k3=d0->k0k1k2k3=d1},[k4k5k6k7=reg128#2%bot->k4k5k6k7=reg128#2%top},[k4k5k6k7=d2->k4k5k6k7=d3},[i=int32#13,=sigma +# asm 2: ldr >i=r12,=sigma +ldr r12,=sigma + +# qhasm: start0 = mem128[i] +# asm 1: vld1.8 {>start0=reg128#3%bot->start0=reg128#3%top},[start0=d4->start0=d5},[start1=reg128#4,#0 +# asm 2: vmov.i64 >start1=q3,#0 +vmov.i64 q3,#0 + +# qhasm: start1 bot = mem64[n] +# asm 1: vld1.8 {k2k3k6k7=reg128#6,k2k3k6k7=q5,n2n3n3n2=reg128#1,#0 +# asm 2: vmov.i64 >n2n3n3n2=q0,#0 +vmov.i64 q0,#0 + +# qhasm: unsigneddiag0=reg128#8,diag0=q7,diag1=reg128#9,diag1=q8,start2=reg128#10,start2=q9,nextblock=reg128#11,#0xff +# asm 2: vmov.i64 >nextblock=q10,#0xff +vmov.i64 q10,#0xff + +# qhasm: 4x nextblock unsigned>>= 7 +# asm 1: vshr.u32 >nextblock=reg128#11,nextblock=q10,n2n3n3n2=reg128#1,n2n3n3n2=q0,n2n3n3n2=reg128#1,n2n3n3n2=q0,next_diag0=reg128#2,next_diag0=q1,next_diag1=reg128#5,next_diag1=q4,i=int32#5,=12 +# asm 2: ldr >i=r4,=12 +ldr r4,=12 + +# qhasm: mainloop2: +._mainloop2: + +# qhasm: 4x a0 = diag1 + diag0 +# asm 1: vadd.i32 >a0=reg128#11,a0=q10,next_a0=reg128#14,next_a0=q13,b0=reg128#15,b0=q14,next_b0=reg128#16,next_b0=q15,> 25 +# asm 1: vsri.i32 > 25 +# asm 1: vsri.i32 diag3=reg128#7,diag3=q6,next_diag3=reg128#11,next_diag3=q10,a1=reg128#13,a1=q12,next_a1=reg128#14,next_a1=q13,b1=reg128#15,b1=q14,next_b1=reg128#16,next_b1=q15,> 23 +# asm 1: vsri.i32 > 23 +# asm 1: vsri.i32 diag2=reg128#6,diag2=q5,next_diag2=reg128#12,next_diag2=q11,a2=reg128#13,a2=q12,diag3=reg128#7,diag3=q6,next_a2=reg128#14,next_a2=q13,b2=reg128#15,b2=q14,next_diag3=reg128#11,next_diag3=q10,next_b2=reg128#16,next_b2=q15,> 19 +# asm 1: vsri.i32 > 19 +# asm 1: vsri.i32 diag1=reg128#9,diag1=q8,next_diag1=reg128#5,next_diag1=q4,a3=reg128#13,a3=q12,next_a3=reg128#14,next_a3=q13,b3=reg128#15,b3=q14,next_b3=reg128#16,next_b3=q15,> 14 +# asm 1: vsri.i32 diag1=reg128#9,diag1=q8,> 14 +# asm 1: vsri.i32 diag0=reg128#8,diag0=q7,next_diag1=reg128#5,next_diag1=q4,next_diag0=reg128#2,next_diag0=q1,a0=reg128#13,a0=q12,next_a0=reg128#14,next_a0=q13,b0=reg128#15,b0=q14,next_b0=reg128#16,next_b0=q15,> 25 +# asm 1: vsri.i32 > 25 +# asm 1: vsri.i32 diag1=reg128#9,diag1=q8,next_diag1=reg128#5,next_diag1=q4,a1=reg128#13,a1=q12,next_a1=reg128#14,next_a1=q13,b1=reg128#15,b1=q14,next_b1=reg128#16,next_b1=q15,> 23 +# asm 1: vsri.i32 ? i -= 2 +# asm 1: subs > 23 +# asm 1: vsri.i32 diag2=reg128#6,diag2=q5,next_diag2=reg128#12,next_diag2=q11,a2=reg128#13,a2=q12,diag1=reg128#9,diag1=q8,next_a2=reg128#14,next_a2=q13,b2=reg128#15,b2=q14,next_diag1=reg128#5,next_diag1=q4,next_b2=reg128#16,next_b2=q15,> 19 +# asm 1: vsri.i32 > 19 +# asm 1: vsri.i32 diag3=reg128#7,diag3=q6,next_diag3=reg128#11,next_diag3=q10,a3=reg128#13,a3=q12,next_a3=reg128#14,next_a3=q13,b3=reg128#15,b3=q14,next_b3=reg128#16,next_b3=q15,> 14 +# asm 1: vsri.i32 diag3=reg128#7,diag3=q6,> 14 +# asm 1: vsri.i32 diag0=reg128#8,diag0=q7,next_diag3=reg128#13,next_diag3=q12,next_diag0=reg128#2,next_diag0=q1, +bhi ._mainloop2 + +# qhasm: 2x abab = 0xffffffff +# asm 1: vmov.i64 >abab=reg128#11,#0xffffffff +# asm 2: vmov.i64 >abab=q10,#0xffffffff +vmov.i64 q10,#0xffffffff + +# qhasm: new x4x9x14x3 + +# qhasm: x4x9x14x3 bot = stack_start3 bot +# asm 1: vldr x0x5x10x15=reg128#8,x0x5x10x15=q7,x12x1x6x11=reg128#9,x12x1x6x11=q8,x8x13x2x7=reg128#6,x8x13x2x7=q5,x4x9x14x3=reg128#7,x4x9x14x3=q6,x0x1x10x11=reg128#10,x0x1x10x11=q9,x12x13x6x7=reg128#14,x12x13x6x7=q13,x8x9x2x3=reg128#15,x8x9x2x3=q14,x4x5x14x15=reg128#16,x4x5x14x15=q15,x0x1x2x3=reg128#6,x0x1x2x3=q5,x4x5x6x7=reg128#7,x4x5x6x7=q6,x8x9x10x11=reg128#8,x8x9x10x11=q7,x12x13x14x15=reg128#9,x12x13x14x15=q8,m0m1m2m3=reg128#10%bot->m0m1m2m3=reg128#10%top},[m0m1m2m3=d18->m0m1m2m3=d19},[m4m5m6m7=reg128#14%bot->m4m5m6m7=reg128#14%top},[m4m5m6m7=d26->m4m5m6m7=d27},[m8m9m10m11=reg128#15%bot->m8m9m10m11=reg128#15%top},[m8m9m10m11=d28->m8m9m10m11=d29},[m12m13m14m15=reg128#16%bot->m12m13m14m15=reg128#16%top},[m12m13m14m15=d30->m12m13m14m15=d31},[x0x1x2x3=reg128#6,x0x1x2x3=q5,x4x5x6x7=reg128#7,x4x5x6x7=q6,x8x9x10x11=reg128#8,x8x9x10x11=q7,x12x13x14x15=reg128#9,x12x13x14x15=q8,x0x5x10x15=reg128#2,x0x5x10x15=q1,x12x1x6x11=reg128#5,x12x1x6x11=q4,x8x13x2x7=reg128#6,x8x13x2x7=q5,x4x9x14x3=reg128#7,x4x9x14x3=q6,x0x1x10x11=reg128#8,x0x1x10x11=q7,x12x13x6x7=reg128#9,x12x13x6x7=q8,x8x9x2x3=reg128#10,x8x9x2x3=q9,x4x5x14x15=reg128#12,x4x5x14x15=q11,x0x1x2x3=reg128#2,x0x1x2x3=q1,x4x5x6x7=reg128#5,x4x5x6x7=q4,x8x9x10x11=reg128#6,x8x9x10x11=q5,x12x13x14x15=reg128#7,x12x13x14x15=q6,m0m1m2m3=reg128#8%bot->m0m1m2m3=reg128#8%top},[m0m1m2m3=d14->m0m1m2m3=d15},[m4m5m6m7=reg128#9%bot->m4m5m6m7=reg128#9%top},[m4m5m6m7=d16->m4m5m6m7=d17},[m8m9m10m11=reg128#10%bot->m8m9m10m11=reg128#10%top},[m8m9m10m11=d18->m8m9m10m11=d19},[m12m13m14m15=reg128#11%bot->m12m13m14m15=reg128#11%top},[m12m13m14m15=d20->m12m13m14m15=d21},[x0x1x2x3=reg128#2,x0x1x2x3=q1,x4x5x6x7=reg128#5,x4x5x6x7=q4,x8x9x10x11=reg128#6,x8x9x10x11=q5,x12x13x14x15=reg128#7,x12x13x14x15=q6,? mlenhigh - 0 +# asm 1: cmp +bhi ._mlenatleast128 + +# qhasm: =? mlenlow - 0 +# asm 1: cmp savec=stack32#1 +# asm 2: str savec=[sp,#64] +str r0,[sp,#64] + +# qhasm: c = &tmp +# asm 1: lea >c=int32#1,c=r0,i=int32#4,=0 +# asm 2: ldr >i=r3,=0 +ldr r3,=0 + +# qhasm: mcopy: +._mcopy: + +# qhasm: mi = mem8[m + 0] +# asm 1: ldrb >mi=int32#5,[mi=r4,[mi=int32#2,=0 +# asm 2: ldr >mi=r1,=0 +ldr r1,=0 + +# qhasm: pad: +._pad: + +# qhasm: mem8[c + 0] = mi +# asm 1: strb m=int32#2,m=r1,diag0=reg128#2,diag0=q1,diag1=reg128#5,diag1=q4,diag2=reg128#8,diag2=q7,diag3=reg128#9,diag3=q8,nextblock=reg128#10,#0xff +# asm 2: vmov.i64 >nextblock=q9,#0xff +vmov.i64 q9,#0xff + +# qhasm: 4x nextblock unsigned>>= 7 +# asm 1: vshr.u32 >nextblock=reg128#10,nextblock=q9,n2n3n3n2=reg128#1,n2n3n3n2=q0,i=int32#4,=12 +# asm 2: ldr >i=r3,=12 +ldr r3,=12 + +# qhasm: mainloop1: +._mainloop1: + +# qhasm: 4x a0 = diag1 + diag0 +# asm 1: vadd.i32 >a0=reg128#10,a0=q9,b0=reg128#11,b0=q10,> 25 +# asm 1: vsri.i32 diag3=reg128#9,diag3=q8,a1=reg128#10,a1=q9,b1=reg128#11,b1=q10,> 23 +# asm 1: vsri.i32 diag2=reg128#8,diag2=q7,a2=reg128#10,a2=q9,diag3=reg128#9,diag3=q8,b2=reg128#11,b2=q10,> 19 +# asm 1: vsri.i32 diag1=reg128#5,diag1=q4,a3=reg128#10,a3=q9,b3=reg128#11,b3=q10,> 14 +# asm 1: vsri.i32 diag1=reg128#5,diag1=q4,diag0=reg128#2,diag0=q1,a0=reg128#10,a0=q9,b0=reg128#11,b0=q10,> 25 +# asm 1: vsri.i32 diag1=reg128#5,diag1=q4,a1=reg128#10,a1=q9,b1=reg128#11,b1=q10,> 23 +# asm 1: vsri.i32 ? i -= 2 +# asm 1: subs diag2=reg128#8,diag2=q7,a2=reg128#10,a2=q9,diag1=reg128#5,diag1=q4,b2=reg128#11,b2=q10,> 19 +# asm 1: vsri.i32 diag3=reg128#9,diag3=q8,a3=reg128#10,a3=q9,b3=reg128#11,b3=q10,> 14 +# asm 1: vsri.i32 diag3=reg128#9,diag3=q8,diag0=reg128#2,diag0=q1, +bhi ._mainloop1 + +# qhasm: 2x abab = 0xffffffff +# asm 1: vmov.i64 >abab=reg128#10,#0xffffffff +# asm 2: vmov.i64 >abab=q9,#0xffffffff +vmov.i64 q9,#0xffffffff + +# qhasm: 4x x0x5x10x15 = diag0 + start0 +# asm 1: vadd.i32 >x0x5x10x15=reg128#2,x0x5x10x15=q1,x12x1x6x11=reg128#5,x12x1x6x11=q4,x8x13x2x7=reg128#6,x8x13x2x7=q5,x4x9x14x3=reg128#7,x4x9x14x3=q6,x0x1x10x11=reg128#8,x0x1x10x11=q7,x12x13x6x7=reg128#9,x12x13x6x7=q8,x8x9x2x3=reg128#11,x8x9x2x3=q10,x4x5x14x15=reg128#12,x4x5x14x15=q11,x0x1x2x3=reg128#2,x0x1x2x3=q1,x4x5x6x7=reg128#5,x4x5x6x7=q4,x8x9x10x11=reg128#6,x8x9x10x11=q5,x12x13x14x15=reg128#7,x12x13x14x15=q6,m0m1m2m3=reg128#8%bot->m0m1m2m3=reg128#8%top},[m0m1m2m3=d14->m0m1m2m3=d15},[m4m5m6m7=reg128#9%bot->m4m5m6m7=reg128#9%top},[m4m5m6m7=d16->m4m5m6m7=d17},[m8m9m10m11=reg128#10%bot->m8m9m10m11=reg128#10%top},[m8m9m10m11=d18->m8m9m10m11=d19},[m12m13m14m15=reg128#11%bot->m12m13m14m15=reg128#11%top},[m12m13m14m15=d20->m12m13m14m15=d21},[x0x1x2x3=reg128#2,x0x1x2x3=q1,x4x5x6x7=reg128#5,x4x5x6x7=q4,x8x9x10x11=reg128#6,x8x9x10x11=q5,x12x13x14x15=reg128#7,x12x13x14x15=q6,i=int32#4,=0 +# asm 2: ldr >i=r3,=0 +ldr r3,=0 + +# qhasm: m = c - 64 +# asm 1: sub >m=int32#2,m=r1,c=int32#1,c=r0,ci=int32#5,[ci=r4,[? mlenlow -= 64 +# asm 1: subs +bhi ._mlenatleast1 + +# qhasm: done: +._done: + +# qhasm: new caller_r4 + +# qhasm: caller_r4 = stack_r4 +# asm 1: ldr >caller_r4=int32#5,caller_r4=r4,result=int32#1,=0 +# asm 2: ldr >result=r0,=0 +ldr r0,=0 + +# qhasm: return result +add sp,sp,#256 +bx lr diff --git a/ext/bin/tap-windows-ndis6/arm64/zttap300.cat b/ext/bin/tap-windows-ndis6/arm64/zttap300.cat new file mode 100644 index 0000000000000000000000000000000000000000..906a15a4b4875ed8635b0e49c30a49c0d3f120a0 GIT binary patch literal 11761 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 z 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, Grant Limberg +ADD . /ZeroTierOne +RUN export PATH=$PATH:~/.cargo/bin && cd ZeroTierOne && make clean && make central-controller -j8 + +FROM registry.zerotier.com/zerotier/ctlrun:latest +COPY --from=builder /ZeroTierOne/zerotier-one /usr/local/bin/zerotier-one +RUN chmod a+x /usr/local/bin/zerotier-one +RUN echo "/usr/local/lib64" > /etc/ld.so.conf.d/usr-local-lib64.conf && ldconfig + +ADD ext/central-controller-docker/main.sh / +RUN chmod a+x /main.sh + +ENTRYPOINT /main.sh diff --git a/ext/central-controller-docker/Dockerfile.builder b/ext/central-controller-docker/Dockerfile.builder new file mode 100644 index 0000000..29356b8 --- /dev/null +++ b/ext/central-controller-docker/Dockerfile.builder @@ -0,0 +1,26 @@ +# Dockerfile for building ZeroTier Central Controllers +FROM ubuntu:jammy as builder +MAINTAINER Adam Ierymekno , Grant Limberg + +ARG git_branch=master + +RUN apt update && apt upgrade -y +RUN apt -y install \ + build-essential \ + pkg-config \ + bash \ + clang \ + libjemalloc2 \ + libjemalloc-dev \ + libpq5 \ + libpq-dev \ + openssl \ + libssl-dev \ + postgresql-client \ + postgresql-client-common \ + curl \ + google-perftools \ + libgoogle-perftools-dev \ + protobuf-compiler + +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y diff --git a/ext/central-controller-docker/Dockerfile.run_base b/ext/central-controller-docker/Dockerfile.run_base new file mode 100644 index 0000000..a581d01 --- /dev/null +++ b/ext/central-controller-docker/Dockerfile.run_base @@ -0,0 +1,15 @@ +FROM ubuntu:jammy + +RUN apt update && apt upgrade -y + +RUN apt -y install \ + netcat \ + postgresql-client \ + postgresql-client-common \ + libjemalloc2 \ + libpq5 \ + curl \ + binutils \ + linux-tools-gke \ + perf-tools-unstable \ + google-perftools diff --git a/ext/central-controller-docker/Makefile b/ext/central-controller-docker/Makefile new file mode 100644 index 0000000..46ec8ee --- /dev/null +++ b/ext/central-controller-docker/Makefile @@ -0,0 +1,16 @@ +registry = registry.zerotier.com/zerotier + +all: controller-builder controller-runbase + +buildx: + @echo "docker buildx create" + # docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + docker run --privileged --rm tonistiigi/binfmt --install all + @echo docker buildx create --name multiarch --driver docker-container --use + @echo docker buildx inspect --bootstrap + +controller-builder: buildx + docker buildx build --no-cache --platform linux/amd64,linux/arm64 -t $(registry)/ctlbuild:latest -f Dockerfile.builder . --push + +controller-runbase: buildx + docker buildx build --no-cache --platform linux/amd64,linux/arm64 -t $(registry)/ctlrun:latest -f Dockerfile.run_base . --push diff --git a/ext/central-controller-docker/README.md b/ext/central-controller-docker/README.md new file mode 100644 index 0000000..a954b1c --- /dev/null +++ b/ext/central-controller-docker/README.md @@ -0,0 +1,3 @@ +# ZeroTier Central Controller Docker Image + +Dockerfile & startup script for use with [ZeroTier Central](https://my.zerotier.com). Not intended for public use. diff --git a/ext/central-controller-docker/main.sh b/ext/central-controller-docker/main.sh new file mode 100755 index 0000000..5583b3a --- /dev/null +++ b/ext/central-controller-docker/main.sh @@ -0,0 +1,115 @@ +#!/bin/bash + +if [ -z "$ZT_IDENTITY_PATH" ]; then + echo '*** FAILED: ZT_IDENTITY_PATH environment variable is not defined' + exit 1 +fi +if [ -z "$ZT_DB_HOST" ]; then + echo '*** FAILED: ZT_DB_HOST environment variable not defined' + exit 1 +fi +if [ -z "$ZT_DB_PORT" ]; then + echo '*** FAILED: ZT_DB_PORT environment variable not defined' + exit 1 +fi +if [ -z "$ZT_DB_NAME" ]; then + echo '*** FAILED: ZT_DB_NAME environment variable not defined' + exit 1 +fi +if [ -z "$ZT_DB_USER" ]; then + echo '*** FAILED: ZT_DB_USER environment variable not defined' + exit 1 +fi +if [ -z "$ZT_DB_PASSWORD" ]; then + echo '*** FAILED: ZT_DB_PASSWORD environment variable not defined' + exit 1 +fi + +REDIS="" +if [ "$ZT_USE_REDIS" == "true" ]; then + if [ -z "$ZT_REDIS_HOST" ]; then + echo '*** FAILED: ZT_REDIS_HOST environment variable not defined' + exit 1 + fi + + if [ -z "$ZT_REDIS_PORT" ]; then + echo '*** FAILED: ZT_REDIS_PORT enivronment variable not defined' + exit 1 + fi + + if [ -z "$ZT_REDIS_CLUSTER_MODE" ]; then + echo '*** FAILED: ZT_REDIS_CLUSTER_MODE environment variable not defined' + exit 1 + fi + + REDIS="\"redis\": { + \"hostname\": \"${ZT_REDIS_HOST}\", + \"port\": ${ZT_REDIS_PORT}, + \"clusterMode\": ${ZT_REDIS_CLUSTER_MODE}, + \"password\": \"${ZT_REDIS_PASSWORD}\" + } + " +else + REDIS="\"redis\": null" +fi + +mkdir -p /var/lib/zerotier-one + +pushd /var/lib/zerotier-one +ln -s $ZT_IDENTITY_PATH/identity.public identity.public +ln -s $ZT_IDENTITY_PATH/identity.secret identity.secret +if [ -f "$ZT_IDENTITY_PATH/authtoken.secret" ]; then + ln -s $ZT_IDENTITY_PATH/authtoken.secret authtoken.secret +fi +popd + +DEFAULT_PORT=9993 +DEFAULT_LB_MODE=false + +APP_NAME="controller-$(cat /var/lib/zerotier-one/identity.public | cut -d ':' -f 1)" + +echo "{ + \"settings\": { + \"controllerDbPath\": \"postgres:host=${ZT_DB_HOST} port=${ZT_DB_PORT} dbname=${ZT_DB_NAME} user=${ZT_DB_USER} password=${ZT_DB_PASSWORD} application_name=${APP_NAME} sslmode=prefer sslcert=${DB_CLIENT_CERT} sslkey=${DB_CLIENT_KEY} sslrootcert=${DB_SERVER_CA}\", + \"portMappingEnabled\": true, + \"softwareUpdate\": \"disable\", + \"interfacePrefixBlacklist\": [ + \"inot\", + \"nat64\" + ], + \"lowBandwidthMode\": ${ZT_LB_MODE:-$DEFAULT_LB_MODE}, + \"ssoRedirectURL\": \"${ZT_SSO_REDIRECT_URL}\", + \"allowManagementFrom\": [\"127.0.0.1\", \"::1\", \"10.0.0.0/8\"], + ${REDIS} + } +} +" > /var/lib/zerotier-one/local.conf + +if [ -n "$DB_SERVER_CA" ]; then + echo "secret list" + chmod 600 /secrets/db/*.pem + ls -l /secrets/db/ + until /usr/bin/pg_isready -h ${ZT_DB_HOST} -p ${ZT_DB_PORT} -d "sslmode=prefer sslcert=${DB_CLIENT_CERT} sslkey=${DB_CLIENT_KEY} sslrootcert=${DB_SERVER_CA}"; do + echo "Waiting for PostgreSQL..."; + sleep 2; + done +else + until /usr/bin/pg_isready -h ${ZT_DB_HOST} -p ${ZT_DB_PORT}; do + echo "Waiting for PostgreSQL..."; + sleep 2; + done +fi + +if [ -n "$ZT_TEMPORAL_HOST" ] && [ -n "$ZT_TEMPORAL_PORT" ]; then + echo "waiting for temporal..." + while ! nc -z ${ZT_TEMPORAL_HOST} ${ZT_TEMPORAL_PORT}; do + echo "waiting..."; + sleep 1; + done + echo "Temporal is up" +fi + +export GLIBCXX_FORCE_NEW=1 +export GLIBCPP_FORCE_NEW=1 +export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libjemalloc.so.2" +exec /usr/local/bin/zerotier-one -p${ZT_CONTROLLER_PORT:-$DEFAULT_PORT} /var/lib/zerotier-one diff --git a/ext/cpp-httplib/httplib.h b/ext/cpp-httplib/httplib.h new file mode 100644 index 0000000..dfdd260 --- /dev/null +++ b/ext/cpp-httplib/httplib.h @@ -0,0 +1,9441 @@ +// +// httplib.h +// +// Copyright (c) 2024 Yuji Hirose. All rights reserved. +// MIT License +// + +#ifndef CPPHTTPLIB_HTTPLIB_H +#define CPPHTTPLIB_HTTPLIB_H + +#define CPPHTTPLIB_VERSION "0.15.3" + +/* + * Configuration + */ + +#ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND +#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 5 +#endif + +#ifndef CPPHTTPLIB_KEEPALIVE_MAX_COUNT +#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 5 +#endif + +#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND +#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 300 +#endif + +#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND +#define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND 0 +#endif + +#ifndef CPPHTTPLIB_READ_TIMEOUT_SECOND +#define CPPHTTPLIB_READ_TIMEOUT_SECOND 5 +#endif + +#ifndef CPPHTTPLIB_READ_TIMEOUT_USECOND +#define CPPHTTPLIB_READ_TIMEOUT_USECOND 0 +#endif + +#ifndef CPPHTTPLIB_WRITE_TIMEOUT_SECOND +#define CPPHTTPLIB_WRITE_TIMEOUT_SECOND 5 +#endif + +#ifndef CPPHTTPLIB_WRITE_TIMEOUT_USECOND +#define CPPHTTPLIB_WRITE_TIMEOUT_USECOND 0 +#endif + +#ifndef CPPHTTPLIB_IDLE_INTERVAL_SECOND +#define CPPHTTPLIB_IDLE_INTERVAL_SECOND 0 +#endif + +#ifndef CPPHTTPLIB_IDLE_INTERVAL_USECOND +#ifdef _WIN32 +#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 10000 +#else +#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 0 +#endif +#endif + +#ifndef CPPHTTPLIB_REQUEST_URI_MAX_LENGTH +#define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH 8192 +#endif + +#ifndef CPPHTTPLIB_HEADER_MAX_LENGTH +#define CPPHTTPLIB_HEADER_MAX_LENGTH 8192 +#endif + +#ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT +#define CPPHTTPLIB_REDIRECT_MAX_COUNT 20 +#endif + +#ifndef CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT +#define CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT 1024 +#endif + +#ifndef CPPHTTPLIB_PAYLOAD_MAX_LENGTH +#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH ((std::numeric_limits::max)()) +#endif + +#ifndef CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH +#define CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH 8192 +#endif + +#ifndef CPPHTTPLIB_RANGE_MAX_COUNT +#define CPPHTTPLIB_RANGE_MAX_COUNT 1024 +#endif + +#ifndef CPPHTTPLIB_TCP_NODELAY +#define CPPHTTPLIB_TCP_NODELAY false +#endif + +#ifndef CPPHTTPLIB_RECV_BUFSIZ +#define CPPHTTPLIB_RECV_BUFSIZ size_t(4096u) +#endif + +#ifndef CPPHTTPLIB_COMPRESSION_BUFSIZ +#define CPPHTTPLIB_COMPRESSION_BUFSIZ size_t(16384u) +#endif + +#ifndef CPPHTTPLIB_THREAD_POOL_COUNT +#define CPPHTTPLIB_THREAD_POOL_COUNT \ + ((std::max)(8u, std::thread::hardware_concurrency() > 0 \ + ? std::thread::hardware_concurrency() - 1 \ + : 0)) +#endif + +#ifndef CPPHTTPLIB_RECV_FLAGS +#define CPPHTTPLIB_RECV_FLAGS 0 +#endif + +#ifndef CPPHTTPLIB_SEND_FLAGS +#define CPPHTTPLIB_SEND_FLAGS 0 +#endif + +#ifndef CPPHTTPLIB_LISTEN_BACKLOG +#define CPPHTTPLIB_LISTEN_BACKLOG 5 +#endif + +/* + * Headers + */ + +#ifdef _WIN32 +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif //_CRT_SECURE_NO_WARNINGS + +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif //_CRT_NONSTDC_NO_DEPRECATE + +#if defined(_MSC_VER) +#if _MSC_VER < 1900 +#error Sorry, Visual Studio versions prior to 2015 are not supported +#endif + +#pragma comment(lib, "ws2_32.lib") + +#ifdef _WIN64 +using ssize_t = __int64; +#else +using ssize_t = long; +#endif +#endif // _MSC_VER + +#ifndef S_ISREG +#define S_ISREG(m) (((m) & S_IFREG) == S_IFREG) +#endif // S_ISREG + +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR) +#endif // S_ISDIR + +#ifndef NOMINMAX +#define NOMINMAX +#endif // NOMINMAX + +#include +#include +#include + +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 +#endif + +using socket_t = SOCKET; +#ifdef CPPHTTPLIB_USE_POLL +#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout) +#endif + +#else // not _WIN32 + +#include +#if !defined(_AIX) && !defined(__MVS__) +#include +#endif +#ifdef __MVS__ +#include +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif +#endif +#include +#include +#include +#ifdef __linux__ +#include +#endif +#include +#ifdef CPPHTTPLIB_USE_POLL +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +using socket_t = int; +#ifndef INVALID_SOCKET +#define INVALID_SOCKET (-1) +#endif +#endif //_WIN32 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +#ifdef _WIN32 +#include + +// these are defined in wincrypt.h and it breaks compilation if BoringSSL is +// used +#undef X509_NAME +#undef X509_CERT_PAIR +#undef X509_EXTENSIONS +#undef PKCS7_SIGNER_INFO + +#ifdef _MSC_VER +#pragma comment(lib, "crypt32.lib") +#endif +#elif defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN) && defined(__APPLE__) +#include +#if TARGET_OS_OSX +#include +#include +#endif // TARGET_OS_OSX +#endif // _WIN32 + +#include +#include +#include +#include + +#if defined(_WIN32) && defined(OPENSSL_USE_APPLINK) +#include +#endif + +#include +#include + +#if OPENSSL_VERSION_NUMBER < 0x30000000L +#error Sorry, OpenSSL versions prior to 3.0.0 are not supported +#endif + +#endif + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +#include +#endif + +#ifdef CPPHTTPLIB_BROTLI_SUPPORT +#include +#include +#endif + +/* + * Declaration + */ +namespace httplib { + +namespace detail { + +/* + * Backport std::make_unique from C++14. + * + * NOTE: This code came up with the following stackoverflow post: + * https://stackoverflow.com/questions/10149840/c-arrays-and-make-unique + * + */ + +template +typename std::enable_if::value, std::unique_ptr>::type +make_unique(Args &&...args) { + return std::unique_ptr(new T(std::forward(args)...)); +} + +template +typename std::enable_if::value, std::unique_ptr>::type +make_unique(std::size_t n) { + typedef typename std::remove_extent::type RT; + return std::unique_ptr(new RT[n]); +} + +struct ci { + bool operator()(const std::string &s1, const std::string &s2) const { + return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), + s2.end(), + [](unsigned char c1, unsigned char c2) { + return ::tolower(c1) < ::tolower(c2); + }); + } +}; + +// This is based on +// "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189". + +struct scope_exit { + explicit scope_exit(std::function &&f) + : exit_function(std::move(f)), execute_on_destruction{true} {} + + scope_exit(scope_exit &&rhs) noexcept + : exit_function(std::move(rhs.exit_function)), + execute_on_destruction{rhs.execute_on_destruction} { + rhs.release(); + } + + ~scope_exit() { + if (execute_on_destruction) { this->exit_function(); } + } + + void release() { this->execute_on_destruction = false; } + +private: + scope_exit(const scope_exit &) = delete; + void operator=(const scope_exit &) = delete; + scope_exit &operator=(scope_exit &&) = delete; + + std::function exit_function; + bool execute_on_destruction; +}; + +} // namespace detail + +enum StatusCode { + // Information responses + Continue_100 = 100, + SwitchingProtocol_101 = 101, + Processing_102 = 102, + EarlyHints_103 = 103, + + // Successful responses + OK_200 = 200, + Created_201 = 201, + Accepted_202 = 202, + NonAuthoritativeInformation_203 = 203, + NoContent_204 = 204, + ResetContent_205 = 205, + PartialContent_206 = 206, + MultiStatus_207 = 207, + AlreadyReported_208 = 208, + IMUsed_226 = 226, + + // Redirection messages + MultipleChoices_300 = 300, + MovedPermanently_301 = 301, + Found_302 = 302, + SeeOther_303 = 303, + NotModified_304 = 304, + UseProxy_305 = 305, + unused_306 = 306, + TemporaryRedirect_307 = 307, + PermanentRedirect_308 = 308, + + // Client error responses + BadRequest_400 = 400, + Unauthorized_401 = 401, + PaymentRequired_402 = 402, + Forbidden_403 = 403, + NotFound_404 = 404, + MethodNotAllowed_405 = 405, + NotAcceptable_406 = 406, + ProxyAuthenticationRequired_407 = 407, + RequestTimeout_408 = 408, + Conflict_409 = 409, + Gone_410 = 410, + LengthRequired_411 = 411, + PreconditionFailed_412 = 412, + PayloadTooLarge_413 = 413, + UriTooLong_414 = 414, + UnsupportedMediaType_415 = 415, + RangeNotSatisfiable_416 = 416, + ExpectationFailed_417 = 417, + ImATeapot_418 = 418, + MisdirectedRequest_421 = 421, + UnprocessableContent_422 = 422, + Locked_423 = 423, + FailedDependency_424 = 424, + TooEarly_425 = 425, + UpgradeRequired_426 = 426, + PreconditionRequired_428 = 428, + TooManyRequests_429 = 429, + RequestHeaderFieldsTooLarge_431 = 431, + UnavailableForLegalReasons_451 = 451, + + // Server error responses + InternalServerError_500 = 500, + NotImplemented_501 = 501, + BadGateway_502 = 502, + ServiceUnavailable_503 = 503, + GatewayTimeout_504 = 504, + HttpVersionNotSupported_505 = 505, + VariantAlsoNegotiates_506 = 506, + InsufficientStorage_507 = 507, + LoopDetected_508 = 508, + NotExtended_510 = 510, + NetworkAuthenticationRequired_511 = 511, +}; + +using Headers = std::multimap; + +using Params = std::multimap; +using Match = std::smatch; + +using Progress = std::function; + +struct Response; +using ResponseHandler = std::function; + +struct MultipartFormData { + std::string name; + std::string content; + std::string filename; + std::string content_type; +}; +using MultipartFormDataItems = std::vector; +using MultipartFormDataMap = std::multimap; + +class DataSink { +public: + DataSink() : os(&sb_), sb_(*this) {} + + DataSink(const DataSink &) = delete; + DataSink &operator=(const DataSink &) = delete; + DataSink(DataSink &&) = delete; + DataSink &operator=(DataSink &&) = delete; + + std::function write; + std::function is_writable; + std::function done; + std::function done_with_trailer; + std::ostream os; + +private: + class data_sink_streambuf : public std::streambuf { + public: + explicit data_sink_streambuf(DataSink &sink) : sink_(sink) {} + + protected: + std::streamsize xsputn(const char *s, std::streamsize n) override { + sink_.write(s, static_cast(n)); + return n; + } + + private: + DataSink &sink_; + }; + + data_sink_streambuf sb_; +}; + +using ContentProvider = + std::function; + +using ContentProviderWithoutLength = + std::function; + +using ContentProviderResourceReleaser = std::function; + +struct MultipartFormDataProvider { + std::string name; + ContentProviderWithoutLength provider; + std::string filename; + std::string content_type; +}; +using MultipartFormDataProviderItems = std::vector; + +using ContentReceiverWithProgress = + std::function; + +using ContentReceiver = + std::function; + +using MultipartContentHeader = + std::function; + +class ContentReader { +public: + using Reader = std::function; + using MultipartReader = std::function; + + ContentReader(Reader reader, MultipartReader multipart_reader) + : reader_(std::move(reader)), + multipart_reader_(std::move(multipart_reader)) {} + + bool operator()(MultipartContentHeader header, + ContentReceiver receiver) const { + return multipart_reader_(std::move(header), std::move(receiver)); + } + + bool operator()(ContentReceiver receiver) const { + return reader_(std::move(receiver)); + } + + Reader reader_; + MultipartReader multipart_reader_; +}; + +using Range = std::pair; +using Ranges = std::vector; + +struct Request { + std::string method; + std::string path; + Headers headers; + std::string body; + + std::string remote_addr; + int remote_port = -1; + std::string local_addr; + int local_port = -1; + + // for server + std::string version; + std::string target; + Params params; + MultipartFormDataMap files; + Ranges ranges; + Match matches; + std::unordered_map path_params; + + // for client + ResponseHandler response_handler; + ContentReceiverWithProgress content_receiver; + Progress progress; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + const SSL *ssl = nullptr; +#endif + + bool has_header(const std::string &key) const; + std::string get_header_value(const std::string &key, size_t id = 0) const; + uint64_t get_header_value_u64(const std::string &key, size_t id = 0) const; + size_t get_header_value_count(const std::string &key) const; + void set_header(const std::string &key, const std::string &val); + + bool has_param(const std::string &key) const; + std::string get_param_value(const std::string &key, size_t id = 0) const; + size_t get_param_value_count(const std::string &key) const; + + bool is_multipart_form_data() const; + + bool has_file(const std::string &key) const; + MultipartFormData get_file_value(const std::string &key) const; + std::vector get_file_values(const std::string &key) const; + + // private members... + size_t redirect_count_ = CPPHTTPLIB_REDIRECT_MAX_COUNT; + size_t content_length_ = 0; + ContentProvider content_provider_; + bool is_chunked_content_provider_ = false; + size_t authorization_count_ = 0; +}; + +struct Response { + std::string version; + int status = -1; + std::string reason; + Headers headers; + std::string body; + std::string location; // Redirect location + + bool has_header(const std::string &key) const; + std::string get_header_value(const std::string &key, size_t id = 0) const; + uint64_t get_header_value_u64(const std::string &key, size_t id = 0) const; + size_t get_header_value_count(const std::string &key) const; + void set_header(const std::string &key, const std::string &val); + + void set_redirect(const std::string &url, int status = StatusCode::Found_302); + void set_content(const char *s, size_t n, const std::string &content_type); + void set_content(const std::string &s, const std::string &content_type); + void set_content(std::string &&s, const std::string &content_type); + + void set_content_provider( + size_t length, const std::string &content_type, ContentProvider provider, + ContentProviderResourceReleaser resource_releaser = nullptr); + + void set_content_provider( + const std::string &content_type, ContentProviderWithoutLength provider, + ContentProviderResourceReleaser resource_releaser = nullptr); + + void set_chunked_content_provider( + const std::string &content_type, ContentProviderWithoutLength provider, + ContentProviderResourceReleaser resource_releaser = nullptr); + + Response() = default; + Response(const Response &) = default; + Response &operator=(const Response &) = default; + Response(Response &&) = default; + Response &operator=(Response &&) = default; + ~Response() { + if (content_provider_resource_releaser_) { + content_provider_resource_releaser_(content_provider_success_); + } + } + + // private members... + size_t content_length_ = 0; + ContentProvider content_provider_; + ContentProviderResourceReleaser content_provider_resource_releaser_; + bool is_chunked_content_provider_ = false; + bool content_provider_success_ = false; +}; + +class Stream { +public: + virtual ~Stream() = default; + + virtual bool is_readable() const = 0; + virtual bool is_writable() const = 0; + + virtual ssize_t read(char *ptr, size_t size) = 0; + virtual ssize_t write(const char *ptr, size_t size) = 0; + virtual void get_remote_ip_and_port(std::string &ip, int &port) const = 0; + virtual void get_local_ip_and_port(std::string &ip, int &port) const = 0; + virtual socket_t socket() const = 0; + + template + ssize_t write_format(const char *fmt, const Args &...args); + ssize_t write(const char *ptr); + ssize_t write(const std::string &s); +}; + +class TaskQueue { +public: + TaskQueue() = default; + virtual ~TaskQueue() = default; + + virtual bool enqueue(std::function fn) = 0; + virtual void shutdown() = 0; + + virtual void on_idle() {} +}; + +class ThreadPool : public TaskQueue { +public: + explicit ThreadPool(size_t n, size_t mqr = 0) + : shutdown_(false), max_queued_requests_(mqr) { + while (n) { + threads_.emplace_back(worker(*this)); + n--; + } + } + + ThreadPool(const ThreadPool &) = delete; + ~ThreadPool() override = default; + + bool enqueue(std::function fn) override { + { + std::unique_lock lock(mutex_); + if (max_queued_requests_ > 0 && jobs_.size() >= max_queued_requests_) { + return false; + } + jobs_.push_back(std::move(fn)); + } + + cond_.notify_one(); + return true; + } + + void shutdown() override { + // Stop all worker threads... + { + std::unique_lock lock(mutex_); + shutdown_ = true; + } + + cond_.notify_all(); + + // Join... + for (auto &t : threads_) { + t.join(); + } + } + +private: + struct worker { + explicit worker(ThreadPool &pool) : pool_(pool) {} + + void operator()() { + for (;;) { + std::function fn; + { + std::unique_lock lock(pool_.mutex_); + + pool_.cond_.wait( + lock, [&] { return !pool_.jobs_.empty() || pool_.shutdown_; }); + + if (pool_.shutdown_ && pool_.jobs_.empty()) { break; } + + fn = std::move(pool_.jobs_.front()); + pool_.jobs_.pop_front(); + } + + assert(true == static_cast(fn)); + fn(); + } + } + + ThreadPool &pool_; + }; + friend struct worker; + + std::vector threads_; + std::list> jobs_; + + bool shutdown_; + size_t max_queued_requests_ = 0; + + std::condition_variable cond_; + std::mutex mutex_; +}; + +using Logger = std::function; + +using SocketOptions = std::function; + +void default_socket_options(socket_t sock); + +const char *status_message(int status); + +std::string get_bearer_token_auth(const Request &req); + +namespace detail { + +class MatcherBase { +public: + virtual ~MatcherBase() = default; + + // Match request path and populate its matches and + virtual bool match(Request &request) const = 0; +}; + +/** + * Captures parameters in request path and stores them in Request::path_params + * + * Capture name is a substring of a pattern from : to /. + * The rest of the pattern is matched agains the request path directly + * Parameters are captured starting from the next character after + * the end of the last matched static pattern fragment until the next /. + * + * Example pattern: + * "/path/fragments/:capture/more/fragments/:second_capture" + * Static fragments: + * "/path/fragments/", "more/fragments/" + * + * Given the following request path: + * "/path/fragments/:1/more/fragments/:2" + * the resulting capture will be + * {{"capture", "1"}, {"second_capture", "2"}} + */ +class PathParamsMatcher : public MatcherBase { +public: + PathParamsMatcher(const std::string &pattern); + + bool match(Request &request) const override; + +private: + static constexpr char marker = ':'; + // Treat segment separators as the end of path parameter capture + // Does not need to handle query parameters as they are parsed before path + // matching + static constexpr char separator = '/'; + + // Contains static path fragments to match against, excluding the '/' after + // path params + // Fragments are separated by path params + std::vector static_fragments_; + // Stores the names of the path parameters to be used as keys in the + // Request::path_params map + std::vector param_names_; +}; + +/** + * Performs std::regex_match on request path + * and stores the result in Request::matches + * + * Note that regex match is performed directly on the whole request. + * This means that wildcard patterns may match multiple path segments with /: + * "/begin/(.*)/end" will match both "/begin/middle/end" and "/begin/1/2/end". + */ +class RegexMatcher : public MatcherBase { +public: + RegexMatcher(const std::string &pattern) : regex_(pattern) {} + + bool match(Request &request) const override; + +private: + std::regex regex_; +}; + +ssize_t write_headers(Stream &strm, const Headers &headers); + +} // namespace detail + +class Server { +public: + using Handler = std::function; + + using ExceptionHandler = + std::function; + + enum class HandlerResponse { + Handled, + Unhandled, + }; + using HandlerWithResponse = + std::function; + + using HandlerWithContentReader = std::function; + + using Expect100ContinueHandler = + std::function; + + Server(); + + virtual ~Server(); + + virtual bool is_valid() const; + + Server &Get(const std::string &pattern, Handler handler); + Server &Post(const std::string &pattern, Handler handler); + Server &Post(const std::string &pattern, HandlerWithContentReader handler); + Server &Put(const std::string &pattern, Handler handler); + Server &Put(const std::string &pattern, HandlerWithContentReader handler); + Server &Patch(const std::string &pattern, Handler handler); + Server &Patch(const std::string &pattern, HandlerWithContentReader handler); + Server &Delete(const std::string &pattern, Handler handler); + Server &Delete(const std::string &pattern, HandlerWithContentReader handler); + Server &Options(const std::string &pattern, Handler handler); + + bool set_base_dir(const std::string &dir, + const std::string &mount_point = std::string()); + bool set_mount_point(const std::string &mount_point, const std::string &dir, + Headers headers = Headers()); + bool remove_mount_point(const std::string &mount_point); + Server &set_file_extension_and_mimetype_mapping(const std::string &ext, + const std::string &mime); + Server &set_default_file_mimetype(const std::string &mime); + Server &set_file_request_handler(Handler handler); + + Server &set_error_handler(HandlerWithResponse handler); + Server &set_error_handler(Handler handler); + Server &set_exception_handler(ExceptionHandler handler); + Server &set_pre_routing_handler(HandlerWithResponse handler); + Server &set_post_routing_handler(Handler handler); + + Server &set_expect_100_continue_handler(Expect100ContinueHandler handler); + Server &set_logger(Logger logger); + + Server &set_address_family(int family); + Server &set_tcp_nodelay(bool on); + Server &set_socket_options(SocketOptions socket_options); + + Server &set_default_headers(Headers headers); + Server & + set_header_writer(std::function const &writer); + + Server &set_keep_alive_max_count(size_t count); + Server &set_keep_alive_timeout(time_t sec); + + Server &set_read_timeout(time_t sec, time_t usec = 0); + template + Server &set_read_timeout(const std::chrono::duration &duration); + + Server &set_write_timeout(time_t sec, time_t usec = 0); + template + Server &set_write_timeout(const std::chrono::duration &duration); + + Server &set_idle_interval(time_t sec, time_t usec = 0); + template + Server &set_idle_interval(const std::chrono::duration &duration); + + Server &set_payload_max_length(size_t length); + + bool bind_to_port(const std::string &host, int port, int socket_flags = 0); + int bind_to_any_port(const std::string &host, int socket_flags = 0); + bool listen_after_bind(); + + bool listen(const std::string &host, int port, int socket_flags = 0); + + bool is_running() const; + void wait_until_ready() const; + void stop(); + + std::function new_task_queue; + +protected: + bool process_request(Stream &strm, bool close_connection, + bool &connection_closed, + const std::function &setup_request); + + std::atomic svr_sock_{INVALID_SOCKET}; + size_t keep_alive_max_count_ = CPPHTTPLIB_KEEPALIVE_MAX_COUNT; + time_t keep_alive_timeout_sec_ = CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND; + time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND; + time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND; + time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND; + time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND; + time_t idle_interval_sec_ = CPPHTTPLIB_IDLE_INTERVAL_SECOND; + time_t idle_interval_usec_ = CPPHTTPLIB_IDLE_INTERVAL_USECOND; + size_t payload_max_length_ = CPPHTTPLIB_PAYLOAD_MAX_LENGTH; + +private: + using Handlers = + std::vector, Handler>>; + using HandlersForContentReader = + std::vector, + HandlerWithContentReader>>; + + static std::unique_ptr + make_matcher(const std::string &pattern); + + socket_t create_server_socket(const std::string &host, int port, + int socket_flags, + SocketOptions socket_options) const; + int bind_internal(const std::string &host, int port, int socket_flags); + bool listen_internal(); + + bool routing(Request &req, Response &res, Stream &strm); + bool handle_file_request(const Request &req, Response &res, + bool head = false); + bool dispatch_request(Request &req, Response &res, + const Handlers &handlers) const; + bool dispatch_request_for_content_reader( + Request &req, Response &res, ContentReader content_reader, + const HandlersForContentReader &handlers) const; + + bool parse_request_line(const char *s, Request &req) const; + void apply_ranges(const Request &req, Response &res, + std::string &content_type, std::string &boundary) const; + bool write_response(Stream &strm, bool close_connection, Request &req, + Response &res); + bool write_response_with_content(Stream &strm, bool close_connection, + const Request &req, Response &res); + bool write_response_core(Stream &strm, bool close_connection, + const Request &req, Response &res, + bool need_apply_ranges); + bool write_content_with_provider(Stream &strm, const Request &req, + Response &res, const std::string &boundary, + const std::string &content_type); + bool read_content(Stream &strm, Request &req, Response &res); + bool + read_content_with_content_receiver(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver); + bool read_content_core(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver) const; + + virtual bool process_and_close_socket(socket_t sock); + + std::atomic is_running_{false}; + std::atomic done_{false}; + + struct MountPointEntry { + std::string mount_point; + std::string base_dir; + Headers headers; + }; + std::vector base_dirs_; + std::map file_extension_and_mimetype_map_; + std::string default_file_mimetype_ = "application/octet-stream"; + Handler file_request_handler_; + + Handlers get_handlers_; + Handlers post_handlers_; + HandlersForContentReader post_handlers_for_content_reader_; + Handlers put_handlers_; + HandlersForContentReader put_handlers_for_content_reader_; + Handlers patch_handlers_; + HandlersForContentReader patch_handlers_for_content_reader_; + Handlers delete_handlers_; + HandlersForContentReader delete_handlers_for_content_reader_; + Handlers options_handlers_; + + HandlerWithResponse error_handler_; + ExceptionHandler exception_handler_; + HandlerWithResponse pre_routing_handler_; + Handler post_routing_handler_; + Expect100ContinueHandler expect_100_continue_handler_; + + Logger logger_; + + int address_family_ = AF_UNSPEC; + bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY; + SocketOptions socket_options_ = default_socket_options; + + Headers default_headers_; + std::function header_writer_ = + detail::write_headers; +}; + +enum class Error { + Success = 0, + Unknown, + Connection, + BindIPAddress, + Read, + Write, + ExceedRedirectCount, + Canceled, + SSLConnection, + SSLLoadingCerts, + SSLServerVerification, + UnsupportedMultipartBoundaryChars, + Compression, + ConnectionTimeout, + ProxyConnection, + + // For internal use only + SSLPeerCouldBeClosed_, +}; + +std::string to_string(Error error); + +std::ostream &operator<<(std::ostream &os, const Error &obj); + +class Result { +public: + Result() = default; + Result(std::unique_ptr &&res, Error err, + Headers &&request_headers = Headers{}) + : res_(std::move(res)), err_(err), + request_headers_(std::move(request_headers)) {} + // Response + operator bool() const { return res_ != nullptr; } + bool operator==(std::nullptr_t) const { return res_ == nullptr; } + bool operator!=(std::nullptr_t) const { return res_ != nullptr; } + const Response &value() const { return *res_; } + Response &value() { return *res_; } + const Response &operator*() const { return *res_; } + Response &operator*() { return *res_; } + const Response *operator->() const { return res_.get(); } + Response *operator->() { return res_.get(); } + + // Error + Error error() const { return err_; } + + // Request Headers + bool has_request_header(const std::string &key) const; + std::string get_request_header_value(const std::string &key, + size_t id = 0) const; + uint64_t get_request_header_value_u64(const std::string &key, + size_t id = 0) const; + size_t get_request_header_value_count(const std::string &key) const; + +private: + std::unique_ptr res_; + Error err_ = Error::Unknown; + Headers request_headers_; +}; + +class ClientImpl { +public: + explicit ClientImpl(const std::string &host); + + explicit ClientImpl(const std::string &host, int port); + + explicit ClientImpl(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + + virtual ~ClientImpl(); + + virtual bool is_valid() const; + + Result Get(const std::string &path); + Result Get(const std::string &path, const Headers &headers); + Result Get(const std::string &path, Progress progress); + Result Get(const std::string &path, const Headers &headers, + Progress progress); + Result Get(const std::string &path, ContentReceiver content_receiver); + Result Get(const std::string &path, const Headers &headers, + ContentReceiver content_receiver); + Result Get(const std::string &path, ContentReceiver content_receiver, + Progress progress); + Result Get(const std::string &path, const Headers &headers, + ContentReceiver content_receiver, Progress progress); + Result Get(const std::string &path, ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const std::string &path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const std::string &path, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress); + Result Get(const std::string &path, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress); + + Result Get(const std::string &path, const Params ¶ms, + const Headers &headers, Progress progress = nullptr); + Result Get(const std::string &path, const Params ¶ms, + const Headers &headers, ContentReceiver content_receiver, + Progress progress = nullptr); + Result Get(const std::string &path, const Params ¶ms, + const Headers &headers, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress = nullptr); + + Result Head(const std::string &path); + Result Head(const std::string &path, const Headers &headers); + + Result Post(const std::string &path); + Result Post(const std::string &path, const Headers &headers); + Result Post(const std::string &path, const char *body, size_t content_length, + const std::string &content_type); + Result Post(const std::string &path, const Headers &headers, const char *body, + size_t content_length, const std::string &content_type); + Result Post(const std::string &path, const std::string &body, + const std::string &content_type); + Result Post(const std::string &path, const Headers &headers, + const std::string &body, const std::string &content_type); + Result Post(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type); + Result Post(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Post(const std::string &path, const Headers &headers, + size_t content_length, ContentProvider content_provider, + const std::string &content_type); + Result Post(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Post(const std::string &path, const Params ¶ms); + Result Post(const std::string &path, const Headers &headers, + const Params ¶ms); + Result Post(const std::string &path, const MultipartFormDataItems &items); + Result Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items); + Result Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, const std::string &boundary); + Result Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items); + + Result Put(const std::string &path); + Result Put(const std::string &path, const char *body, size_t content_length, + const std::string &content_type); + Result Put(const std::string &path, const Headers &headers, const char *body, + size_t content_length, const std::string &content_type); + Result Put(const std::string &path, const std::string &body, + const std::string &content_type); + Result Put(const std::string &path, const Headers &headers, + const std::string &body, const std::string &content_type); + Result Put(const std::string &path, size_t content_length, + ContentProvider content_provider, const std::string &content_type); + Result Put(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Put(const std::string &path, const Headers &headers, + size_t content_length, ContentProvider content_provider, + const std::string &content_type); + Result Put(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Put(const std::string &path, const Params ¶ms); + Result Put(const std::string &path, const Headers &headers, + const Params ¶ms); + Result Put(const std::string &path, const MultipartFormDataItems &items); + Result Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items); + Result Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, const std::string &boundary); + Result Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items); + + Result Patch(const std::string &path); + Result Patch(const std::string &path, const char *body, size_t content_length, + const std::string &content_type); + Result Patch(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type); + Result Patch(const std::string &path, const std::string &body, + const std::string &content_type); + Result Patch(const std::string &path, const Headers &headers, + const std::string &body, const std::string &content_type); + Result Patch(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type); + Result Patch(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Patch(const std::string &path, const Headers &headers, + size_t content_length, ContentProvider content_provider, + const std::string &content_type); + Result Patch(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + + Result Delete(const std::string &path); + Result Delete(const std::string &path, const Headers &headers); + Result Delete(const std::string &path, const char *body, + size_t content_length, const std::string &content_type); + Result Delete(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type); + Result Delete(const std::string &path, const std::string &body, + const std::string &content_type); + Result Delete(const std::string &path, const Headers &headers, + const std::string &body, const std::string &content_type); + + Result Options(const std::string &path); + Result Options(const std::string &path, const Headers &headers); + + bool send(Request &req, Response &res, Error &error); + Result send(const Request &req); + + void stop(); + + std::string host() const; + int port() const; + + size_t is_socket_open() const; + socket_t socket() const; + + void set_hostname_addr_map(std::map addr_map); + + void set_default_headers(Headers headers); + + void + set_header_writer(std::function const &writer); + + void set_address_family(int family); + void set_tcp_nodelay(bool on); + void set_socket_options(SocketOptions socket_options); + + void set_connection_timeout(time_t sec, time_t usec = 0); + template + void + set_connection_timeout(const std::chrono::duration &duration); + + void set_read_timeout(time_t sec, time_t usec = 0); + template + void set_read_timeout(const std::chrono::duration &duration); + + void set_write_timeout(time_t sec, time_t usec = 0); + template + void set_write_timeout(const std::chrono::duration &duration); + + void set_basic_auth(const std::string &username, const std::string &password); + void set_bearer_token_auth(const std::string &token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_digest_auth(const std::string &username, + const std::string &password); +#endif + + void set_keep_alive(bool on); + void set_follow_location(bool on); + + void set_url_encode(bool on); + + void set_compress(bool on); + + void set_decompress(bool on); + + void set_interface(const std::string &intf); + + void set_proxy(const std::string &host, int port); + void set_proxy_basic_auth(const std::string &username, + const std::string &password); + void set_proxy_bearer_token_auth(const std::string &token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_proxy_digest_auth(const std::string &username, + const std::string &password); +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_ca_cert_path(const std::string &ca_cert_file_path, + const std::string &ca_cert_dir_path = std::string()); + void set_ca_cert_store(X509_STORE *ca_cert_store); + X509_STORE *create_ca_cert_store(const char *ca_cert, std::size_t size) const; +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void enable_server_certificate_verification(bool enabled); +#endif + + void set_logger(Logger logger); + +protected: + struct Socket { + socket_t sock = INVALID_SOCKET; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + SSL *ssl = nullptr; +#endif + + bool is_open() const { return sock != INVALID_SOCKET; } + }; + + virtual bool create_and_connect_socket(Socket &socket, Error &error); + + // All of: + // shutdown_ssl + // shutdown_socket + // close_socket + // should ONLY be called when socket_mutex_ is locked. + // Also, shutdown_ssl and close_socket should also NOT be called concurrently + // with a DIFFERENT thread sending requests using that socket. + virtual void shutdown_ssl(Socket &socket, bool shutdown_gracefully); + void shutdown_socket(Socket &socket) const; + void close_socket(Socket &socket); + + bool process_request(Stream &strm, Request &req, Response &res, + bool close_connection, Error &error); + + bool write_content_with_provider(Stream &strm, const Request &req, + Error &error) const; + + void copy_settings(const ClientImpl &rhs); + + // Socket endpoint information + const std::string host_; + const int port_; + const std::string host_and_port_; + + // Current open socket + Socket socket_; + mutable std::mutex socket_mutex_; + std::recursive_mutex request_mutex_; + + // These are all protected under socket_mutex + size_t socket_requests_in_flight_ = 0; + std::thread::id socket_requests_are_from_thread_ = std::thread::id(); + bool socket_should_be_closed_when_request_is_done_ = false; + + // Hostname-IP map + std::map addr_map_; + + // Default headers + Headers default_headers_; + + // Header writer + std::function header_writer_ = + detail::write_headers; + + // Settings + std::string client_cert_path_; + std::string client_key_path_; + + time_t connection_timeout_sec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND; + time_t connection_timeout_usec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND; + time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND; + time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND; + time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND; + time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND; + + std::string basic_auth_username_; + std::string basic_auth_password_; + std::string bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + std::string digest_auth_username_; + std::string digest_auth_password_; +#endif + + bool keep_alive_ = false; + bool follow_location_ = false; + + bool url_encode_ = true; + + int address_family_ = AF_UNSPEC; + bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY; + SocketOptions socket_options_ = nullptr; + + bool compress_ = false; + bool decompress_ = true; + + std::string interface_; + + std::string proxy_host_; + int proxy_port_ = -1; + + std::string proxy_basic_auth_username_; + std::string proxy_basic_auth_password_; + std::string proxy_bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + std::string proxy_digest_auth_username_; + std::string proxy_digest_auth_password_; +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + std::string ca_cert_file_path_; + std::string ca_cert_dir_path_; + + X509_STORE *ca_cert_store_ = nullptr; +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + bool server_certificate_verification_ = true; +#endif + + Logger logger_; + +private: + bool send_(Request &req, Response &res, Error &error); + Result send_(Request &&req); + + socket_t create_client_socket(Error &error) const; + bool read_response_line(Stream &strm, const Request &req, + Response &res) const; + bool write_request(Stream &strm, Request &req, bool close_connection, + Error &error); + bool redirect(Request &req, Response &res, Error &error); + bool handle_request(Stream &strm, Request &req, Response &res, + bool close_connection, Error &error); + std::unique_ptr send_with_content_provider( + Request &req, const char *body, size_t content_length, + ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const std::string &content_type, Error &error); + Result send_with_content_provider( + const std::string &method, const std::string &path, + const Headers &headers, const char *body, size_t content_length, + ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const std::string &content_type); + ContentProviderWithoutLength get_multipart_content_provider( + const std::string &boundary, const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items) const; + + std::string adjust_host_string(const std::string &host) const; + + virtual bool process_socket(const Socket &socket, + std::function callback); + virtual bool is_ssl() const; +}; + +class Client { +public: + // Universal interface + explicit Client(const std::string &scheme_host_port); + + explicit Client(const std::string &scheme_host_port, + const std::string &client_cert_path, + const std::string &client_key_path); + + // HTTP only interface + explicit Client(const std::string &host, int port); + + explicit Client(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + + Client(Client &&) = default; + + ~Client(); + + bool is_valid() const; + + Result Get(const std::string &path); + Result Get(const std::string &path, const Headers &headers); + Result Get(const std::string &path, Progress progress); + Result Get(const std::string &path, const Headers &headers, + Progress progress); + Result Get(const std::string &path, ContentReceiver content_receiver); + Result Get(const std::string &path, const Headers &headers, + ContentReceiver content_receiver); + Result Get(const std::string &path, ContentReceiver content_receiver, + Progress progress); + Result Get(const std::string &path, const Headers &headers, + ContentReceiver content_receiver, Progress progress); + Result Get(const std::string &path, ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const std::string &path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const std::string &path, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress); + Result Get(const std::string &path, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress); + + Result Get(const std::string &path, const Params ¶ms, + const Headers &headers, Progress progress = nullptr); + Result Get(const std::string &path, const Params ¶ms, + const Headers &headers, ContentReceiver content_receiver, + Progress progress = nullptr); + Result Get(const std::string &path, const Params ¶ms, + const Headers &headers, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress = nullptr); + + Result Head(const std::string &path); + Result Head(const std::string &path, const Headers &headers); + + Result Post(const std::string &path); + Result Post(const std::string &path, const Headers &headers); + Result Post(const std::string &path, const char *body, size_t content_length, + const std::string &content_type); + Result Post(const std::string &path, const Headers &headers, const char *body, + size_t content_length, const std::string &content_type); + Result Post(const std::string &path, const std::string &body, + const std::string &content_type); + Result Post(const std::string &path, const Headers &headers, + const std::string &body, const std::string &content_type); + Result Post(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type); + Result Post(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Post(const std::string &path, const Headers &headers, + size_t content_length, ContentProvider content_provider, + const std::string &content_type); + Result Post(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Post(const std::string &path, const Params ¶ms); + Result Post(const std::string &path, const Headers &headers, + const Params ¶ms); + Result Post(const std::string &path, const MultipartFormDataItems &items); + Result Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items); + Result Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, const std::string &boundary); + Result Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items); + + Result Put(const std::string &path); + Result Put(const std::string &path, const char *body, size_t content_length, + const std::string &content_type); + Result Put(const std::string &path, const Headers &headers, const char *body, + size_t content_length, const std::string &content_type); + Result Put(const std::string &path, const std::string &body, + const std::string &content_type); + Result Put(const std::string &path, const Headers &headers, + const std::string &body, const std::string &content_type); + Result Put(const std::string &path, size_t content_length, + ContentProvider content_provider, const std::string &content_type); + Result Put(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Put(const std::string &path, const Headers &headers, + size_t content_length, ContentProvider content_provider, + const std::string &content_type); + Result Put(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Put(const std::string &path, const Params ¶ms); + Result Put(const std::string &path, const Headers &headers, + const Params ¶ms); + Result Put(const std::string &path, const MultipartFormDataItems &items); + Result Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items); + Result Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, const std::string &boundary); + Result Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items); + + Result Patch(const std::string &path); + Result Patch(const std::string &path, const char *body, size_t content_length, + const std::string &content_type); + Result Patch(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type); + Result Patch(const std::string &path, const std::string &body, + const std::string &content_type); + Result Patch(const std::string &path, const Headers &headers, + const std::string &body, const std::string &content_type); + Result Patch(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type); + Result Patch(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + Result Patch(const std::string &path, const Headers &headers, + size_t content_length, ContentProvider content_provider, + const std::string &content_type); + Result Patch(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type); + + Result Delete(const std::string &path); + Result Delete(const std::string &path, const Headers &headers); + Result Delete(const std::string &path, const char *body, + size_t content_length, const std::string &content_type); + Result Delete(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type); + Result Delete(const std::string &path, const std::string &body, + const std::string &content_type); + Result Delete(const std::string &path, const Headers &headers, + const std::string &body, const std::string &content_type); + + Result Options(const std::string &path); + Result Options(const std::string &path, const Headers &headers); + + bool send(Request &req, Response &res, Error &error); + Result send(const Request &req); + + void stop(); + + std::string host() const; + int port() const; + + size_t is_socket_open() const; + socket_t socket() const; + + void set_hostname_addr_map(std::map addr_map); + + void set_default_headers(Headers headers); + + void + set_header_writer(std::function const &writer); + + void set_address_family(int family); + void set_tcp_nodelay(bool on); + void set_socket_options(SocketOptions socket_options); + + void set_connection_timeout(time_t sec, time_t usec = 0); + template + void + set_connection_timeout(const std::chrono::duration &duration); + + void set_read_timeout(time_t sec, time_t usec = 0); + template + void set_read_timeout(const std::chrono::duration &duration); + + void set_write_timeout(time_t sec, time_t usec = 0); + template + void set_write_timeout(const std::chrono::duration &duration); + + void set_basic_auth(const std::string &username, const std::string &password); + void set_bearer_token_auth(const std::string &token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_digest_auth(const std::string &username, + const std::string &password); +#endif + + void set_keep_alive(bool on); + void set_follow_location(bool on); + + void set_url_encode(bool on); + + void set_compress(bool on); + + void set_decompress(bool on); + + void set_interface(const std::string &intf); + + void set_proxy(const std::string &host, int port); + void set_proxy_basic_auth(const std::string &username, + const std::string &password); + void set_proxy_bearer_token_auth(const std::string &token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_proxy_digest_auth(const std::string &username, + const std::string &password); +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void enable_server_certificate_verification(bool enabled); +#endif + + void set_logger(Logger logger); + + // SSL +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_ca_cert_path(const std::string &ca_cert_file_path, + const std::string &ca_cert_dir_path = std::string()); + + void set_ca_cert_store(X509_STORE *ca_cert_store); + void load_ca_cert_store(const char *ca_cert, std::size_t size); + + long get_openssl_verify_result() const; + + SSL_CTX *ssl_context() const; +#endif + +private: + std::unique_ptr cli_; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + bool is_ssl_ = false; +#endif +}; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +class SSLServer : public Server { +public: + SSLServer(const char *cert_path, const char *private_key_path, + const char *client_ca_cert_file_path = nullptr, + const char *client_ca_cert_dir_path = nullptr, + const char *private_key_password = nullptr); + + SSLServer(X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store = nullptr); + + SSLServer( + const std::function &setup_ssl_ctx_callback); + + ~SSLServer() override; + + bool is_valid() const override; + + SSL_CTX *ssl_context() const; + +private: + bool process_and_close_socket(socket_t sock) override; + + SSL_CTX *ctx_; + std::mutex ctx_mutex_; +}; + +class SSLClient : public ClientImpl { +public: + explicit SSLClient(const std::string &host); + + explicit SSLClient(const std::string &host, int port); + + explicit SSLClient(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + + explicit SSLClient(const std::string &host, int port, X509 *client_cert, + EVP_PKEY *client_key); + + ~SSLClient() override; + + bool is_valid() const override; + + void set_ca_cert_store(X509_STORE *ca_cert_store); + void load_ca_cert_store(const char *ca_cert, std::size_t size); + + long get_openssl_verify_result() const; + + SSL_CTX *ssl_context() const; + +private: + bool create_and_connect_socket(Socket &socket, Error &error) override; + void shutdown_ssl(Socket &socket, bool shutdown_gracefully) override; + void shutdown_ssl_impl(Socket &socket, bool shutdown_gracefully); + + bool process_socket(const Socket &socket, + std::function callback) override; + bool is_ssl() const override; + + bool connect_with_proxy(Socket &sock, Response &res, bool &success, + Error &error); + bool initialize_ssl(Socket &socket, Error &error); + + bool load_certs(); + + bool verify_host(X509 *server_cert) const; + bool verify_host_with_subject_alt_name(X509 *server_cert) const; + bool verify_host_with_common_name(X509 *server_cert) const; + bool check_host_name(const char *pattern, size_t pattern_len) const; + + SSL_CTX *ctx_; + std::mutex ctx_mutex_; + std::once_flag initialize_cert_; + + std::vector host_components_; + + long verify_result_ = 0; + + friend class ClientImpl; +}; +#endif + +/* + * Implementation of template methods. + */ + +namespace detail { + +template +inline void duration_to_sec_and_usec(const T &duration, U callback) { + auto sec = std::chrono::duration_cast(duration).count(); + auto usec = std::chrono::duration_cast( + duration - std::chrono::seconds(sec)) + .count(); + callback(static_cast(sec), static_cast(usec)); +} + +inline uint64_t get_header_value_u64(const Headers &headers, + const std::string &key, size_t id, + uint64_t def) { + auto rng = headers.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { + return std::strtoull(it->second.data(), nullptr, 10); + } + return def; +} + +} // namespace detail + +inline uint64_t Request::get_header_value_u64(const std::string &key, + size_t id) const { + return detail::get_header_value_u64(headers, key, id, 0); +} + +inline uint64_t Response::get_header_value_u64(const std::string &key, + size_t id) const { + return detail::get_header_value_u64(headers, key, id, 0); +} + +template +inline ssize_t Stream::write_format(const char *fmt, const Args &...args) { + const auto bufsiz = 2048; + std::array buf{}; + + auto sn = snprintf(buf.data(), buf.size() - 1, fmt, args...); + if (sn <= 0) { return sn; } + + auto n = static_cast(sn); + + if (n >= buf.size() - 1) { + std::vector glowable_buf(buf.size()); + + while (n >= glowable_buf.size() - 1) { + glowable_buf.resize(glowable_buf.size() * 2); + n = static_cast( + snprintf(&glowable_buf[0], glowable_buf.size() - 1, fmt, args...)); + } + return write(&glowable_buf[0], n); + } else { + return write(buf.data(), n); + } +} + +inline void default_socket_options(socket_t sock) { + int yes = 1; +#ifdef _WIN32 + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + reinterpret_cast(&yes), sizeof(yes)); + setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, + reinterpret_cast(&yes), sizeof(yes)); +#else +#ifdef SO_REUSEPORT + setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, + reinterpret_cast(&yes), sizeof(yes)); +#else + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + reinterpret_cast(&yes), sizeof(yes)); +#endif +#endif +} + +inline const char *status_message(int status) { + switch (status) { + case StatusCode::Continue_100: return "Continue"; + case StatusCode::SwitchingProtocol_101: return "Switching Protocol"; + case StatusCode::Processing_102: return "Processing"; + case StatusCode::EarlyHints_103: return "Early Hints"; + case StatusCode::OK_200: return "OK"; + case StatusCode::Created_201: return "Created"; + case StatusCode::Accepted_202: return "Accepted"; + case StatusCode::NonAuthoritativeInformation_203: + return "Non-Authoritative Information"; + case StatusCode::NoContent_204: return "No Content"; + case StatusCode::ResetContent_205: return "Reset Content"; + case StatusCode::PartialContent_206: return "Partial Content"; + case StatusCode::MultiStatus_207: return "Multi-Status"; + case StatusCode::AlreadyReported_208: return "Already Reported"; + case StatusCode::IMUsed_226: return "IM Used"; + case StatusCode::MultipleChoices_300: return "Multiple Choices"; + case StatusCode::MovedPermanently_301: return "Moved Permanently"; + case StatusCode::Found_302: return "Found"; + case StatusCode::SeeOther_303: return "See Other"; + case StatusCode::NotModified_304: return "Not Modified"; + case StatusCode::UseProxy_305: return "Use Proxy"; + case StatusCode::unused_306: return "unused"; + case StatusCode::TemporaryRedirect_307: return "Temporary Redirect"; + case StatusCode::PermanentRedirect_308: return "Permanent Redirect"; + case StatusCode::BadRequest_400: return "Bad Request"; + case StatusCode::Unauthorized_401: return "Unauthorized"; + case StatusCode::PaymentRequired_402: return "Payment Required"; + case StatusCode::Forbidden_403: return "Forbidden"; + case StatusCode::NotFound_404: return "Not Found"; + case StatusCode::MethodNotAllowed_405: return "Method Not Allowed"; + case StatusCode::NotAcceptable_406: return "Not Acceptable"; + case StatusCode::ProxyAuthenticationRequired_407: + return "Proxy Authentication Required"; + case StatusCode::RequestTimeout_408: return "Request Timeout"; + case StatusCode::Conflict_409: return "Conflict"; + case StatusCode::Gone_410: return "Gone"; + case StatusCode::LengthRequired_411: return "Length Required"; + case StatusCode::PreconditionFailed_412: return "Precondition Failed"; + case StatusCode::PayloadTooLarge_413: return "Payload Too Large"; + case StatusCode::UriTooLong_414: return "URI Too Long"; + case StatusCode::UnsupportedMediaType_415: return "Unsupported Media Type"; + case StatusCode::RangeNotSatisfiable_416: return "Range Not Satisfiable"; + case StatusCode::ExpectationFailed_417: return "Expectation Failed"; + case StatusCode::ImATeapot_418: return "I'm a teapot"; + case StatusCode::MisdirectedRequest_421: return "Misdirected Request"; + case StatusCode::UnprocessableContent_422: return "Unprocessable Content"; + case StatusCode::Locked_423: return "Locked"; + case StatusCode::FailedDependency_424: return "Failed Dependency"; + case StatusCode::TooEarly_425: return "Too Early"; + case StatusCode::UpgradeRequired_426: return "Upgrade Required"; + case StatusCode::PreconditionRequired_428: return "Precondition Required"; + case StatusCode::TooManyRequests_429: return "Too Many Requests"; + case StatusCode::RequestHeaderFieldsTooLarge_431: + return "Request Header Fields Too Large"; + case StatusCode::UnavailableForLegalReasons_451: + return "Unavailable For Legal Reasons"; + case StatusCode::NotImplemented_501: return "Not Implemented"; + case StatusCode::BadGateway_502: return "Bad Gateway"; + case StatusCode::ServiceUnavailable_503: return "Service Unavailable"; + case StatusCode::GatewayTimeout_504: return "Gateway Timeout"; + case StatusCode::HttpVersionNotSupported_505: + return "HTTP Version Not Supported"; + case StatusCode::VariantAlsoNegotiates_506: return "Variant Also Negotiates"; + case StatusCode::InsufficientStorage_507: return "Insufficient Storage"; + case StatusCode::LoopDetected_508: return "Loop Detected"; + case StatusCode::NotExtended_510: return "Not Extended"; + case StatusCode::NetworkAuthenticationRequired_511: + return "Network Authentication Required"; + + default: + case StatusCode::InternalServerError_500: return "Internal Server Error"; + } +} + +inline std::string get_bearer_token_auth(const Request &req) { + if (req.has_header("Authorization")) { + static std::string BearerHeaderPrefix = "Bearer "; + return req.get_header_value("Authorization") + .substr(BearerHeaderPrefix.length()); + } + return ""; +} + +template +inline Server & +Server::set_read_timeout(const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_read_timeout(sec, usec); }); + return *this; +} + +template +inline Server & +Server::set_write_timeout(const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_write_timeout(sec, usec); }); + return *this; +} + +template +inline Server & +Server::set_idle_interval(const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_idle_interval(sec, usec); }); + return *this; +} + +inline std::string to_string(const Error error) { + switch (error) { + case Error::Success: return "Success (no error)"; + case Error::Connection: return "Could not establish connection"; + case Error::BindIPAddress: return "Failed to bind IP address"; + case Error::Read: return "Failed to read connection"; + case Error::Write: return "Failed to write connection"; + case Error::ExceedRedirectCount: return "Maximum redirect count exceeded"; + case Error::Canceled: return "Connection handling canceled"; + case Error::SSLConnection: return "SSL connection failed"; + case Error::SSLLoadingCerts: return "SSL certificate loading failed"; + case Error::SSLServerVerification: return "SSL server verification failed"; + case Error::UnsupportedMultipartBoundaryChars: + return "Unsupported HTTP multipart boundary characters"; + case Error::Compression: return "Compression failed"; + case Error::ConnectionTimeout: return "Connection timed out"; + case Error::ProxyConnection: return "Proxy connection failed"; + case Error::Unknown: return "Unknown"; + default: break; + } + + return "Invalid"; +} + +inline std::ostream &operator<<(std::ostream &os, const Error &obj) { + os << to_string(obj); + os << " (" << static_cast::type>(obj) << ')'; + return os; +} + +inline uint64_t Result::get_request_header_value_u64(const std::string &key, + size_t id) const { + return detail::get_header_value_u64(request_headers_, key, id, 0); +} + +template +inline void ClientImpl::set_connection_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) { + set_connection_timeout(sec, usec); + }); +} + +template +inline void ClientImpl::set_read_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_read_timeout(sec, usec); }); +} + +template +inline void ClientImpl::set_write_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec( + duration, [&](time_t sec, time_t usec) { set_write_timeout(sec, usec); }); +} + +template +inline void Client::set_connection_timeout( + const std::chrono::duration &duration) { + cli_->set_connection_timeout(duration); +} + +template +inline void +Client::set_read_timeout(const std::chrono::duration &duration) { + cli_->set_read_timeout(duration); +} + +template +inline void +Client::set_write_timeout(const std::chrono::duration &duration) { + cli_->set_write_timeout(duration); +} + +/* + * Forward declarations and types that will be part of the .h file if split into + * .h + .cc. + */ + +std::string hosted_at(const std::string &hostname); + +void hosted_at(const std::string &hostname, std::vector &addrs); + +std::string append_query_params(const std::string &path, const Params ¶ms); + +std::pair make_range_header(const Ranges &ranges); + +std::pair +make_basic_authentication_header(const std::string &username, + const std::string &password, + bool is_proxy = false); + +namespace detail { + +std::string encode_query_param(const std::string &value); + +std::string decode_url(const std::string &s, bool convert_plus_to_space); + +void read_file(const std::string &path, std::string &out); + +std::string trim_copy(const std::string &s); + +void split(const char *b, const char *e, char d, + std::function fn); + +void split(const char *b, const char *e, char d, size_t m, + std::function fn); + +bool process_client_socket(socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, + std::function callback); + +socket_t create_client_socket( + const std::string &host, const std::string &ip, int port, + int address_family, bool tcp_nodelay, SocketOptions socket_options, + time_t connection_timeout_sec, time_t connection_timeout_usec, + time_t read_timeout_sec, time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, const std::string &intf, Error &error); + +const char *get_header_value(const Headers &headers, const std::string &key, + size_t id = 0, const char *def = nullptr); + +std::string params_to_query_str(const Params ¶ms); + +void parse_query_text(const std::string &s, Params ¶ms); + +bool parse_multipart_boundary(const std::string &content_type, + std::string &boundary); + +bool parse_range_header(const std::string &s, Ranges &ranges); + +int close_socket(socket_t sock); + +ssize_t send_socket(socket_t sock, const void *ptr, size_t size, int flags); + +ssize_t read_socket(socket_t sock, void *ptr, size_t size, int flags); + +enum class EncodingType { None = 0, Gzip, Brotli }; + +EncodingType encoding_type(const Request &req, const Response &res); + +class BufferStream : public Stream { +public: + BufferStream() = default; + ~BufferStream() override = default; + + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + void get_local_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + + const std::string &get_buffer() const; + +private: + std::string buffer; + size_t position = 0; +}; + +class compressor { +public: + virtual ~compressor() = default; + + typedef std::function Callback; + virtual bool compress(const char *data, size_t data_length, bool last, + Callback callback) = 0; +}; + +class decompressor { +public: + virtual ~decompressor() = default; + + virtual bool is_valid() const = 0; + + typedef std::function Callback; + virtual bool decompress(const char *data, size_t data_length, + Callback callback) = 0; +}; + +class nocompressor : public compressor { +public: + ~nocompressor() override = default; + + bool compress(const char *data, size_t data_length, bool /*last*/, + Callback callback) override; +}; + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +class gzip_compressor : public compressor { +public: + gzip_compressor(); + ~gzip_compressor() override; + + bool compress(const char *data, size_t data_length, bool last, + Callback callback) override; + +private: + bool is_valid_ = false; + z_stream strm_; +}; + +class gzip_decompressor : public decompressor { +public: + gzip_decompressor(); + ~gzip_decompressor() override; + + bool is_valid() const override; + + bool decompress(const char *data, size_t data_length, + Callback callback) override; + +private: + bool is_valid_ = false; + z_stream strm_; +}; +#endif + +#ifdef CPPHTTPLIB_BROTLI_SUPPORT +class brotli_compressor : public compressor { +public: + brotli_compressor(); + ~brotli_compressor(); + + bool compress(const char *data, size_t data_length, bool last, + Callback callback) override; + +private: + BrotliEncoderState *state_ = nullptr; +}; + +class brotli_decompressor : public decompressor { +public: + brotli_decompressor(); + ~brotli_decompressor(); + + bool is_valid() const override; + + bool decompress(const char *data, size_t data_length, + Callback callback) override; + +private: + BrotliDecoderResult decoder_r; + BrotliDecoderState *decoder_s = nullptr; +}; +#endif + +// NOTE: until the read size reaches `fixed_buffer_size`, use `fixed_buffer` +// to store data. The call can set memory on stack for performance. +class stream_line_reader { +public: + stream_line_reader(Stream &strm, char *fixed_buffer, + size_t fixed_buffer_size); + const char *ptr() const; + size_t size() const; + bool end_with_crlf() const; + bool getline(); + +private: + void append(char c); + + Stream &strm_; + char *fixed_buffer_; + const size_t fixed_buffer_size_; + size_t fixed_buffer_used_size_ = 0; + std::string glowable_buffer_; +}; + +class mmap { +public: + mmap(const char *path); + ~mmap(); + + bool open(const char *path); + void close(); + + bool is_open() const; + size_t size() const; + const char *data() const; + +private: +#if defined(_WIN32) + HANDLE hFile_; + HANDLE hMapping_; +#else + int fd_; +#endif + size_t size_; + void *addr_; +}; + +} // namespace detail + +// ---------------------------------------------------------------------------- + +/* + * Implementation that will be part of the .cc file if split into .h + .cc. + */ + +namespace detail { + +inline bool is_hex(char c, int &v) { + if (0x20 <= c && isdigit(c)) { + v = c - '0'; + return true; + } else if ('A' <= c && c <= 'F') { + v = c - 'A' + 10; + return true; + } else if ('a' <= c && c <= 'f') { + v = c - 'a' + 10; + return true; + } + return false; +} + +inline bool from_hex_to_i(const std::string &s, size_t i, size_t cnt, + int &val) { + if (i >= s.size()) { return false; } + + val = 0; + for (; cnt; i++, cnt--) { + if (!s[i]) { return false; } + auto v = 0; + if (is_hex(s[i], v)) { + val = val * 16 + v; + } else { + return false; + } + } + return true; +} + +inline std::string from_i_to_hex(size_t n) { + static const auto charset = "0123456789abcdef"; + std::string ret; + do { + ret = charset[n & 15] + ret; + n >>= 4; + } while (n > 0); + return ret; +} + +inline size_t to_utf8(int code, char *buff) { + if (code < 0x0080) { + buff[0] = static_cast(code & 0x7F); + return 1; + } else if (code < 0x0800) { + buff[0] = static_cast(0xC0 | ((code >> 6) & 0x1F)); + buff[1] = static_cast(0x80 | (code & 0x3F)); + return 2; + } else if (code < 0xD800) { + buff[0] = static_cast(0xE0 | ((code >> 12) & 0xF)); + buff[1] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[2] = static_cast(0x80 | (code & 0x3F)); + return 3; + } else if (code < 0xE000) { // D800 - DFFF is invalid... + return 0; + } else if (code < 0x10000) { + buff[0] = static_cast(0xE0 | ((code >> 12) & 0xF)); + buff[1] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[2] = static_cast(0x80 | (code & 0x3F)); + return 3; + } else if (code < 0x110000) { + buff[0] = static_cast(0xF0 | ((code >> 18) & 0x7)); + buff[1] = static_cast(0x80 | ((code >> 12) & 0x3F)); + buff[2] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[3] = static_cast(0x80 | (code & 0x3F)); + return 4; + } + + // NOTREACHED + return 0; +} + +// NOTE: This code came up with the following stackoverflow post: +// https://stackoverflow.com/questions/180947/base64-decode-snippet-in-c +inline std::string base64_encode(const std::string &in) { + static const auto lookup = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + std::string out; + out.reserve(in.size()); + + auto val = 0; + auto valb = -6; + + for (auto c : in) { + val = (val << 8) + static_cast(c); + valb += 8; + while (valb >= 0) { + out.push_back(lookup[(val >> valb) & 0x3F]); + valb -= 6; + } + } + + if (valb > -6) { out.push_back(lookup[((val << 8) >> (valb + 8)) & 0x3F]); } + + while (out.size() % 4) { + out.push_back('='); + } + + return out; +} + +inline bool is_file(const std::string &path) { +#ifdef _WIN32 + return _access_s(path.c_str(), 0) == 0; +#else + struct stat st; + return stat(path.c_str(), &st) >= 0 && S_ISREG(st.st_mode); +#endif +} + +inline bool is_dir(const std::string &path) { + struct stat st; + return stat(path.c_str(), &st) >= 0 && S_ISDIR(st.st_mode); +} + +inline bool is_valid_path(const std::string &path) { + size_t level = 0; + size_t i = 0; + + // Skip slash + while (i < path.size() && path[i] == '/') { + i++; + } + + while (i < path.size()) { + // Read component + auto beg = i; + while (i < path.size() && path[i] != '/') { + if (path[i] == '\0') { + return false; + } else if (path[i] == '\\') { + return false; + } + i++; + } + + auto len = i - beg; + assert(len > 0); + + if (!path.compare(beg, len, ".")) { + ; + } else if (!path.compare(beg, len, "..")) { + if (level == 0) { return false; } + level--; + } else { + level++; + } + + // Skip slash + while (i < path.size() && path[i] == '/') { + i++; + } + } + + return true; +} + +inline std::string encode_query_param(const std::string &value) { + std::ostringstream escaped; + escaped.fill('0'); + escaped << std::hex; + + for (auto c : value) { + if (std::isalnum(static_cast(c)) || c == '-' || c == '_' || + c == '.' || c == '!' || c == '~' || c == '*' || c == '\'' || c == '(' || + c == ')') { + escaped << c; + } else { + escaped << std::uppercase; + escaped << '%' << std::setw(2) + << static_cast(static_cast(c)); + escaped << std::nouppercase; + } + } + + return escaped.str(); +} + +inline std::string encode_url(const std::string &s) { + std::string result; + result.reserve(s.size()); + + for (size_t i = 0; s[i]; i++) { + switch (s[i]) { + case ' ': result += "%20"; break; + case '+': result += "%2B"; break; + case '\r': result += "%0D"; break; + case '\n': result += "%0A"; break; + case '\'': result += "%27"; break; + case ',': result += "%2C"; break; + // case ':': result += "%3A"; break; // ok? probably... + case ';': result += "%3B"; break; + default: + auto c = static_cast(s[i]); + if (c >= 0x80) { + result += '%'; + char hex[4]; + auto len = snprintf(hex, sizeof(hex) - 1, "%02X", c); + assert(len == 2); + result.append(hex, static_cast(len)); + } else { + result += s[i]; + } + break; + } + } + + return result; +} + +inline std::string decode_url(const std::string &s, + bool convert_plus_to_space) { + std::string result; + + for (size_t i = 0; i < s.size(); i++) { + if (s[i] == '%' && i + 1 < s.size()) { + if (s[i + 1] == 'u') { + auto val = 0; + if (from_hex_to_i(s, i + 2, 4, val)) { + // 4 digits Unicode codes + char buff[4]; + size_t len = to_utf8(val, buff); + if (len > 0) { result.append(buff, len); } + i += 5; // 'u0000' + } else { + result += s[i]; + } + } else { + auto val = 0; + if (from_hex_to_i(s, i + 1, 2, val)) { + // 2 digits hex codes + result += static_cast(val); + i += 2; // '00' + } else { + result += s[i]; + } + } + } else if (convert_plus_to_space && s[i] == '+') { + result += ' '; + } else { + result += s[i]; + } + } + + return result; +} + +inline void read_file(const std::string &path, std::string &out) { + std::ifstream fs(path, std::ios_base::binary); + fs.seekg(0, std::ios_base::end); + auto size = fs.tellg(); + fs.seekg(0); + out.resize(static_cast(size)); + fs.read(&out[0], static_cast(size)); +} + +inline std::string file_extension(const std::string &path) { + std::smatch m; + static auto re = std::regex("\\.([a-zA-Z0-9]+)$"); + if (std::regex_search(path, m, re)) { return m[1].str(); } + return std::string(); +} + +inline bool is_space_or_tab(char c) { return c == ' ' || c == '\t'; } + +inline std::pair trim(const char *b, const char *e, size_t left, + size_t right) { + while (b + left < e && is_space_or_tab(b[left])) { + left++; + } + while (right > 0 && is_space_or_tab(b[right - 1])) { + right--; + } + return std::make_pair(left, right); +} + +inline std::string trim_copy(const std::string &s) { + auto r = trim(s.data(), s.data() + s.size(), 0, s.size()); + return s.substr(r.first, r.second - r.first); +} + +inline std::string trim_double_quotes_copy(const std::string &s) { + if (s.length() >= 2 && s.front() == '"' && s.back() == '"') { + return s.substr(1, s.size() - 2); + } + return s; +} + +inline void split(const char *b, const char *e, char d, + std::function fn) { + return split(b, e, d, (std::numeric_limits::max)(), std::move(fn)); +} + +inline void split(const char *b, const char *e, char d, size_t m, + std::function fn) { + size_t i = 0; + size_t beg = 0; + size_t count = 1; + + while (e ? (b + i < e) : (b[i] != '\0')) { + if (b[i] == d && count < m) { + auto r = trim(b, e, beg, i); + if (r.first < r.second) { fn(&b[r.first], &b[r.second]); } + beg = i + 1; + count++; + } + i++; + } + + if (i) { + auto r = trim(b, e, beg, i); + if (r.first < r.second) { fn(&b[r.first], &b[r.second]); } + } +} + +inline stream_line_reader::stream_line_reader(Stream &strm, char *fixed_buffer, + size_t fixed_buffer_size) + : strm_(strm), fixed_buffer_(fixed_buffer), + fixed_buffer_size_(fixed_buffer_size) {} + +inline const char *stream_line_reader::ptr() const { + if (glowable_buffer_.empty()) { + return fixed_buffer_; + } else { + return glowable_buffer_.data(); + } +} + +inline size_t stream_line_reader::size() const { + if (glowable_buffer_.empty()) { + return fixed_buffer_used_size_; + } else { + return glowable_buffer_.size(); + } +} + +inline bool stream_line_reader::end_with_crlf() const { + auto end = ptr() + size(); + return size() >= 2 && end[-2] == '\r' && end[-1] == '\n'; +} + +inline bool stream_line_reader::getline() { + fixed_buffer_used_size_ = 0; + glowable_buffer_.clear(); + + for (size_t i = 0;; i++) { + char byte; + auto n = strm_.read(&byte, 1); + + if (n < 0) { + return false; + } else if (n == 0) { + if (i == 0) { + return false; + } else { + break; + } + } + + append(byte); + + if (byte == '\n') { break; } + } + + return true; +} + +inline void stream_line_reader::append(char c) { + if (fixed_buffer_used_size_ < fixed_buffer_size_ - 1) { + fixed_buffer_[fixed_buffer_used_size_++] = c; + fixed_buffer_[fixed_buffer_used_size_] = '\0'; + } else { + if (glowable_buffer_.empty()) { + assert(fixed_buffer_[fixed_buffer_used_size_] == '\0'); + glowable_buffer_.assign(fixed_buffer_, fixed_buffer_used_size_); + } + glowable_buffer_ += c; + } +} + +inline mmap::mmap(const char *path) +#if defined(_WIN32) + : hFile_(NULL), hMapping_(NULL) +#else + : fd_(-1) +#endif + , + size_(0), addr_(nullptr) { + open(path); +} + +inline mmap::~mmap() { close(); } + +inline bool mmap::open(const char *path) { + close(); + +#if defined(_WIN32) + hFile_ = ::CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile_ == INVALID_HANDLE_VALUE) { return false; } + + size_ = ::GetFileSize(hFile_, NULL); + + hMapping_ = ::CreateFileMapping(hFile_, NULL, PAGE_READONLY, 0, 0, NULL); + + if (hMapping_ == NULL) { + close(); + return false; + } + + addr_ = ::MapViewOfFile(hMapping_, FILE_MAP_READ, 0, 0, 0); +#else + fd_ = ::open(path, O_RDONLY); + if (fd_ == -1) { return false; } + + struct stat sb; + if (fstat(fd_, &sb) == -1) { + close(); + return false; + } + size_ = static_cast(sb.st_size); + + addr_ = ::mmap(NULL, size_, PROT_READ, MAP_PRIVATE, fd_, 0); +#endif + + if (addr_ == nullptr) { + close(); + return false; + } + + return true; +} + +inline bool mmap::is_open() const { return addr_ != nullptr; } + +inline size_t mmap::size() const { return size_; } + +inline const char *mmap::data() const { + return static_cast(addr_); +} + +inline void mmap::close() { +#if defined(_WIN32) + if (addr_) { + ::UnmapViewOfFile(addr_); + addr_ = nullptr; + } + + if (hMapping_) { + ::CloseHandle(hMapping_); + hMapping_ = NULL; + } + + if (hFile_ != INVALID_HANDLE_VALUE) { + ::CloseHandle(hFile_); + hFile_ = INVALID_HANDLE_VALUE; + } +#else + if (addr_ != nullptr) { + munmap(addr_, size_); + addr_ = nullptr; + } + + if (fd_ != -1) { + ::close(fd_); + fd_ = -1; + } +#endif + size_ = 0; +} +inline int close_socket(socket_t sock) { +#ifdef _WIN32 + return closesocket(sock); +#else + return close(sock); +#endif +} + +template inline ssize_t handle_EINTR(T fn) { + ssize_t res = 0; + while (true) { + res = fn(); + if (res < 0 && errno == EINTR) { continue; } + break; + } + return res; +} + +inline ssize_t read_socket(socket_t sock, void *ptr, size_t size, int flags) { + return handle_EINTR([&]() { + return recv(sock, +#ifdef _WIN32 + static_cast(ptr), static_cast(size), +#else + ptr, size, +#endif + flags); + }); +} + +inline ssize_t send_socket(socket_t sock, const void *ptr, size_t size, + int flags) { + return handle_EINTR([&]() { + return send(sock, +#ifdef _WIN32 + static_cast(ptr), static_cast(size), +#else + ptr, size, +#endif + flags); + }); +} + +inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLIN; + + auto timeout = static_cast(sec * 1000 + usec / 1000); + + return handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return -1; } +#endif + + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); + + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + + return handle_EINTR([&]() { + return select(static_cast(sock + 1), &fds, nullptr, nullptr, &tv); + }); +#endif +} + +inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLOUT; + + auto timeout = static_cast(sec * 1000 + usec / 1000); + + return handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return -1; } +#endif + + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); + + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + + return handle_EINTR([&]() { + return select(static_cast(sock + 1), nullptr, &fds, nullptr, &tv); + }); +#endif +} + +inline Error wait_until_socket_is_ready(socket_t sock, time_t sec, + time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLIN | POLLOUT; + + auto timeout = static_cast(sec * 1000 + usec / 1000); + + auto poll_res = handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); + + if (poll_res == 0) { return Error::ConnectionTimeout; } + + if (poll_res > 0 && pfd_read.revents & (POLLIN | POLLOUT)) { + auto error = 0; + socklen_t len = sizeof(error); + auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR, + reinterpret_cast(&error), &len); + auto successful = res >= 0 && !error; + return successful ? Error::Success : Error::Connection; + } + + return Error::Connection; +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return Error::Connection; } +#endif + + fd_set fdsr; + FD_ZERO(&fdsr); + FD_SET(sock, &fdsr); + + auto fdsw = fdsr; + auto fdse = fdsr; + + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + + auto ret = handle_EINTR([&]() { + return select(static_cast(sock + 1), &fdsr, &fdsw, &fdse, &tv); + }); + + if (ret == 0) { return Error::ConnectionTimeout; } + + if (ret > 0 && (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) { + auto error = 0; + socklen_t len = sizeof(error); + auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR, + reinterpret_cast(&error), &len); + auto successful = res >= 0 && !error; + return successful ? Error::Success : Error::Connection; + } + return Error::Connection; +#endif +} + +inline bool is_socket_alive(socket_t sock) { + const auto val = detail::select_read(sock, 0, 0); + if (val == 0) { + return true; + } else if (val < 0 && errno == EBADF) { + return false; + } + char buf[1]; + return detail::read_socket(sock, &buf[0], sizeof(buf), MSG_PEEK) > 0; +} + +class SocketStream : public Stream { +public: + SocketStream(socket_t sock, time_t read_timeout_sec, time_t read_timeout_usec, + time_t write_timeout_sec, time_t write_timeout_usec); + ~SocketStream() override; + + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + void get_local_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + +private: + socket_t sock_; + time_t read_timeout_sec_; + time_t read_timeout_usec_; + time_t write_timeout_sec_; + time_t write_timeout_usec_; + + std::vector read_buff_; + size_t read_buff_off_ = 0; + size_t read_buff_content_size_ = 0; + + static const size_t read_buff_size_ = 1024l * 4; +}; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +class SSLSocketStream : public Stream { +public: + SSLSocketStream(socket_t sock, SSL *ssl, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec); + ~SSLSocketStream() override; + + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + void get_local_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + +private: + socket_t sock_; + SSL *ssl_; + time_t read_timeout_sec_; + time_t read_timeout_usec_; + time_t write_timeout_sec_; + time_t write_timeout_usec_; +}; +#endif + +inline bool keep_alive(socket_t sock, time_t keep_alive_timeout_sec) { + using namespace std::chrono; + auto start = steady_clock::now(); + while (true) { + auto val = select_read(sock, 0, 10000); + if (val < 0) { + return false; + } else if (val == 0) { + auto current = steady_clock::now(); + auto duration = duration_cast(current - start); + auto timeout = keep_alive_timeout_sec * 1000; + if (duration.count() > timeout) { return false; } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } else { + return true; + } + } +} + +template +inline bool +process_server_socket_core(const std::atomic &svr_sock, socket_t sock, + size_t keep_alive_max_count, + time_t keep_alive_timeout_sec, T callback) { + assert(keep_alive_max_count > 0); + auto ret = false; + auto count = keep_alive_max_count; + while (svr_sock != INVALID_SOCKET && count > 0 && + keep_alive(sock, keep_alive_timeout_sec)) { + auto close_connection = count == 1; + auto connection_closed = false; + ret = callback(close_connection, connection_closed); + if (!ret || connection_closed) { break; } + count--; + } + return ret; +} + +template +inline bool +process_server_socket(const std::atomic &svr_sock, socket_t sock, + size_t keep_alive_max_count, + time_t keep_alive_timeout_sec, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, T callback) { + return process_server_socket_core( + svr_sock, sock, keep_alive_max_count, keep_alive_timeout_sec, + [&](bool close_connection, bool &connection_closed) { + SocketStream strm(sock, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm, close_connection, connection_closed); + }); +} + +inline bool process_client_socket(socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec, + std::function callback) { + SocketStream strm(sock, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm); +} + +inline int shutdown_socket(socket_t sock) { +#ifdef _WIN32 + return shutdown(sock, SD_BOTH); +#else + return shutdown(sock, SHUT_RDWR); +#endif +} + +template +socket_t create_socket(const std::string &host, const std::string &ip, int port, + int address_family, int socket_flags, bool tcp_nodelay, + SocketOptions socket_options, + BindOrConnect bind_or_connect) { + // Get address info + const char *node = nullptr; + struct addrinfo hints; + struct addrinfo *result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + + if (!ip.empty()) { + node = ip.c_str(); + // Ask getaddrinfo to convert IP in c-string to address + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_NUMERICHOST; + } else { + if (!host.empty()) { node = host.c_str(); } + hints.ai_family = address_family; + hints.ai_flags = socket_flags; + } + +#ifndef _WIN32 + if (hints.ai_family == AF_UNIX) { + const auto addrlen = host.length(); + if (addrlen > sizeof(sockaddr_un::sun_path)) { return INVALID_SOCKET; } + + auto sock = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol); + if (sock != INVALID_SOCKET) { + sockaddr_un addr{}; + addr.sun_family = AF_UNIX; + std::copy(host.begin(), host.end(), addr.sun_path); + + hints.ai_addr = reinterpret_cast(&addr); + hints.ai_addrlen = static_cast( + sizeof(addr) - sizeof(addr.sun_path) + addrlen); + + fcntl(sock, F_SETFD, FD_CLOEXEC); + if (socket_options) { socket_options(sock); } + + if (!bind_or_connect(sock, hints)) { + close_socket(sock); + sock = INVALID_SOCKET; + } + } + return sock; + } +#endif + + auto service = std::to_string(port); + + if (getaddrinfo(node, service.c_str(), &hints, &result)) { +#if defined __linux__ && !defined __ANDROID__ + res_init(); +#endif + return INVALID_SOCKET; + } + + for (auto rp = result; rp; rp = rp->ai_next) { + // Create a socket +#ifdef _WIN32 + auto sock = + WSASocketW(rp->ai_family, rp->ai_socktype, rp->ai_protocol, nullptr, 0, + WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED); + /** + * Since the WSA_FLAG_NO_HANDLE_INHERIT is only supported on Windows 7 SP1 + * and above the socket creation fails on older Windows Systems. + * + * Let's try to create a socket the old way in this case. + * + * Reference: + * https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketa + * + * WSA_FLAG_NO_HANDLE_INHERIT: + * This flag is supported on Windows 7 with SP1, Windows Server 2008 R2 with + * SP1, and later + * + */ + if (sock == INVALID_SOCKET) { + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + } +#else + auto sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); +#endif + if (sock == INVALID_SOCKET) { continue; } + +#ifndef _WIN32 + if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { + close_socket(sock); + continue; + } +#endif + + if (tcp_nodelay) { + auto yes = 1; +#ifdef _WIN32 + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + reinterpret_cast(&yes), sizeof(yes)); +#else + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + reinterpret_cast(&yes), sizeof(yes)); +#endif + } + + if (socket_options) { socket_options(sock); } + + if (rp->ai_family == AF_INET6) { + auto no = 0; +#ifdef _WIN32 + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, + reinterpret_cast(&no), sizeof(no)); +#else + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, + reinterpret_cast(&no), sizeof(no)); +#endif + } + + // bind or connect + if (bind_or_connect(sock, *rp)) { + freeaddrinfo(result); + return sock; + } + + close_socket(sock); + } + + freeaddrinfo(result); + return INVALID_SOCKET; +} + +inline void set_nonblocking(socket_t sock, bool nonblocking) { +#ifdef _WIN32 + auto flags = nonblocking ? 1UL : 0UL; + ioctlsocket(sock, FIONBIO, &flags); +#else + auto flags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, + nonblocking ? (flags | O_NONBLOCK) : (flags & (~O_NONBLOCK))); +#endif +} + +inline bool is_connection_error() { +#ifdef _WIN32 + return WSAGetLastError() != WSAEWOULDBLOCK; +#else + return errno != EINPROGRESS; +#endif +} + +inline bool bind_ip_address(socket_t sock, const std::string &host) { + struct addrinfo hints; + struct addrinfo *result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + + if (getaddrinfo(host.c_str(), "0", &hints, &result)) { return false; } + + auto ret = false; + for (auto rp = result; rp; rp = rp->ai_next) { + const auto &ai = *rp; + if (!::bind(sock, ai.ai_addr, static_cast(ai.ai_addrlen))) { + ret = true; + break; + } + } + + freeaddrinfo(result); + return ret; +} + +#if !defined _WIN32 && !defined ANDROID && !defined _AIX && !defined __MVS__ +#define USE_IF2IP +#endif + +#ifdef USE_IF2IP +inline std::string if2ip(int address_family, const std::string &ifn) { + struct ifaddrs *ifap; + getifaddrs(&ifap); + std::string addr_candidate; + for (auto ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr && ifn == ifa->ifa_name && + (AF_UNSPEC == address_family || + ifa->ifa_addr->sa_family == address_family)) { + if (ifa->ifa_addr->sa_family == AF_INET) { + auto sa = reinterpret_cast(ifa->ifa_addr); + char buf[INET_ADDRSTRLEN]; + if (inet_ntop(AF_INET, &sa->sin_addr, buf, INET_ADDRSTRLEN)) { + freeifaddrs(ifap); + return std::string(buf, INET_ADDRSTRLEN); + } + } else if (ifa->ifa_addr->sa_family == AF_INET6) { + auto sa = reinterpret_cast(ifa->ifa_addr); + if (!IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr)) { + char buf[INET6_ADDRSTRLEN] = {}; + if (inet_ntop(AF_INET6, &sa->sin6_addr, buf, INET6_ADDRSTRLEN)) { + // equivalent to mac's IN6_IS_ADDR_UNIQUE_LOCAL + auto s6_addr_head = sa->sin6_addr.s6_addr[0]; + if (s6_addr_head == 0xfc || s6_addr_head == 0xfd) { + addr_candidate = std::string(buf, INET6_ADDRSTRLEN); + } else { + freeifaddrs(ifap); + return std::string(buf, INET6_ADDRSTRLEN); + } + } + } + } + } + } + freeifaddrs(ifap); + return addr_candidate; +} +#endif + +inline socket_t create_client_socket( + const std::string &host, const std::string &ip, int port, + int address_family, bool tcp_nodelay, SocketOptions socket_options, + time_t connection_timeout_sec, time_t connection_timeout_usec, + time_t read_timeout_sec, time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, const std::string &intf, Error &error) { + auto sock = create_socket( + host, ip, port, address_family, 0, tcp_nodelay, std::move(socket_options), + [&](socket_t sock2, struct addrinfo &ai) -> bool { + if (!intf.empty()) { +#ifdef USE_IF2IP + auto ip_from_if = if2ip(address_family, intf); + if (ip_from_if.empty()) { ip_from_if = intf; } + if (!bind_ip_address(sock2, ip_from_if)) { + error = Error::BindIPAddress; + return false; + } +#endif + } + + set_nonblocking(sock2, true); + + auto ret = + ::connect(sock2, ai.ai_addr, static_cast(ai.ai_addrlen)); + + if (ret < 0) { + if (is_connection_error()) { + error = Error::Connection; + return false; + } + error = wait_until_socket_is_ready(sock2, connection_timeout_sec, + connection_timeout_usec); + if (error != Error::Success) { return false; } + } + + set_nonblocking(sock2, false); + + { +#ifdef _WIN32 + auto timeout = static_cast(read_timeout_sec * 1000 + + read_timeout_usec / 1000); + setsockopt(sock2, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&timeout), sizeof(timeout)); +#else + timeval tv; + tv.tv_sec = static_cast(read_timeout_sec); + tv.tv_usec = static_cast(read_timeout_usec); + setsockopt(sock2, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&tv), sizeof(tv)); +#endif + } + { + +#ifdef _WIN32 + auto timeout = static_cast(write_timeout_sec * 1000 + + write_timeout_usec / 1000); + setsockopt(sock2, SOL_SOCKET, SO_SNDTIMEO, + reinterpret_cast(&timeout), sizeof(timeout)); +#else + timeval tv; + tv.tv_sec = static_cast(write_timeout_sec); + tv.tv_usec = static_cast(write_timeout_usec); + setsockopt(sock2, SOL_SOCKET, SO_SNDTIMEO, + reinterpret_cast(&tv), sizeof(tv)); +#endif + } + + error = Error::Success; + return true; + }); + + if (sock != INVALID_SOCKET) { + error = Error::Success; + } else { + if (error == Error::Success) { error = Error::Connection; } + } + + return sock; +} + +inline bool get_ip_and_port(const struct sockaddr_storage &addr, + socklen_t addr_len, std::string &ip, int &port) { + if (addr.ss_family == AF_INET) { + port = ntohs(reinterpret_cast(&addr)->sin_port); + } else if (addr.ss_family == AF_INET6) { + port = + ntohs(reinterpret_cast(&addr)->sin6_port); + } else { + return false; + } + + std::array ipstr{}; + if (getnameinfo(reinterpret_cast(&addr), addr_len, + ipstr.data(), static_cast(ipstr.size()), nullptr, + 0, NI_NUMERICHOST)) { + return false; + } + + ip = ipstr.data(); + return true; +} + +inline void get_local_ip_and_port(socket_t sock, std::string &ip, int &port) { + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + if (!getsockname(sock, reinterpret_cast(&addr), + &addr_len)) { + get_ip_and_port(addr, addr_len, ip, port); + } +} + +inline void get_remote_ip_and_port(socket_t sock, std::string &ip, int &port) { + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + + if (!getpeername(sock, reinterpret_cast(&addr), + &addr_len)) { +#ifndef _WIN32 + if (addr.ss_family == AF_UNIX) { +#if defined(__linux__) + struct ucred ucred; + socklen_t len = sizeof(ucred); + if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == 0) { + port = ucred.pid; + } +#elif defined(SOL_LOCAL) && defined(SO_PEERPID) // __APPLE__ + pid_t pid; + socklen_t len = sizeof(pid); + if (getsockopt(sock, SOL_LOCAL, SO_PEERPID, &pid, &len) == 0) { + port = pid; + } +#endif + return; + } +#endif + get_ip_and_port(addr, addr_len, ip, port); + } +} + +inline constexpr unsigned int str2tag_core(const char *s, size_t l, + unsigned int h) { + return (l == 0) + ? h + : str2tag_core( + s + 1, l - 1, + // Unsets the 6 high bits of h, therefore no overflow happens + (((std::numeric_limits::max)() >> 6) & + h * 33) ^ + static_cast(*s)); +} + +inline unsigned int str2tag(const std::string &s) { + return str2tag_core(s.data(), s.size(), 0); +} + +namespace udl { + +inline constexpr unsigned int operator"" _t(const char *s, size_t l) { + return str2tag_core(s, l, 0); +} + +} // namespace udl + +inline std::string +find_content_type(const std::string &path, + const std::map &user_data, + const std::string &default_content_type) { + auto ext = file_extension(path); + + auto it = user_data.find(ext); + if (it != user_data.end()) { return it->second; } + + using udl::operator""_t; + + switch (str2tag(ext)) { + default: return default_content_type; + + case "css"_t: return "text/css"; + case "csv"_t: return "text/csv"; + case "htm"_t: + case "html"_t: return "text/html"; + case "js"_t: + case "mjs"_t: return "text/javascript"; + case "txt"_t: return "text/plain"; + case "vtt"_t: return "text/vtt"; + + case "apng"_t: return "image/apng"; + case "avif"_t: return "image/avif"; + case "bmp"_t: return "image/bmp"; + case "gif"_t: return "image/gif"; + case "png"_t: return "image/png"; + case "svg"_t: return "image/svg+xml"; + case "webp"_t: return "image/webp"; + case "ico"_t: return "image/x-icon"; + case "tif"_t: return "image/tiff"; + case "tiff"_t: return "image/tiff"; + case "jpg"_t: + case "jpeg"_t: return "image/jpeg"; + + case "mp4"_t: return "video/mp4"; + case "mpeg"_t: return "video/mpeg"; + case "webm"_t: return "video/webm"; + + case "mp3"_t: return "audio/mp3"; + case "mpga"_t: return "audio/mpeg"; + case "weba"_t: return "audio/webm"; + case "wav"_t: return "audio/wave"; + + case "otf"_t: return "font/otf"; + case "ttf"_t: return "font/ttf"; + case "woff"_t: return "font/woff"; + case "woff2"_t: return "font/woff2"; + + case "7z"_t: return "application/x-7z-compressed"; + case "atom"_t: return "application/atom+xml"; + case "pdf"_t: return "application/pdf"; + case "json"_t: return "application/json"; + case "rss"_t: return "application/rss+xml"; + case "tar"_t: return "application/x-tar"; + case "xht"_t: + case "xhtml"_t: return "application/xhtml+xml"; + case "xslt"_t: return "application/xslt+xml"; + case "xml"_t: return "application/xml"; + case "gz"_t: return "application/gzip"; + case "zip"_t: return "application/zip"; + case "wasm"_t: return "application/wasm"; + } +} + +inline bool can_compress_content_type(const std::string &content_type) { + using udl::operator""_t; + + auto tag = str2tag(content_type); + + switch (tag) { + case "image/svg+xml"_t: + case "application/javascript"_t: + case "application/json"_t: + case "application/xml"_t: + case "application/protobuf"_t: + case "application/xhtml+xml"_t: return true; + + default: + return !content_type.rfind("text/", 0) && tag != "text/event-stream"_t; + } +} + +inline EncodingType encoding_type(const Request &req, const Response &res) { + auto ret = + detail::can_compress_content_type(res.get_header_value("Content-Type")); + if (!ret) { return EncodingType::None; } + + const auto &s = req.get_header_value("Accept-Encoding"); + (void)(s); + +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + // TODO: 'Accept-Encoding' has br, not br;q=0 + ret = s.find("br") != std::string::npos; + if (ret) { return EncodingType::Brotli; } +#endif + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + // TODO: 'Accept-Encoding' has gzip, not gzip;q=0 + ret = s.find("gzip") != std::string::npos; + if (ret) { return EncodingType::Gzip; } +#endif + + return EncodingType::None; +} + +inline bool nocompressor::compress(const char *data, size_t data_length, + bool /*last*/, Callback callback) { + if (!data_length) { return true; } + return callback(data, data_length); +} + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +inline gzip_compressor::gzip_compressor() { + std::memset(&strm_, 0, sizeof(strm_)); + strm_.zalloc = Z_NULL; + strm_.zfree = Z_NULL; + strm_.opaque = Z_NULL; + + is_valid_ = deflateInit2(&strm_, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, + Z_DEFAULT_STRATEGY) == Z_OK; +} + +inline gzip_compressor::~gzip_compressor() { deflateEnd(&strm_); } + +inline bool gzip_compressor::compress(const char *data, size_t data_length, + bool last, Callback callback) { + assert(is_valid_); + + do { + constexpr size_t max_avail_in = + (std::numeric_limits::max)(); + + strm_.avail_in = static_cast( + (std::min)(data_length, max_avail_in)); + strm_.next_in = const_cast(reinterpret_cast(data)); + + data_length -= strm_.avail_in; + data += strm_.avail_in; + + auto flush = (last && data_length == 0) ? Z_FINISH : Z_NO_FLUSH; + auto ret = Z_OK; + + std::array buff{}; + do { + strm_.avail_out = static_cast(buff.size()); + strm_.next_out = reinterpret_cast(buff.data()); + + ret = deflate(&strm_, flush); + if (ret == Z_STREAM_ERROR) { return false; } + + if (!callback(buff.data(), buff.size() - strm_.avail_out)) { + return false; + } + } while (strm_.avail_out == 0); + + assert((flush == Z_FINISH && ret == Z_STREAM_END) || + (flush == Z_NO_FLUSH && ret == Z_OK)); + assert(strm_.avail_in == 0); + } while (data_length > 0); + + return true; +} + +inline gzip_decompressor::gzip_decompressor() { + std::memset(&strm_, 0, sizeof(strm_)); + strm_.zalloc = Z_NULL; + strm_.zfree = Z_NULL; + strm_.opaque = Z_NULL; + + // 15 is the value of wbits, which should be at the maximum possible value + // to ensure that any gzip stream can be decoded. The offset of 32 specifies + // that the stream type should be automatically detected either gzip or + // deflate. + is_valid_ = inflateInit2(&strm_, 32 + 15) == Z_OK; +} + +inline gzip_decompressor::~gzip_decompressor() { inflateEnd(&strm_); } + +inline bool gzip_decompressor::is_valid() const { return is_valid_; } + +inline bool gzip_decompressor::decompress(const char *data, size_t data_length, + Callback callback) { + assert(is_valid_); + + auto ret = Z_OK; + + do { + constexpr size_t max_avail_in = + (std::numeric_limits::max)(); + + strm_.avail_in = static_cast( + (std::min)(data_length, max_avail_in)); + strm_.next_in = const_cast(reinterpret_cast(data)); + + data_length -= strm_.avail_in; + data += strm_.avail_in; + + std::array buff{}; + while (strm_.avail_in > 0 && ret == Z_OK) { + strm_.avail_out = static_cast(buff.size()); + strm_.next_out = reinterpret_cast(buff.data()); + + ret = inflate(&strm_, Z_NO_FLUSH); + + assert(ret != Z_STREAM_ERROR); + switch (ret) { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: inflateEnd(&strm_); return false; + } + + if (!callback(buff.data(), buff.size() - strm_.avail_out)) { + return false; + } + } + + if (ret != Z_OK && ret != Z_STREAM_END) { return false; } + + } while (data_length > 0); + + return true; +} +#endif + +#ifdef CPPHTTPLIB_BROTLI_SUPPORT +inline brotli_compressor::brotli_compressor() { + state_ = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr); +} + +inline brotli_compressor::~brotli_compressor() { + BrotliEncoderDestroyInstance(state_); +} + +inline bool brotli_compressor::compress(const char *data, size_t data_length, + bool last, Callback callback) { + std::array buff{}; + + auto operation = last ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS; + auto available_in = data_length; + auto next_in = reinterpret_cast(data); + + for (;;) { + if (last) { + if (BrotliEncoderIsFinished(state_)) { break; } + } else { + if (!available_in) { break; } + } + + auto available_out = buff.size(); + auto next_out = buff.data(); + + if (!BrotliEncoderCompressStream(state_, operation, &available_in, &next_in, + &available_out, &next_out, nullptr)) { + return false; + } + + auto output_bytes = buff.size() - available_out; + if (output_bytes) { + callback(reinterpret_cast(buff.data()), output_bytes); + } + } + + return true; +} + +inline brotli_decompressor::brotli_decompressor() { + decoder_s = BrotliDecoderCreateInstance(0, 0, 0); + decoder_r = decoder_s ? BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT + : BROTLI_DECODER_RESULT_ERROR; +} + +inline brotli_decompressor::~brotli_decompressor() { + if (decoder_s) { BrotliDecoderDestroyInstance(decoder_s); } +} + +inline bool brotli_decompressor::is_valid() const { return decoder_s; } + +inline bool brotli_decompressor::decompress(const char *data, + size_t data_length, + Callback callback) { + if (decoder_r == BROTLI_DECODER_RESULT_SUCCESS || + decoder_r == BROTLI_DECODER_RESULT_ERROR) { + return 0; + } + + auto next_in = reinterpret_cast(data); + size_t avail_in = data_length; + size_t total_out; + + decoder_r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; + + std::array buff{}; + while (decoder_r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { + char *next_out = buff.data(); + size_t avail_out = buff.size(); + + decoder_r = BrotliDecoderDecompressStream( + decoder_s, &avail_in, &next_in, &avail_out, + reinterpret_cast(&next_out), &total_out); + + if (decoder_r == BROTLI_DECODER_RESULT_ERROR) { return false; } + + if (!callback(buff.data(), buff.size() - avail_out)) { return false; } + } + + return decoder_r == BROTLI_DECODER_RESULT_SUCCESS || + decoder_r == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT; +} +#endif + +inline bool has_header(const Headers &headers, const std::string &key) { + return headers.find(key) != headers.end(); +} + +inline const char *get_header_value(const Headers &headers, + const std::string &key, size_t id, + const char *def) { + auto rng = headers.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { return it->second.c_str(); } + return def; +} + +inline bool compare_case_ignore(const std::string &a, const std::string &b) { + if (a.size() != b.size()) { return false; } + for (size_t i = 0; i < b.size(); i++) { + if (::tolower(a[i]) != ::tolower(b[i])) { return false; } + } + return true; +} + +template +inline bool parse_header(const char *beg, const char *end, T fn) { + // Skip trailing spaces and tabs. + while (beg < end && is_space_or_tab(end[-1])) { + end--; + } + + auto p = beg; + while (p < end && *p != ':') { + p++; + } + + if (p == end) { return false; } + + auto key_end = p; + + if (*p++ != ':') { return false; } + + while (p < end && is_space_or_tab(*p)) { + p++; + } + + if (p < end) { + auto key_len = key_end - beg; + if (!key_len) { return false; } + + auto key = std::string(beg, key_end); + auto val = compare_case_ignore(key, "Location") + ? std::string(p, end) + : decode_url(std::string(p, end), false); + fn(std::move(key), std::move(val)); + return true; + } + + return false; +} + +inline bool read_headers(Stream &strm, Headers &headers) { + const auto bufsiz = 2048; + char buf[bufsiz]; + stream_line_reader line_reader(strm, buf, bufsiz); + + for (;;) { + if (!line_reader.getline()) { return false; } + + // Check if the line ends with CRLF. + auto line_terminator_len = 2; + if (line_reader.end_with_crlf()) { + // Blank line indicates end of headers. + if (line_reader.size() == 2) { break; } +#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR + } else { + // Blank line indicates end of headers. + if (line_reader.size() == 1) { break; } + line_terminator_len = 1; + } +#else + } else { + continue; // Skip invalid line. + } +#endif + + if (line_reader.size() > CPPHTTPLIB_HEADER_MAX_LENGTH) { return false; } + + // Exclude line terminator + auto end = line_reader.ptr() + line_reader.size() - line_terminator_len; + + parse_header(line_reader.ptr(), end, + [&](std::string &&key, std::string &&val) { + headers.emplace(std::move(key), std::move(val)); + }); + } + + return true; +} + +inline bool read_content_with_length(Stream &strm, uint64_t len, + Progress progress, + ContentReceiverWithProgress out) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + + uint64_t r = 0; + while (r < len) { + auto read_len = static_cast(len - r); + auto n = strm.read(buf, (std::min)(read_len, CPPHTTPLIB_RECV_BUFSIZ)); + if (n <= 0) { return false; } + + if (!out(buf, static_cast(n), r, len)) { return false; } + r += static_cast(n); + + if (progress) { + if (!progress(r, len)) { return false; } + } + } + + return true; +} + +inline void skip_content_with_length(Stream &strm, uint64_t len) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + uint64_t r = 0; + while (r < len) { + auto read_len = static_cast(len - r); + auto n = strm.read(buf, (std::min)(read_len, CPPHTTPLIB_RECV_BUFSIZ)); + if (n <= 0) { return; } + r += static_cast(n); + } +} + +inline bool read_content_without_length(Stream &strm, + ContentReceiverWithProgress out) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + uint64_t r = 0; + for (;;) { + auto n = strm.read(buf, CPPHTTPLIB_RECV_BUFSIZ); + if (n <= 0) { return true; } + + if (!out(buf, static_cast(n), r, 0)) { return false; } + r += static_cast(n); + } + + return true; +} + +template +inline bool read_content_chunked(Stream &strm, T &x, + ContentReceiverWithProgress out) { + const auto bufsiz = 16; + char buf[bufsiz]; + + stream_line_reader line_reader(strm, buf, bufsiz); + + if (!line_reader.getline()) { return false; } + + unsigned long chunk_len; + while (true) { + char *end_ptr; + + chunk_len = std::strtoul(line_reader.ptr(), &end_ptr, 16); + + if (end_ptr == line_reader.ptr()) { return false; } + if (chunk_len == ULONG_MAX) { return false; } + + if (chunk_len == 0) { break; } + + if (!read_content_with_length(strm, chunk_len, nullptr, out)) { + return false; + } + + if (!line_reader.getline()) { return false; } + + if (strcmp(line_reader.ptr(), "\r\n") != 0) { return false; } + + if (!line_reader.getline()) { return false; } + } + + assert(chunk_len == 0); + + // Trailer + if (!line_reader.getline()) { return false; } + + while (strcmp(line_reader.ptr(), "\r\n") != 0) { + if (line_reader.size() > CPPHTTPLIB_HEADER_MAX_LENGTH) { return false; } + + // Exclude line terminator + constexpr auto line_terminator_len = 2; + auto end = line_reader.ptr() + line_reader.size() - line_terminator_len; + + parse_header(line_reader.ptr(), end, + [&](std::string &&key, std::string &&val) { + x.headers.emplace(std::move(key), std::move(val)); + }); + + if (!line_reader.getline()) { return false; } + } + + return true; +} + +inline bool is_chunked_transfer_encoding(const Headers &headers) { + return compare_case_ignore( + get_header_value(headers, "Transfer-Encoding", 0, ""), "chunked"); +} + +template +bool prepare_content_receiver(T &x, int &status, + ContentReceiverWithProgress receiver, + bool decompress, U callback) { + if (decompress) { + std::string encoding = x.get_header_value("Content-Encoding"); + std::unique_ptr decompressor; + + if (encoding == "gzip" || encoding == "deflate") { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + decompressor = detail::make_unique(); +#else + status = StatusCode::UnsupportedMediaType_415; + return false; +#endif + } else if (encoding.find("br") != std::string::npos) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + decompressor = detail::make_unique(); +#else + status = StatusCode::UnsupportedMediaType_415; + return false; +#endif + } + + if (decompressor) { + if (decompressor->is_valid()) { + ContentReceiverWithProgress out = [&](const char *buf, size_t n, + uint64_t off, uint64_t len) { + return decompressor->decompress(buf, n, + [&](const char *buf2, size_t n2) { + return receiver(buf2, n2, off, len); + }); + }; + return callback(std::move(out)); + } else { + status = StatusCode::InternalServerError_500; + return false; + } + } + } + + ContentReceiverWithProgress out = [&](const char *buf, size_t n, uint64_t off, + uint64_t len) { + return receiver(buf, n, off, len); + }; + return callback(std::move(out)); +} + +template +bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status, + Progress progress, ContentReceiverWithProgress receiver, + bool decompress) { + return prepare_content_receiver( + x, status, std::move(receiver), decompress, + [&](const ContentReceiverWithProgress &out) { + auto ret = true; + auto exceed_payload_max_length = false; + + if (is_chunked_transfer_encoding(x.headers)) { + ret = read_content_chunked(strm, x, out); + } else if (!has_header(x.headers, "Content-Length")) { + ret = read_content_without_length(strm, out); + } else { + auto len = get_header_value_u64(x.headers, "Content-Length", 0, 0); + if (len > payload_max_length) { + exceed_payload_max_length = true; + skip_content_with_length(strm, len); + ret = false; + } else if (len > 0) { + ret = read_content_with_length(strm, len, std::move(progress), out); + } + } + + if (!ret) { + status = exceed_payload_max_length ? StatusCode::PayloadTooLarge_413 + : StatusCode::BadRequest_400; + } + return ret; + }); +} // namespace detail + +inline ssize_t write_headers(Stream &strm, const Headers &headers) { + ssize_t write_len = 0; + for (const auto &x : headers) { + auto len = + strm.write_format("%s: %s\r\n", x.first.c_str(), x.second.c_str()); + if (len < 0) { return len; } + write_len += len; + } + auto len = strm.write("\r\n"); + if (len < 0) { return len; } + write_len += len; + return write_len; +} + +inline bool write_data(Stream &strm, const char *d, size_t l) { + size_t offset = 0; + while (offset < l) { + auto length = strm.write(d + offset, l - offset); + if (length < 0) { return false; } + offset += static_cast(length); + } + return true; +} + +template +inline bool write_content(Stream &strm, const ContentProvider &content_provider, + size_t offset, size_t length, T is_shutting_down, + Error &error) { + size_t end_offset = offset + length; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) -> bool { + if (ok) { + if (strm.is_writable() && write_data(strm, d, l)) { + offset += l; + } else { + ok = false; + } + } + return ok; + }; + + data_sink.is_writable = [&]() -> bool { return strm.is_writable(); }; + + while (offset < end_offset && !is_shutting_down()) { + if (!strm.is_writable()) { + error = Error::Write; + return false; + } else if (!content_provider(offset, end_offset - offset, data_sink)) { + error = Error::Canceled; + return false; + } else if (!ok) { + error = Error::Write; + return false; + } + } + + error = Error::Success; + return true; +} + +template +inline bool write_content(Stream &strm, const ContentProvider &content_provider, + size_t offset, size_t length, + const T &is_shutting_down) { + auto error = Error::Success; + return write_content(strm, content_provider, offset, length, is_shutting_down, + error); +} + +template +inline bool +write_content_without_length(Stream &strm, + const ContentProvider &content_provider, + const T &is_shutting_down) { + size_t offset = 0; + auto data_available = true; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) -> bool { + if (ok) { + offset += l; + if (!strm.is_writable() || !write_data(strm, d, l)) { ok = false; } + } + return ok; + }; + + data_sink.is_writable = [&]() -> bool { return strm.is_writable(); }; + + data_sink.done = [&](void) { data_available = false; }; + + while (data_available && !is_shutting_down()) { + if (!strm.is_writable()) { + return false; + } else if (!content_provider(offset, 0, data_sink)) { + return false; + } else if (!ok) { + return false; + } + } + return true; +} + +template +inline bool +write_content_chunked(Stream &strm, const ContentProvider &content_provider, + const T &is_shutting_down, U &compressor, Error &error) { + size_t offset = 0; + auto data_available = true; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) -> bool { + if (ok) { + data_available = l > 0; + offset += l; + + std::string payload; + if (compressor.compress(d, l, false, + [&](const char *data, size_t data_len) { + payload.append(data, data_len); + return true; + })) { + if (!payload.empty()) { + // Emit chunked response header and footer for each chunk + auto chunk = + from_i_to_hex(payload.size()) + "\r\n" + payload + "\r\n"; + if (!strm.is_writable() || + !write_data(strm, chunk.data(), chunk.size())) { + ok = false; + } + } + } else { + ok = false; + } + } + return ok; + }; + + data_sink.is_writable = [&]() -> bool { return strm.is_writable(); }; + + auto done_with_trailer = [&](const Headers *trailer) { + if (!ok) { return; } + + data_available = false; + + std::string payload; + if (!compressor.compress(nullptr, 0, true, + [&](const char *data, size_t data_len) { + payload.append(data, data_len); + return true; + })) { + ok = false; + return; + } + + if (!payload.empty()) { + // Emit chunked response header and footer for each chunk + auto chunk = from_i_to_hex(payload.size()) + "\r\n" + payload + "\r\n"; + if (!strm.is_writable() || + !write_data(strm, chunk.data(), chunk.size())) { + ok = false; + return; + } + } + + static const std::string done_marker("0\r\n"); + if (!write_data(strm, done_marker.data(), done_marker.size())) { + ok = false; + } + + // Trailer + if (trailer) { + for (const auto &kv : *trailer) { + std::string field_line = kv.first + ": " + kv.second + "\r\n"; + if (!write_data(strm, field_line.data(), field_line.size())) { + ok = false; + } + } + } + + static const std::string crlf("\r\n"); + if (!write_data(strm, crlf.data(), crlf.size())) { ok = false; } + }; + + data_sink.done = [&](void) { done_with_trailer(nullptr); }; + + data_sink.done_with_trailer = [&](const Headers &trailer) { + done_with_trailer(&trailer); + }; + + while (data_available && !is_shutting_down()) { + if (!strm.is_writable()) { + error = Error::Write; + return false; + } else if (!content_provider(offset, 0, data_sink)) { + error = Error::Canceled; + return false; + } else if (!ok) { + error = Error::Write; + return false; + } + } + + error = Error::Success; + return true; +} + +template +inline bool write_content_chunked(Stream &strm, + const ContentProvider &content_provider, + const T &is_shutting_down, U &compressor) { + auto error = Error::Success; + return write_content_chunked(strm, content_provider, is_shutting_down, + compressor, error); +} + +template +inline bool redirect(T &cli, Request &req, Response &res, + const std::string &path, const std::string &location, + Error &error) { + Request new_req = req; + new_req.path = path; + new_req.redirect_count_ -= 1; + + if (res.status == StatusCode::SeeOther_303 && + (req.method != "GET" && req.method != "HEAD")) { + new_req.method = "GET"; + new_req.body.clear(); + new_req.headers.clear(); + } + + Response new_res; + + auto ret = cli.send(new_req, new_res, error); + if (ret) { + req = new_req; + res = new_res; + + if (res.location.empty()) { res.location = location; } + } + return ret; +} + +inline std::string params_to_query_str(const Params ¶ms) { + std::string query; + + for (auto it = params.begin(); it != params.end(); ++it) { + if (it != params.begin()) { query += "&"; } + query += it->first; + query += "="; + query += encode_query_param(it->second); + } + return query; +} + +inline void parse_query_text(const std::string &s, Params ¶ms) { + std::set cache; + split(s.data(), s.data() + s.size(), '&', [&](const char *b, const char *e) { + std::string kv(b, e); + if (cache.find(kv) != cache.end()) { return; } + cache.insert(kv); + + std::string key; + std::string val; + split(b, e, '=', [&](const char *b2, const char *e2) { + if (key.empty()) { + key.assign(b2, e2); + } else { + val.assign(b2, e2); + } + }); + + if (!key.empty()) { + params.emplace(decode_url(key, true), decode_url(val, true)); + } + }); +} + +inline bool parse_multipart_boundary(const std::string &content_type, + std::string &boundary) { + auto boundary_keyword = "boundary="; + auto pos = content_type.find(boundary_keyword); + if (pos == std::string::npos) { return false; } + auto end = content_type.find(';', pos); + auto beg = pos + strlen(boundary_keyword); + boundary = trim_double_quotes_copy(content_type.substr(beg, end - beg)); + return !boundary.empty(); +} + +inline void parse_disposition_params(const std::string &s, Params ¶ms) { + std::set cache; + split(s.data(), s.data() + s.size(), ';', [&](const char *b, const char *e) { + std::string kv(b, e); + if (cache.find(kv) != cache.end()) { return; } + cache.insert(kv); + + std::string key; + std::string val; + split(b, e, '=', [&](const char *b2, const char *e2) { + if (key.empty()) { + key.assign(b2, e2); + } else { + val.assign(b2, e2); + } + }); + + if (!key.empty()) { + params.emplace(trim_double_quotes_copy((key)), + trim_double_quotes_copy((val))); + } + }); +} + +#ifdef CPPHTTPLIB_NO_EXCEPTIONS +inline bool parse_range_header(const std::string &s, Ranges &ranges) { +#else +inline bool parse_range_header(const std::string &s, Ranges &ranges) try { +#endif + static auto re_first_range = std::regex(R"(bytes=(\d*-\d*(?:,\s*\d*-\d*)*))"); + std::smatch m; + if (std::regex_match(s, m, re_first_range)) { + auto pos = static_cast(m.position(1)); + auto len = static_cast(m.length(1)); + auto all_valid_ranges = true; + split(&s[pos], &s[pos + len], ',', [&](const char *b, const char *e) { + if (!all_valid_ranges) { return; } + static auto re_another_range = std::regex(R"(\s*(\d*)-(\d*))"); + std::cmatch cm; + if (std::regex_match(b, e, cm, re_another_range)) { + ssize_t first = -1; + if (!cm.str(1).empty()) { + first = static_cast(std::stoll(cm.str(1))); + } + + ssize_t last = -1; + if (!cm.str(2).empty()) { + last = static_cast(std::stoll(cm.str(2))); + } + + if (first != -1 && last != -1 && first > last) { + all_valid_ranges = false; + return; + } + ranges.emplace_back(std::make_pair(first, last)); + } + }); + return all_valid_ranges; + } + return false; +#ifdef CPPHTTPLIB_NO_EXCEPTIONS +} +#else +} catch (...) { return false; } +#endif + +class MultipartFormDataParser { +public: + MultipartFormDataParser() = default; + + void set_boundary(std::string &&boundary) { + boundary_ = boundary; + dash_boundary_crlf_ = dash_ + boundary_ + crlf_; + crlf_dash_boundary_ = crlf_ + dash_ + boundary_; + } + + bool is_valid() const { return is_valid_; } + + bool parse(const char *buf, size_t n, const ContentReceiver &content_callback, + const MultipartContentHeader &header_callback) { + + buf_append(buf, n); + + while (buf_size() > 0) { + switch (state_) { + case 0: { // Initial boundary + buf_erase(buf_find(dash_boundary_crlf_)); + if (dash_boundary_crlf_.size() > buf_size()) { return true; } + if (!buf_start_with(dash_boundary_crlf_)) { return false; } + buf_erase(dash_boundary_crlf_.size()); + state_ = 1; + break; + } + case 1: { // New entry + clear_file_info(); + state_ = 2; + break; + } + case 2: { // Headers + auto pos = buf_find(crlf_); + if (pos > CPPHTTPLIB_HEADER_MAX_LENGTH) { return false; } + while (pos < buf_size()) { + // Empty line + if (pos == 0) { + if (!header_callback(file_)) { + is_valid_ = false; + return false; + } + buf_erase(crlf_.size()); + state_ = 3; + break; + } + + const auto header = buf_head(pos); + + if (!parse_header(header.data(), header.data() + header.size(), + [&](std::string &&, std::string &&) {})) { + is_valid_ = false; + return false; + } + + static const std::string header_content_type = "Content-Type:"; + + if (start_with_case_ignore(header, header_content_type)) { + file_.content_type = + trim_copy(header.substr(header_content_type.size())); + } else { + static const std::regex re_content_disposition( + R"~(^Content-Disposition:\s*form-data;\s*(.*)$)~", + std::regex_constants::icase); + + std::smatch m; + if (std::regex_match(header, m, re_content_disposition)) { + Params params; + parse_disposition_params(m[1], params); + + auto it = params.find("name"); + if (it != params.end()) { + file_.name = it->second; + } else { + is_valid_ = false; + return false; + } + + it = params.find("filename"); + if (it != params.end()) { file_.filename = it->second; } + + it = params.find("filename*"); + if (it != params.end()) { + // Only allow UTF-8 enconnding... + static const std::regex re_rfc5987_encoding( + R"~(^UTF-8''(.+?)$)~", std::regex_constants::icase); + + std::smatch m2; + if (std::regex_match(it->second, m2, re_rfc5987_encoding)) { + file_.filename = decode_url(m2[1], false); // override... + } else { + is_valid_ = false; + return false; + } + } + } + } + buf_erase(pos + crlf_.size()); + pos = buf_find(crlf_); + } + if (state_ != 3) { return true; } + break; + } + case 3: { // Body + if (crlf_dash_boundary_.size() > buf_size()) { return true; } + auto pos = buf_find(crlf_dash_boundary_); + if (pos < buf_size()) { + if (!content_callback(buf_data(), pos)) { + is_valid_ = false; + return false; + } + buf_erase(pos + crlf_dash_boundary_.size()); + state_ = 4; + } else { + auto len = buf_size() - crlf_dash_boundary_.size(); + if (len > 0) { + if (!content_callback(buf_data(), len)) { + is_valid_ = false; + return false; + } + buf_erase(len); + } + return true; + } + break; + } + case 4: { // Boundary + if (crlf_.size() > buf_size()) { return true; } + if (buf_start_with(crlf_)) { + buf_erase(crlf_.size()); + state_ = 1; + } else { + if (dash_.size() > buf_size()) { return true; } + if (buf_start_with(dash_)) { + buf_erase(dash_.size()); + is_valid_ = true; + buf_erase(buf_size()); // Remove epilogue + } else { + return true; + } + } + break; + } + } + } + + return true; + } + +private: + void clear_file_info() { + file_.name.clear(); + file_.filename.clear(); + file_.content_type.clear(); + } + + bool start_with_case_ignore(const std::string &a, + const std::string &b) const { + if (a.size() < b.size()) { return false; } + for (size_t i = 0; i < b.size(); i++) { + if (::tolower(a[i]) != ::tolower(b[i])) { return false; } + } + return true; + } + + const std::string dash_ = "--"; + const std::string crlf_ = "\r\n"; + std::string boundary_; + std::string dash_boundary_crlf_; + std::string crlf_dash_boundary_; + + size_t state_ = 0; + bool is_valid_ = false; + MultipartFormData file_; + + // Buffer + bool start_with(const std::string &a, size_t spos, size_t epos, + const std::string &b) const { + if (epos - spos < b.size()) { return false; } + for (size_t i = 0; i < b.size(); i++) { + if (a[i + spos] != b[i]) { return false; } + } + return true; + } + + size_t buf_size() const { return buf_epos_ - buf_spos_; } + + const char *buf_data() const { return &buf_[buf_spos_]; } + + std::string buf_head(size_t l) const { return buf_.substr(buf_spos_, l); } + + bool buf_start_with(const std::string &s) const { + return start_with(buf_, buf_spos_, buf_epos_, s); + } + + size_t buf_find(const std::string &s) const { + auto c = s.front(); + + size_t off = buf_spos_; + while (off < buf_epos_) { + auto pos = off; + while (true) { + if (pos == buf_epos_) { return buf_size(); } + if (buf_[pos] == c) { break; } + pos++; + } + + auto remaining_size = buf_epos_ - pos; + if (s.size() > remaining_size) { return buf_size(); } + + if (start_with(buf_, pos, buf_epos_, s)) { return pos - buf_spos_; } + + off = pos + 1; + } + + return buf_size(); + } + + void buf_append(const char *data, size_t n) { + auto remaining_size = buf_size(); + if (remaining_size > 0 && buf_spos_ > 0) { + for (size_t i = 0; i < remaining_size; i++) { + buf_[i] = buf_[buf_spos_ + i]; + } + } + buf_spos_ = 0; + buf_epos_ = remaining_size; + + if (remaining_size + n > buf_.size()) { buf_.resize(remaining_size + n); } + + for (size_t i = 0; i < n; i++) { + buf_[buf_epos_ + i] = data[i]; + } + buf_epos_ += n; + } + + void buf_erase(size_t size) { buf_spos_ += size; } + + std::string buf_; + size_t buf_spos_ = 0; + size_t buf_epos_ = 0; +}; + +inline std::string to_lower(const char *beg, const char *end) { + std::string out; + auto it = beg; + while (it != end) { + out += static_cast(::tolower(*it)); + it++; + } + return out; +} + +inline std::string random_string(size_t length) { + static const char data[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + // std::random_device might actually be deterministic on some + // platforms, but due to lack of support in the c++ standard library, + // doing better requires either some ugly hacks or breaking portability. + static std::random_device seed_gen; + + // Request 128 bits of entropy for initialization + static std::seed_seq seed_sequence{seed_gen(), seed_gen(), seed_gen(), + seed_gen()}; + + static std::mt19937 engine(seed_sequence); + + std::string result; + for (size_t i = 0; i < length; i++) { + result += data[engine() % (sizeof(data) - 1)]; + } + return result; +} + +inline std::string make_multipart_data_boundary() { + return "--cpp-httplib-multipart-data-" + detail::random_string(16); +} + +inline bool is_multipart_boundary_chars_valid(const std::string &boundary) { + auto valid = true; + for (size_t i = 0; i < boundary.size(); i++) { + auto c = boundary[i]; + if (!std::isalnum(c) && c != '-' && c != '_') { + valid = false; + break; + } + } + return valid; +} + +template +inline std::string +serialize_multipart_formdata_item_begin(const T &item, + const std::string &boundary) { + std::string body = "--" + boundary + "\r\n"; + body += "Content-Disposition: form-data; name=\"" + item.name + "\""; + if (!item.filename.empty()) { + body += "; filename=\"" + item.filename + "\""; + } + body += "\r\n"; + if (!item.content_type.empty()) { + body += "Content-Type: " + item.content_type + "\r\n"; + } + body += "\r\n"; + + return body; +} + +inline std::string serialize_multipart_formdata_item_end() { return "\r\n"; } + +inline std::string +serialize_multipart_formdata_finish(const std::string &boundary) { + return "--" + boundary + "--\r\n"; +} + +inline std::string +serialize_multipart_formdata_get_content_type(const std::string &boundary) { + return "multipart/form-data; boundary=" + boundary; +} + +inline std::string +serialize_multipart_formdata(const MultipartFormDataItems &items, + const std::string &boundary, bool finish = true) { + std::string body; + + for (const auto &item : items) { + body += serialize_multipart_formdata_item_begin(item, boundary); + body += item.content + serialize_multipart_formdata_item_end(); + } + + if (finish) { body += serialize_multipart_formdata_finish(boundary); } + + return body; +} + +inline bool range_error(Request &req, Response &res) { + if (!req.ranges.empty() && 200 <= res.status && res.status < 300) { + ssize_t contant_len = static_cast( + res.content_length_ ? res.content_length_ : res.body.size()); + + ssize_t prev_first_pos = -1; + ssize_t prev_last_pos = -1; + size_t overwrapping_count = 0; + + // NOTE: The following Range check is based on '14.2. Range' in RFC 9110 + // 'HTTP Semantics' to avoid potential denial-of-service attacks. + // https://www.rfc-editor.org/rfc/rfc9110#section-14.2 + + // Too many ranges + if (req.ranges.size() > CPPHTTPLIB_RANGE_MAX_COUNT) { return true; } + + for (auto &r : req.ranges) { + auto &first_pos = r.first; + auto &last_pos = r.second; + + if (first_pos == -1 && last_pos == -1) { + first_pos = 0; + last_pos = contant_len; + } + + if (first_pos == -1) { + first_pos = contant_len - last_pos; + last_pos = contant_len - 1; + } + + if (last_pos == -1) { last_pos = contant_len - 1; } + + // Range must be within content length + if (!(0 <= first_pos && first_pos <= last_pos && + last_pos <= contant_len - 1)) { + return true; + } + + // Ranges must be in ascending order + if (first_pos <= prev_first_pos) { return true; } + + // Request must not have more than two overlapping ranges + if (first_pos <= prev_last_pos) { + overwrapping_count++; + if (overwrapping_count > 2) { return true; } + } + + prev_first_pos = (std::max)(prev_first_pos, first_pos); + prev_last_pos = (std::max)(prev_last_pos, last_pos); + } + } + + return false; +} + +inline std::pair +get_range_offset_and_length(Range r, size_t content_length) { + assert(r.first != -1 && r.second != -1); + assert(0 <= r.first && r.first < static_cast(content_length)); + assert(r.first <= r.second && + r.second < static_cast(content_length)); + + return std::make_pair(r.first, static_cast(r.second - r.first) + 1); +} + +inline std::string make_content_range_header_field( + const std::pair &offset_and_length, size_t content_length) { + auto st = offset_and_length.first; + auto ed = st + offset_and_length.second - 1; + + std::string field = "bytes "; + field += std::to_string(st); + field += "-"; + field += std::to_string(ed); + field += "/"; + field += std::to_string(content_length); + return field; +} + +template +bool process_multipart_ranges_data(const Request &req, + const std::string &boundary, + const std::string &content_type, + size_t content_length, SToken stoken, + CToken ctoken, Content content) { + for (size_t i = 0; i < req.ranges.size(); i++) { + ctoken("--"); + stoken(boundary); + ctoken("\r\n"); + if (!content_type.empty()) { + ctoken("Content-Type: "); + stoken(content_type); + ctoken("\r\n"); + } + + auto offset_and_length = + get_range_offset_and_length(req.ranges[i], content_length); + + ctoken("Content-Range: "); + stoken(make_content_range_header_field(offset_and_length, content_length)); + ctoken("\r\n"); + ctoken("\r\n"); + + if (!content(offset_and_length.first, offset_and_length.second)) { + return false; + } + ctoken("\r\n"); + } + + ctoken("--"); + stoken(boundary); + ctoken("--"); + + return true; +} + +inline void make_multipart_ranges_data(const Request &req, Response &res, + const std::string &boundary, + const std::string &content_type, + size_t content_length, + std::string &data) { + process_multipart_ranges_data( + req, boundary, content_type, content_length, + [&](const std::string &token) { data += token; }, + [&](const std::string &token) { data += token; }, + [&](size_t offset, size_t length) { + assert(offset + length <= content_length); + data += res.body.substr(offset, length); + return true; + }); +} + +inline size_t get_multipart_ranges_data_length(const Request &req, + const std::string &boundary, + const std::string &content_type, + size_t content_length) { + size_t data_length = 0; + + process_multipart_ranges_data( + req, boundary, content_type, content_length, + [&](const std::string &token) { data_length += token.size(); }, + [&](const std::string &token) { data_length += token.size(); }, + [&](size_t /*offset*/, size_t length) { + data_length += length; + return true; + }); + + return data_length; +} + +template +inline bool +write_multipart_ranges_data(Stream &strm, const Request &req, Response &res, + const std::string &boundary, + const std::string &content_type, + size_t content_length, const T &is_shutting_down) { + return process_multipart_ranges_data( + req, boundary, content_type, content_length, + [&](const std::string &token) { strm.write(token); }, + [&](const std::string &token) { strm.write(token); }, + [&](size_t offset, size_t length) { + return write_content(strm, res.content_provider_, offset, length, + is_shutting_down); + }); +} + +inline bool expect_content(const Request &req) { + if (req.method == "POST" || req.method == "PUT" || req.method == "PATCH" || + req.method == "PRI" || req.method == "DELETE") { + return true; + } + // TODO: check if Content-Length is set + return false; +} + +inline bool has_crlf(const std::string &s) { + auto p = s.c_str(); + while (*p) { + if (*p == '\r' || *p == '\n') { return true; } + p++; + } + return false; +} + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline std::string message_digest(const std::string &s, const EVP_MD *algo) { + auto context = std::unique_ptr( + EVP_MD_CTX_new(), EVP_MD_CTX_free); + + unsigned int hash_length = 0; + unsigned char hash[EVP_MAX_MD_SIZE]; + + EVP_DigestInit_ex(context.get(), algo, nullptr); + EVP_DigestUpdate(context.get(), s.c_str(), s.size()); + EVP_DigestFinal_ex(context.get(), hash, &hash_length); + + std::stringstream ss; + for (auto i = 0u; i < hash_length; ++i) { + ss << std::hex << std::setw(2) << std::setfill('0') + << static_cast(hash[i]); + } + + return ss.str(); +} + +inline std::string MD5(const std::string &s) { + return message_digest(s, EVP_md5()); +} + +inline std::string SHA_256(const std::string &s) { + return message_digest(s, EVP_sha256()); +} + +inline std::string SHA_512(const std::string &s) { + return message_digest(s, EVP_sha512()); +} +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +#ifdef _WIN32 +// NOTE: This code came up with the following stackoverflow post: +// https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store +inline bool load_system_certs_on_windows(X509_STORE *store) { + auto hStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"ROOT"); + if (!hStore) { return false; } + + auto result = false; + PCCERT_CONTEXT pContext = NULL; + while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != + nullptr) { + auto encoded_cert = + static_cast(pContext->pbCertEncoded); + + auto x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded); + if (x509) { + X509_STORE_add_cert(store, x509); + X509_free(x509); + result = true; + } + } + + CertFreeCertificateContext(pContext); + CertCloseStore(hStore, 0); + + return result; +} +#elif defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN) && defined(__APPLE__) +#if TARGET_OS_OSX +template +using CFObjectPtr = + std::unique_ptr::type, void (*)(CFTypeRef)>; + +inline void cf_object_ptr_deleter(CFTypeRef obj) { + if (obj) { CFRelease(obj); } +} + +inline bool retrieve_certs_from_keychain(CFObjectPtr &certs) { + CFStringRef keys[] = {kSecClass, kSecMatchLimit, kSecReturnRef}; + CFTypeRef values[] = {kSecClassCertificate, kSecMatchLimitAll, + kCFBooleanTrue}; + + CFObjectPtr query( + CFDictionaryCreate(nullptr, reinterpret_cast(keys), values, + sizeof(keys) / sizeof(keys[0]), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks), + cf_object_ptr_deleter); + + if (!query) { return false; } + + CFTypeRef security_items = nullptr; + if (SecItemCopyMatching(query.get(), &security_items) != errSecSuccess || + CFArrayGetTypeID() != CFGetTypeID(security_items)) { + return false; + } + + certs.reset(reinterpret_cast(security_items)); + return true; +} + +inline bool retrieve_root_certs_from_keychain(CFObjectPtr &certs) { + CFArrayRef root_security_items = nullptr; + if (SecTrustCopyAnchorCertificates(&root_security_items) != errSecSuccess) { + return false; + } + + certs.reset(root_security_items); + return true; +} + +inline bool add_certs_to_x509_store(CFArrayRef certs, X509_STORE *store) { + auto result = false; + for (auto i = 0; i < CFArrayGetCount(certs); ++i) { + const auto cert = reinterpret_cast( + CFArrayGetValueAtIndex(certs, i)); + + if (SecCertificateGetTypeID() != CFGetTypeID(cert)) { continue; } + + CFDataRef cert_data = nullptr; + if (SecItemExport(cert, kSecFormatX509Cert, 0, nullptr, &cert_data) != + errSecSuccess) { + continue; + } + + CFObjectPtr cert_data_ptr(cert_data, cf_object_ptr_deleter); + + auto encoded_cert = static_cast( + CFDataGetBytePtr(cert_data_ptr.get())); + + auto x509 = + d2i_X509(NULL, &encoded_cert, CFDataGetLength(cert_data_ptr.get())); + + if (x509) { + X509_STORE_add_cert(store, x509); + X509_free(x509); + result = true; + } + } + + return result; +} + +inline bool load_system_certs_on_macos(X509_STORE *store) { + auto result = false; + CFObjectPtr certs(nullptr, cf_object_ptr_deleter); + if (retrieve_certs_from_keychain(certs) && certs) { + result = add_certs_to_x509_store(certs.get(), store); + } + + if (retrieve_root_certs_from_keychain(certs) && certs) { + result = add_certs_to_x509_store(certs.get(), store) || result; + } + + return result; +} +#endif // TARGET_OS_OSX +#endif // _WIN32 +#endif // CPPHTTPLIB_OPENSSL_SUPPORT + +#ifdef _WIN32 +class WSInit { +public: + WSInit() { + WSADATA wsaData; + if (WSAStartup(0x0002, &wsaData) == 0) is_valid_ = true; + } + + ~WSInit() { + if (is_valid_) WSACleanup(); + } + + bool is_valid_ = false; +}; + +static WSInit wsinit_; +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline std::pair make_digest_authentication_header( + const Request &req, const std::map &auth, + size_t cnonce_count, const std::string &cnonce, const std::string &username, + const std::string &password, bool is_proxy = false) { + std::string nc; + { + std::stringstream ss; + ss << std::setfill('0') << std::setw(8) << std::hex << cnonce_count; + nc = ss.str(); + } + + std::string qop; + if (auth.find("qop") != auth.end()) { + qop = auth.at("qop"); + if (qop.find("auth-int") != std::string::npos) { + qop = "auth-int"; + } else if (qop.find("auth") != std::string::npos) { + qop = "auth"; + } else { + qop.clear(); + } + } + + std::string algo = "MD5"; + if (auth.find("algorithm") != auth.end()) { algo = auth.at("algorithm"); } + + std::string response; + { + auto H = algo == "SHA-256" ? detail::SHA_256 + : algo == "SHA-512" ? detail::SHA_512 + : detail::MD5; + + auto A1 = username + ":" + auth.at("realm") + ":" + password; + + auto A2 = req.method + ":" + req.path; + if (qop == "auth-int") { A2 += ":" + H(req.body); } + + if (qop.empty()) { + response = H(H(A1) + ":" + auth.at("nonce") + ":" + H(A2)); + } else { + response = H(H(A1) + ":" + auth.at("nonce") + ":" + nc + ":" + cnonce + + ":" + qop + ":" + H(A2)); + } + } + + auto opaque = (auth.find("opaque") != auth.end()) ? auth.at("opaque") : ""; + + auto field = "Digest username=\"" + username + "\", realm=\"" + + auth.at("realm") + "\", nonce=\"" + auth.at("nonce") + + "\", uri=\"" + req.path + "\", algorithm=" + algo + + (qop.empty() ? ", response=\"" + : ", qop=" + qop + ", nc=" + nc + ", cnonce=\"" + + cnonce + "\", response=\"") + + response + "\"" + + (opaque.empty() ? "" : ", opaque=\"" + opaque + "\""); + + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, field); +} +#endif + +inline bool parse_www_authenticate(const Response &res, + std::map &auth, + bool is_proxy) { + auto auth_key = is_proxy ? "Proxy-Authenticate" : "WWW-Authenticate"; + if (res.has_header(auth_key)) { + static auto re = std::regex(R"~((?:(?:,\s*)?(.+?)=(?:"(.*?)"|([^,]*))))~"); + auto s = res.get_header_value(auth_key); + auto pos = s.find(' '); + if (pos != std::string::npos) { + auto type = s.substr(0, pos); + if (type == "Basic") { + return false; + } else if (type == "Digest") { + s = s.substr(pos + 1); + auto beg = std::sregex_iterator(s.begin(), s.end(), re); + for (auto i = beg; i != std::sregex_iterator(); ++i) { + const auto &m = *i; + auto key = s.substr(static_cast(m.position(1)), + static_cast(m.length(1))); + auto val = m.length(2) > 0 + ? s.substr(static_cast(m.position(2)), + static_cast(m.length(2))) + : s.substr(static_cast(m.position(3)), + static_cast(m.length(3))); + auth[key] = val; + } + return true; + } + } + } + return false; +} + +class ContentProviderAdapter { +public: + explicit ContentProviderAdapter( + ContentProviderWithoutLength &&content_provider) + : content_provider_(content_provider) {} + + bool operator()(size_t offset, size_t, DataSink &sink) { + return content_provider_(offset, sink); + } + +private: + ContentProviderWithoutLength content_provider_; +}; + +} // namespace detail + +inline std::string hosted_at(const std::string &hostname) { + std::vector addrs; + hosted_at(hostname, addrs); + if (addrs.empty()) { return std::string(); } + return addrs[0]; +} + +inline void hosted_at(const std::string &hostname, + std::vector &addrs) { + struct addrinfo hints; + struct addrinfo *result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + + if (getaddrinfo(hostname.c_str(), nullptr, &hints, &result)) { +#if defined __linux__ && !defined __ANDROID__ + res_init(); +#endif + return; + } + + for (auto rp = result; rp; rp = rp->ai_next) { + const auto &addr = + *reinterpret_cast(rp->ai_addr); + std::string ip; + auto dummy = -1; + if (detail::get_ip_and_port(addr, sizeof(struct sockaddr_storage), ip, + dummy)) { + addrs.push_back(ip); + } + } + + freeaddrinfo(result); +} + +inline std::string append_query_params(const std::string &path, + const Params ¶ms) { + std::string path_with_query = path; + const static std::regex re("[^?]+\\?.*"); + auto delm = std::regex_match(path, re) ? '&' : '?'; + path_with_query += delm + detail::params_to_query_str(params); + return path_with_query; +} + +// Header utilities +inline std::pair +make_range_header(const Ranges &ranges) { + std::string field = "bytes="; + auto i = 0; + for (const auto &r : ranges) { + if (i != 0) { field += ", "; } + if (r.first != -1) { field += std::to_string(r.first); } + field += '-'; + if (r.second != -1) { field += std::to_string(r.second); } + i++; + } + return std::make_pair("Range", std::move(field)); +} + +inline std::pair +make_basic_authentication_header(const std::string &username, + const std::string &password, bool is_proxy) { + auto field = "Basic " + detail::base64_encode(username + ":" + password); + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, std::move(field)); +} + +inline std::pair +make_bearer_token_authentication_header(const std::string &token, + bool is_proxy = false) { + auto field = "Bearer " + token; + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, std::move(field)); +} + +// Request implementation +inline bool Request::has_header(const std::string &key) const { + return detail::has_header(headers, key); +} + +inline std::string Request::get_header_value(const std::string &key, + size_t id) const { + return detail::get_header_value(headers, key, id, ""); +} + +inline size_t Request::get_header_value_count(const std::string &key) const { + auto r = headers.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} + +inline void Request::set_header(const std::string &key, + const std::string &val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val)) { + headers.emplace(key, val); + } +} + +inline bool Request::has_param(const std::string &key) const { + return params.find(key) != params.end(); +} + +inline std::string Request::get_param_value(const std::string &key, + size_t id) const { + auto rng = params.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { return it->second; } + return std::string(); +} + +inline size_t Request::get_param_value_count(const std::string &key) const { + auto r = params.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} + +inline bool Request::is_multipart_form_data() const { + const auto &content_type = get_header_value("Content-Type"); + return !content_type.rfind("multipart/form-data", 0); +} + +inline bool Request::has_file(const std::string &key) const { + return files.find(key) != files.end(); +} + +inline MultipartFormData Request::get_file_value(const std::string &key) const { + auto it = files.find(key); + if (it != files.end()) { return it->second; } + return MultipartFormData(); +} + +inline std::vector +Request::get_file_values(const std::string &key) const { + std::vector values; + auto rng = files.equal_range(key); + for (auto it = rng.first; it != rng.second; it++) { + values.push_back(it->second); + } + return values; +} + +// Response implementation +inline bool Response::has_header(const std::string &key) const { + return headers.find(key) != headers.end(); +} + +inline std::string Response::get_header_value(const std::string &key, + size_t id) const { + return detail::get_header_value(headers, key, id, ""); +} + +inline size_t Response::get_header_value_count(const std::string &key) const { + auto r = headers.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} + +inline void Response::set_header(const std::string &key, + const std::string &val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val)) { + headers.emplace(key, val); + } +} + +inline void Response::set_redirect(const std::string &url, int stat) { + if (!detail::has_crlf(url)) { + set_header("Location", url); + if (300 <= stat && stat < 400) { + this->status = stat; + } else { + this->status = StatusCode::Found_302; + } + } +} + +inline void Response::set_content(const char *s, size_t n, + const std::string &content_type) { + body.assign(s, n); + + auto rng = headers.equal_range("Content-Type"); + headers.erase(rng.first, rng.second); + set_header("Content-Type", content_type); +} + +inline void Response::set_content(const std::string &s, + const std::string &content_type) { + set_content(s.data(), s.size(), content_type); +} + +inline void Response::set_content(std::string &&s, + const std::string &content_type) { + body = std::move(s); + + auto rng = headers.equal_range("Content-Type"); + headers.erase(rng.first, rng.second); + set_header("Content-Type", content_type); +} + +inline void Response::set_content_provider( + size_t in_length, const std::string &content_type, ContentProvider provider, + ContentProviderResourceReleaser resource_releaser) { + set_header("Content-Type", content_type); + content_length_ = in_length; + if (in_length > 0) { content_provider_ = std::move(provider); } + content_provider_resource_releaser_ = std::move(resource_releaser); + is_chunked_content_provider_ = false; +} + +inline void Response::set_content_provider( + const std::string &content_type, ContentProviderWithoutLength provider, + ContentProviderResourceReleaser resource_releaser) { + set_header("Content-Type", content_type); + content_length_ = 0; + content_provider_ = detail::ContentProviderAdapter(std::move(provider)); + content_provider_resource_releaser_ = std::move(resource_releaser); + is_chunked_content_provider_ = false; +} + +inline void Response::set_chunked_content_provider( + const std::string &content_type, ContentProviderWithoutLength provider, + ContentProviderResourceReleaser resource_releaser) { + set_header("Content-Type", content_type); + content_length_ = 0; + content_provider_ = detail::ContentProviderAdapter(std::move(provider)); + content_provider_resource_releaser_ = std::move(resource_releaser); + is_chunked_content_provider_ = true; +} + +// Result implementation +inline bool Result::has_request_header(const std::string &key) const { + return request_headers_.find(key) != request_headers_.end(); +} + +inline std::string Result::get_request_header_value(const std::string &key, + size_t id) const { + return detail::get_header_value(request_headers_, key, id, ""); +} + +inline size_t +Result::get_request_header_value_count(const std::string &key) const { + auto r = request_headers_.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} + +// Stream implementation +inline ssize_t Stream::write(const char *ptr) { + return write(ptr, strlen(ptr)); +} + +inline ssize_t Stream::write(const std::string &s) { + return write(s.data(), s.size()); +} + +namespace detail { + +// Socket stream implementation +inline SocketStream::SocketStream(socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec) + : sock_(sock), read_timeout_sec_(read_timeout_sec), + read_timeout_usec_(read_timeout_usec), + write_timeout_sec_(write_timeout_sec), + write_timeout_usec_(write_timeout_usec), read_buff_(read_buff_size_, 0) {} + +inline SocketStream::~SocketStream() = default; + +inline bool SocketStream::is_readable() const { + return select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0; +} + +inline bool SocketStream::is_writable() const { + return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0 && + is_socket_alive(sock_); +} + +inline ssize_t SocketStream::read(char *ptr, size_t size) { +#ifdef _WIN32 + size = + (std::min)(size, static_cast((std::numeric_limits::max)())); +#else + size = (std::min)(size, + static_cast((std::numeric_limits::max)())); +#endif + + if (read_buff_off_ < read_buff_content_size_) { + auto remaining_size = read_buff_content_size_ - read_buff_off_; + if (size <= remaining_size) { + memcpy(ptr, read_buff_.data() + read_buff_off_, size); + read_buff_off_ += size; + return static_cast(size); + } else { + memcpy(ptr, read_buff_.data() + read_buff_off_, remaining_size); + read_buff_off_ += remaining_size; + return static_cast(remaining_size); + } + } + + if (!is_readable()) { return -1; } + + read_buff_off_ = 0; + read_buff_content_size_ = 0; + + if (size < read_buff_size_) { + auto n = read_socket(sock_, read_buff_.data(), read_buff_size_, + CPPHTTPLIB_RECV_FLAGS); + if (n <= 0) { + return n; + } else if (n <= static_cast(size)) { + memcpy(ptr, read_buff_.data(), static_cast(n)); + return n; + } else { + memcpy(ptr, read_buff_.data(), size); + read_buff_off_ = size; + read_buff_content_size_ = static_cast(n); + return static_cast(size); + } + } else { + return read_socket(sock_, ptr, size, CPPHTTPLIB_RECV_FLAGS); + } +} + +inline ssize_t SocketStream::write(const char *ptr, size_t size) { + if (!is_writable()) { return -1; } + +#if defined(_WIN32) && !defined(_WIN64) + size = + (std::min)(size, static_cast((std::numeric_limits::max)())); +#endif + + return send_socket(sock_, ptr, size, CPPHTTPLIB_SEND_FLAGS); +} + +inline void SocketStream::get_remote_ip_and_port(std::string &ip, + int &port) const { + return detail::get_remote_ip_and_port(sock_, ip, port); +} + +inline void SocketStream::get_local_ip_and_port(std::string &ip, + int &port) const { + return detail::get_local_ip_and_port(sock_, ip, port); +} + +inline socket_t SocketStream::socket() const { return sock_; } + +// Buffer stream implementation +inline bool BufferStream::is_readable() const { return true; } + +inline bool BufferStream::is_writable() const { return true; } + +inline ssize_t BufferStream::read(char *ptr, size_t size) { +#if defined(_MSC_VER) && _MSC_VER < 1910 + auto len_read = buffer._Copy_s(ptr, size, size, position); +#else + auto len_read = buffer.copy(ptr, size, position); +#endif + position += static_cast(len_read); + return static_cast(len_read); +} + +inline ssize_t BufferStream::write(const char *ptr, size_t size) { + buffer.append(ptr, size); + return static_cast(size); +} + +inline void BufferStream::get_remote_ip_and_port(std::string & /*ip*/, + int & /*port*/) const {} + +inline void BufferStream::get_local_ip_and_port(std::string & /*ip*/, + int & /*port*/) const {} + +inline socket_t BufferStream::socket() const { return 0; } + +inline const std::string &BufferStream::get_buffer() const { return buffer; } + +inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern) { + // One past the last ending position of a path param substring + std::size_t last_param_end = 0; + +#ifndef CPPHTTPLIB_NO_EXCEPTIONS + // Needed to ensure that parameter names are unique during matcher + // construction + // If exceptions are disabled, only last duplicate path + // parameter will be set + std::unordered_set param_name_set; +#endif + + while (true) { + const auto marker_pos = pattern.find(marker, last_param_end); + if (marker_pos == std::string::npos) { break; } + + static_fragments_.push_back( + pattern.substr(last_param_end, marker_pos - last_param_end)); + + const auto param_name_start = marker_pos + 1; + + auto sep_pos = pattern.find(separator, param_name_start); + if (sep_pos == std::string::npos) { sep_pos = pattern.length(); } + + auto param_name = + pattern.substr(param_name_start, sep_pos - param_name_start); + +#ifndef CPPHTTPLIB_NO_EXCEPTIONS + if (param_name_set.find(param_name) != param_name_set.cend()) { + std::string msg = "Encountered path parameter '" + param_name + + "' multiple times in route pattern '" + pattern + "'."; + throw std::invalid_argument(msg); + } +#endif + + param_names_.push_back(std::move(param_name)); + + last_param_end = sep_pos + 1; + } + + if (last_param_end < pattern.length()) { + static_fragments_.push_back(pattern.substr(last_param_end)); + } +} + +inline bool PathParamsMatcher::match(Request &request) const { + request.matches = std::smatch(); + request.path_params.clear(); + request.path_params.reserve(param_names_.size()); + + // One past the position at which the path matched the pattern last time + std::size_t starting_pos = 0; + for (size_t i = 0; i < static_fragments_.size(); ++i) { + const auto &fragment = static_fragments_[i]; + + if (starting_pos + fragment.length() > request.path.length()) { + return false; + } + + // Avoid unnecessary allocation by using strncmp instead of substr + + // comparison + if (std::strncmp(request.path.c_str() + starting_pos, fragment.c_str(), + fragment.length()) != 0) { + return false; + } + + starting_pos += fragment.length(); + + // Should only happen when we have a static fragment after a param + // Example: '/users/:id/subscriptions' + // The 'subscriptions' fragment here does not have a corresponding param + if (i >= param_names_.size()) { continue; } + + auto sep_pos = request.path.find(separator, starting_pos); + if (sep_pos == std::string::npos) { sep_pos = request.path.length(); } + + const auto ¶m_name = param_names_[i]; + + request.path_params.emplace( + param_name, request.path.substr(starting_pos, sep_pos - starting_pos)); + + // Mark everythin up to '/' as matched + starting_pos = sep_pos + 1; + } + // Returns false if the path is longer than the pattern + return starting_pos >= request.path.length(); +} + +inline bool RegexMatcher::match(Request &request) const { + request.path_params.clear(); + return std::regex_match(request.path, request.matches, regex_); +} + +} // namespace detail + +// HTTP server implementation +inline Server::Server() + : new_task_queue( + [] { return new ThreadPool(CPPHTTPLIB_THREAD_POOL_COUNT); }) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif +} + +inline Server::~Server() = default; + +inline std::unique_ptr +Server::make_matcher(const std::string &pattern) { + if (pattern.find("/:") != std::string::npos) { + return detail::make_unique(pattern); + } else { + return detail::make_unique(pattern); + } +} + +inline Server &Server::Get(const std::string &pattern, Handler handler) { + get_handlers_.emplace_back(make_matcher(pattern), std::move(handler)); + return *this; +} + +inline Server &Server::Post(const std::string &pattern, Handler handler) { + post_handlers_.emplace_back(make_matcher(pattern), std::move(handler)); + return *this; +} + +inline Server &Server::Post(const std::string &pattern, + HandlerWithContentReader handler) { + post_handlers_for_content_reader_.emplace_back(make_matcher(pattern), + std::move(handler)); + return *this; +} + +inline Server &Server::Put(const std::string &pattern, Handler handler) { + put_handlers_.emplace_back(make_matcher(pattern), std::move(handler)); + return *this; +} + +inline Server &Server::Put(const std::string &pattern, + HandlerWithContentReader handler) { + put_handlers_for_content_reader_.emplace_back(make_matcher(pattern), + std::move(handler)); + return *this; +} + +inline Server &Server::Patch(const std::string &pattern, Handler handler) { + patch_handlers_.emplace_back(make_matcher(pattern), std::move(handler)); + return *this; +} + +inline Server &Server::Patch(const std::string &pattern, + HandlerWithContentReader handler) { + patch_handlers_for_content_reader_.emplace_back(make_matcher(pattern), + std::move(handler)); + return *this; +} + +inline Server &Server::Delete(const std::string &pattern, Handler handler) { + delete_handlers_.emplace_back(make_matcher(pattern), std::move(handler)); + return *this; +} + +inline Server &Server::Delete(const std::string &pattern, + HandlerWithContentReader handler) { + delete_handlers_for_content_reader_.emplace_back(make_matcher(pattern), + std::move(handler)); + return *this; +} + +inline Server &Server::Options(const std::string &pattern, Handler handler) { + options_handlers_.emplace_back(make_matcher(pattern), std::move(handler)); + return *this; +} + +inline bool Server::set_base_dir(const std::string &dir, + const std::string &mount_point) { + return set_mount_point(mount_point, dir); +} + +inline bool Server::set_mount_point(const std::string &mount_point, + const std::string &dir, Headers headers) { + if (detail::is_dir(dir)) { + std::string mnt = !mount_point.empty() ? mount_point : "/"; + if (!mnt.empty() && mnt[0] == '/') { + base_dirs_.push_back({mnt, dir, std::move(headers)}); + return true; + } + } + return false; +} + +inline bool Server::remove_mount_point(const std::string &mount_point) { + for (auto it = base_dirs_.begin(); it != base_dirs_.end(); ++it) { + if (it->mount_point == mount_point) { + base_dirs_.erase(it); + return true; + } + } + return false; +} + +inline Server & +Server::set_file_extension_and_mimetype_mapping(const std::string &ext, + const std::string &mime) { + file_extension_and_mimetype_map_[ext] = mime; + return *this; +} + +inline Server &Server::set_default_file_mimetype(const std::string &mime) { + default_file_mimetype_ = mime; + return *this; +} + +inline Server &Server::set_file_request_handler(Handler handler) { + file_request_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_error_handler(HandlerWithResponse handler) { + error_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_error_handler(Handler handler) { + error_handler_ = [handler](const Request &req, Response &res) { + handler(req, res); + return HandlerResponse::Handled; + }; + return *this; +} + +inline Server &Server::set_exception_handler(ExceptionHandler handler) { + exception_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_pre_routing_handler(HandlerWithResponse handler) { + pre_routing_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_post_routing_handler(Handler handler) { + post_routing_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_logger(Logger logger) { + logger_ = std::move(logger); + return *this; +} + +inline Server & +Server::set_expect_100_continue_handler(Expect100ContinueHandler handler) { + expect_100_continue_handler_ = std::move(handler); + return *this; +} + +inline Server &Server::set_address_family(int family) { + address_family_ = family; + return *this; +} + +inline Server &Server::set_tcp_nodelay(bool on) { + tcp_nodelay_ = on; + return *this; +} + +inline Server &Server::set_socket_options(SocketOptions socket_options) { + socket_options_ = std::move(socket_options); + return *this; +} + +inline Server &Server::set_default_headers(Headers headers) { + default_headers_ = std::move(headers); + return *this; +} + +inline Server &Server::set_header_writer( + std::function const &writer) { + header_writer_ = writer; + return *this; +} + +inline Server &Server::set_keep_alive_max_count(size_t count) { + keep_alive_max_count_ = count; + return *this; +} + +inline Server &Server::set_keep_alive_timeout(time_t sec) { + keep_alive_timeout_sec_ = sec; + return *this; +} + +inline Server &Server::set_read_timeout(time_t sec, time_t usec) { + read_timeout_sec_ = sec; + read_timeout_usec_ = usec; + return *this; +} + +inline Server &Server::set_write_timeout(time_t sec, time_t usec) { + write_timeout_sec_ = sec; + write_timeout_usec_ = usec; + return *this; +} + +inline Server &Server::set_idle_interval(time_t sec, time_t usec) { + idle_interval_sec_ = sec; + idle_interval_usec_ = usec; + return *this; +} + +inline Server &Server::set_payload_max_length(size_t length) { + payload_max_length_ = length; + return *this; +} + +inline bool Server::bind_to_port(const std::string &host, int port, + int socket_flags) { + return bind_internal(host, port, socket_flags) >= 0; +} +inline int Server::bind_to_any_port(const std::string &host, int socket_flags) { + return bind_internal(host, 0, socket_flags); +} + +inline bool Server::listen_after_bind() { + auto se = detail::scope_exit([&]() { done_ = true; }); + return listen_internal(); +} + +inline bool Server::listen(const std::string &host, int port, + int socket_flags) { + auto se = detail::scope_exit([&]() { done_ = true; }); + return bind_to_port(host, port, socket_flags) && listen_internal(); +} + +inline bool Server::is_running() const { return is_running_; } + +inline void Server::wait_until_ready() const { + while (!is_running() && !done_) { + std::this_thread::sleep_for(std::chrono::milliseconds{1}); + } +} + +inline void Server::stop() { + if (is_running_) { + assert(svr_sock_ != INVALID_SOCKET); + std::atomic sock(svr_sock_.exchange(INVALID_SOCKET)); + detail::shutdown_socket(sock); + detail::close_socket(sock); + } +} + +inline bool Server::parse_request_line(const char *s, Request &req) const { + auto len = strlen(s); + if (len < 2 || s[len - 2] != '\r' || s[len - 1] != '\n') { return false; } + len -= 2; + + { + size_t count = 0; + + detail::split(s, s + len, ' ', [&](const char *b, const char *e) { + switch (count) { + case 0: req.method = std::string(b, e); break; + case 1: req.target = std::string(b, e); break; + case 2: req.version = std::string(b, e); break; + default: break; + } + count++; + }); + + if (count != 3) { return false; } + } + + static const std::set methods{ + "GET", "HEAD", "POST", "PUT", "DELETE", + "CONNECT", "OPTIONS", "TRACE", "PATCH", "PRI"}; + + if (methods.find(req.method) == methods.end()) { return false; } + + if (req.version != "HTTP/1.1" && req.version != "HTTP/1.0") { return false; } + + { + // Skip URL fragment + for (size_t i = 0; i < req.target.size(); i++) { + if (req.target[i] == '#') { + req.target.erase(i); + break; + } + } + + size_t count = 0; + + detail::split(req.target.data(), req.target.data() + req.target.size(), '?', + 2, [&](const char *b, const char *e) { + switch (count) { + case 0: + req.path = detail::decode_url(std::string(b, e), false); + break; + case 1: { + if (e - b > 0) { + detail::parse_query_text(std::string(b, e), req.params); + } + break; + } + default: break; + } + count++; + }); + + if (count > 2) { return false; } + } + + return true; +} + +inline bool Server::write_response(Stream &strm, bool close_connection, + Request &req, Response &res) { + // NOTE: `req.ranges` should be empty, otherwise it will be applied + // incorrectly to the error content. + req.ranges.clear(); + return write_response_core(strm, close_connection, req, res, false); +} + +inline bool Server::write_response_with_content(Stream &strm, + bool close_connection, + const Request &req, + Response &res) { + return write_response_core(strm, close_connection, req, res, true); +} + +inline bool Server::write_response_core(Stream &strm, bool close_connection, + const Request &req, Response &res, + bool need_apply_ranges) { + assert(res.status != -1); + + if (400 <= res.status && error_handler_ && + error_handler_(req, res) == HandlerResponse::Handled) { + need_apply_ranges = true; + } + + std::string content_type; + std::string boundary; + if (need_apply_ranges) { apply_ranges(req, res, content_type, boundary); } + + // Prepare additional headers + if (close_connection || req.get_header_value("Connection") == "close") { + res.set_header("Connection", "close"); + } else { + std::stringstream ss; + ss << "timeout=" << keep_alive_timeout_sec_ + << ", max=" << keep_alive_max_count_; + res.set_header("Keep-Alive", ss.str()); + } + + if (!res.has_header("Content-Type") && + (!res.body.empty() || res.content_length_ > 0 || res.content_provider_)) { + res.set_header("Content-Type", "text/plain"); + } + + if (!res.has_header("Content-Length") && res.body.empty() && + !res.content_length_ && !res.content_provider_) { + res.set_header("Content-Length", "0"); + } + + if (!res.has_header("Accept-Ranges") && req.method == "HEAD") { + res.set_header("Accept-Ranges", "bytes"); + } + + if (post_routing_handler_) { post_routing_handler_(req, res); } + + // Response line and headers + { + detail::BufferStream bstrm; + + if (!bstrm.write_format("HTTP/1.1 %d %s\r\n", res.status, + status_message(res.status))) { + return false; + } + + if (!header_writer_(bstrm, res.headers)) { return false; } + + // Flush buffer + auto &data = bstrm.get_buffer(); + detail::write_data(strm, data.data(), data.size()); + } + + // Body + auto ret = true; + if (req.method != "HEAD") { + if (!res.body.empty()) { + if (!detail::write_data(strm, res.body.data(), res.body.size())) { + ret = false; + } + } else if (res.content_provider_) { + if (write_content_with_provider(strm, req, res, boundary, content_type)) { + res.content_provider_success_ = true; + } else { + ret = false; + } + } + } + + // Log + if (logger_) { logger_(req, res); } + + return ret; +} + +inline bool +Server::write_content_with_provider(Stream &strm, const Request &req, + Response &res, const std::string &boundary, + const std::string &content_type) { + auto is_shutting_down = [this]() { + return this->svr_sock_ == INVALID_SOCKET; + }; + + if (res.content_length_ > 0) { + if (req.ranges.empty()) { + return detail::write_content(strm, res.content_provider_, 0, + res.content_length_, is_shutting_down); + } else if (req.ranges.size() == 1) { + auto offset_and_length = detail::get_range_offset_and_length( + req.ranges[0], res.content_length_); + + return detail::write_content(strm, res.content_provider_, + offset_and_length.first, + offset_and_length.second, is_shutting_down); + } else { + return detail::write_multipart_ranges_data( + strm, req, res, boundary, content_type, res.content_length_, + is_shutting_down); + } + } else { + if (res.is_chunked_content_provider_) { + auto type = detail::encoding_type(req, res); + + std::unique_ptr compressor; + if (type == detail::EncodingType::Gzip) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + compressor = detail::make_unique(); +#endif + } else if (type == detail::EncodingType::Brotli) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + compressor = detail::make_unique(); +#endif + } else { + compressor = detail::make_unique(); + } + assert(compressor != nullptr); + + return detail::write_content_chunked(strm, res.content_provider_, + is_shutting_down, *compressor); + } else { + return detail::write_content_without_length(strm, res.content_provider_, + is_shutting_down); + } + } +} + +inline bool Server::read_content(Stream &strm, Request &req, Response &res) { + MultipartFormDataMap::iterator cur; + auto file_count = 0; + if (read_content_core( + strm, req, res, + // Regular + [&](const char *buf, size_t n) { + if (req.body.size() + n > req.body.max_size()) { return false; } + req.body.append(buf, n); + return true; + }, + // Multipart + [&](const MultipartFormData &file) { + if (file_count++ == CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT) { + return false; + } + cur = req.files.emplace(file.name, file); + return true; + }, + [&](const char *buf, size_t n) { + auto &content = cur->second.content; + if (content.size() + n > content.max_size()) { return false; } + content.append(buf, n); + return true; + })) { + const auto &content_type = req.get_header_value("Content-Type"); + if (!content_type.find("application/x-www-form-urlencoded")) { + if (req.body.size() > CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH) { + res.status = StatusCode::PayloadTooLarge_413; // NOTE: should be 414? + return false; + } + detail::parse_query_text(req.body, req.params); + } + return true; + } + return false; +} + +inline bool Server::read_content_with_content_receiver( + Stream &strm, Request &req, Response &res, ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver) { + return read_content_core(strm, req, res, std::move(receiver), + std::move(multipart_header), + std::move(multipart_receiver)); +} + +inline bool +Server::read_content_core(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver) const { + detail::MultipartFormDataParser multipart_form_data_parser; + ContentReceiverWithProgress out; + + if (req.is_multipart_form_data()) { + const auto &content_type = req.get_header_value("Content-Type"); + std::string boundary; + if (!detail::parse_multipart_boundary(content_type, boundary)) { + res.status = StatusCode::BadRequest_400; + return false; + } + + multipart_form_data_parser.set_boundary(std::move(boundary)); + out = [&](const char *buf, size_t n, uint64_t /*off*/, uint64_t /*len*/) { + /* For debug + size_t pos = 0; + while (pos < n) { + auto read_size = (std::min)(1, n - pos); + auto ret = multipart_form_data_parser.parse( + buf + pos, read_size, multipart_receiver, multipart_header); + if (!ret) { return false; } + pos += read_size; + } + return true; + */ + return multipart_form_data_parser.parse(buf, n, multipart_receiver, + multipart_header); + }; + } else { + out = [receiver](const char *buf, size_t n, uint64_t /*off*/, + uint64_t /*len*/) { return receiver(buf, n); }; + } + + if (req.method == "DELETE" && !req.has_header("Content-Length")) { + return true; + } + + if (!detail::read_content(strm, req, payload_max_length_, res.status, nullptr, + out, true)) { + return false; + } + + if (req.is_multipart_form_data()) { + if (!multipart_form_data_parser.is_valid()) { + res.status = StatusCode::BadRequest_400; + return false; + } + } + + return true; +} + +inline bool Server::handle_file_request(const Request &req, Response &res, + bool head) { + for (const auto &entry : base_dirs_) { + // Prefix match + if (!req.path.compare(0, entry.mount_point.size(), entry.mount_point)) { + std::string sub_path = "/" + req.path.substr(entry.mount_point.size()); + if (detail::is_valid_path(sub_path)) { + auto path = entry.base_dir + sub_path; + if (path.back() == '/') { path += "index.html"; } + + if (detail::is_file(path)) { + for (const auto &kv : entry.headers) { + res.set_header(kv.first, kv.second); + } + + auto mm = std::make_shared(path.c_str()); + if (!mm->is_open()) { return false; } + + res.set_content_provider( + mm->size(), + detail::find_content_type(path, file_extension_and_mimetype_map_, + default_file_mimetype_), + [mm](size_t offset, size_t length, DataSink &sink) -> bool { + sink.write(mm->data() + offset, length); + return true; + }); + + if (!head && file_request_handler_) { + file_request_handler_(req, res); + } + + return true; + } + } + } + } + return false; +} + +inline socket_t +Server::create_server_socket(const std::string &host, int port, + int socket_flags, + SocketOptions socket_options) const { + return detail::create_socket( + host, std::string(), port, address_family_, socket_flags, tcp_nodelay_, + std::move(socket_options), + [](socket_t sock, struct addrinfo &ai) -> bool { + if (::bind(sock, ai.ai_addr, static_cast(ai.ai_addrlen))) { + return false; + } + if (::listen(sock, CPPHTTPLIB_LISTEN_BACKLOG)) { return false; } + return true; + }); +} + +inline int Server::bind_internal(const std::string &host, int port, + int socket_flags) { + if (!is_valid()) { return -1; } + + svr_sock_ = create_server_socket(host, port, socket_flags, socket_options_); + if (svr_sock_ == INVALID_SOCKET) { return -1; } + + if (port == 0) { + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + if (getsockname(svr_sock_, reinterpret_cast(&addr), + &addr_len) == -1) { + return -1; + } + if (addr.ss_family == AF_INET) { + return ntohs(reinterpret_cast(&addr)->sin_port); + } else if (addr.ss_family == AF_INET6) { + return ntohs(reinterpret_cast(&addr)->sin6_port); + } else { + return -1; + } + } else { + return port; + } +} + +inline bool Server::listen_internal() { + auto ret = true; + is_running_ = true; + auto se = detail::scope_exit([&]() { is_running_ = false; }); + + { + std::unique_ptr task_queue(new_task_queue()); + + while (svr_sock_ != INVALID_SOCKET) { +#ifndef _WIN32 + if (idle_interval_sec_ > 0 || idle_interval_usec_ > 0) { +#endif + auto val = detail::select_read(svr_sock_, idle_interval_sec_, + idle_interval_usec_); + if (val == 0) { // Timeout + task_queue->on_idle(); + continue; + } +#ifndef _WIN32 + } +#endif + socket_t sock = accept(svr_sock_, nullptr, nullptr); + + if (sock == INVALID_SOCKET) { + if (errno == EMFILE) { + // The per-process limit of open file descriptors has been reached. + // Try to accept new connections after a short sleep. + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + continue; + } else if (errno == EINTR || errno == EAGAIN) { + continue; + } + if (svr_sock_ != INVALID_SOCKET) { + detail::close_socket(svr_sock_); + ret = false; + } else { + ; // The server socket was closed by user. + } + break; + } + + { +#ifdef _WIN32 + auto timeout = static_cast(read_timeout_sec_ * 1000 + + read_timeout_usec_ / 1000); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&timeout), sizeof(timeout)); +#else + timeval tv; + tv.tv_sec = static_cast(read_timeout_sec_); + tv.tv_usec = static_cast(read_timeout_usec_); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&tv), sizeof(tv)); +#endif + } + { + +#ifdef _WIN32 + auto timeout = static_cast(write_timeout_sec_ * 1000 + + write_timeout_usec_ / 1000); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, + reinterpret_cast(&timeout), sizeof(timeout)); +#else + timeval tv; + tv.tv_sec = static_cast(write_timeout_sec_); + tv.tv_usec = static_cast(write_timeout_usec_); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, + reinterpret_cast(&tv), sizeof(tv)); +#endif + } + + if (!task_queue->enqueue( + [this, sock]() { process_and_close_socket(sock); })) { + detail::shutdown_socket(sock); + detail::close_socket(sock); + } + } + + task_queue->shutdown(); + } + + return ret; +} + +inline bool Server::routing(Request &req, Response &res, Stream &strm) { + if (pre_routing_handler_ && + pre_routing_handler_(req, res) == HandlerResponse::Handled) { + return true; + } + + // File handler + auto is_head_request = req.method == "HEAD"; + if ((req.method == "GET" || is_head_request) && + handle_file_request(req, res, is_head_request)) { + return true; + } + + if (detail::expect_content(req)) { + // Content reader handler + { + ContentReader reader( + [&](ContentReceiver receiver) { + return read_content_with_content_receiver( + strm, req, res, std::move(receiver), nullptr, nullptr); + }, + [&](MultipartContentHeader header, ContentReceiver receiver) { + return read_content_with_content_receiver(strm, req, res, nullptr, + std::move(header), + std::move(receiver)); + }); + + if (req.method == "POST") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + post_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "PUT") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + put_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "PATCH") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + patch_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "DELETE") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + delete_handlers_for_content_reader_)) { + return true; + } + } + } + + // Read content into `req.body` + if (!read_content(strm, req, res)) { return false; } + } + + // Regular handler + if (req.method == "GET" || req.method == "HEAD") { + return dispatch_request(req, res, get_handlers_); + } else if (req.method == "POST") { + return dispatch_request(req, res, post_handlers_); + } else if (req.method == "PUT") { + return dispatch_request(req, res, put_handlers_); + } else if (req.method == "DELETE") { + return dispatch_request(req, res, delete_handlers_); + } else if (req.method == "OPTIONS") { + return dispatch_request(req, res, options_handlers_); + } else if (req.method == "PATCH") { + return dispatch_request(req, res, patch_handlers_); + } + + res.status = StatusCode::BadRequest_400; + return false; +} + +inline bool Server::dispatch_request(Request &req, Response &res, + const Handlers &handlers) const { + for (const auto &x : handlers) { + const auto &matcher = x.first; + const auto &handler = x.second; + + if (matcher->match(req)) { + handler(req, res); + return true; + } + } + return false; +} + +inline void Server::apply_ranges(const Request &req, Response &res, + std::string &content_type, + std::string &boundary) const { + if (req.ranges.size() > 1) { + auto it = res.headers.find("Content-Type"); + if (it != res.headers.end()) { + content_type = it->second; + res.headers.erase(it); + } + + boundary = detail::make_multipart_data_boundary(); + + res.set_header("Content-Type", + "multipart/byteranges; boundary=" + boundary); + } + + auto type = detail::encoding_type(req, res); + + if (res.body.empty()) { + if (res.content_length_ > 0) { + size_t length = 0; + if (req.ranges.empty()) { + length = res.content_length_; + } else if (req.ranges.size() == 1) { + auto offset_and_length = detail::get_range_offset_and_length( + req.ranges[0], res.content_length_); + + length = offset_and_length.second; + + auto content_range = detail::make_content_range_header_field( + offset_and_length, res.content_length_); + res.set_header("Content-Range", content_range); + } else { + length = detail::get_multipart_ranges_data_length( + req, boundary, content_type, res.content_length_); + } + res.set_header("Content-Length", std::to_string(length)); + } else { + if (res.content_provider_) { + if (res.is_chunked_content_provider_) { + res.set_header("Transfer-Encoding", "chunked"); + if (type == detail::EncodingType::Gzip) { + res.set_header("Content-Encoding", "gzip"); + } else if (type == detail::EncodingType::Brotli) { + res.set_header("Content-Encoding", "br"); + } + } + } + } + } else { + if (req.ranges.empty()) { + ; + } else if (req.ranges.size() == 1) { + auto offset_and_length = + detail::get_range_offset_and_length(req.ranges[0], res.body.size()); + auto offset = offset_and_length.first; + auto length = offset_and_length.second; + + auto content_range = detail::make_content_range_header_field( + offset_and_length, res.body.size()); + res.set_header("Content-Range", content_range); + + assert(offset + length <= res.body.size()); + res.body = res.body.substr(offset, length); + } else { + std::string data; + detail::make_multipart_ranges_data(req, res, boundary, content_type, + res.body.size(), data); + res.body.swap(data); + } + + if (type != detail::EncodingType::None) { + std::unique_ptr compressor; + std::string content_encoding; + + if (type == detail::EncodingType::Gzip) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + compressor = detail::make_unique(); + content_encoding = "gzip"; +#endif + } else if (type == detail::EncodingType::Brotli) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + compressor = detail::make_unique(); + content_encoding = "br"; +#endif + } + + if (compressor) { + std::string compressed; + if (compressor->compress(res.body.data(), res.body.size(), true, + [&](const char *data, size_t data_len) { + compressed.append(data, data_len); + return true; + })) { + res.body.swap(compressed); + res.set_header("Content-Encoding", content_encoding); + } + } + } + + auto length = std::to_string(res.body.size()); + res.set_header("Content-Length", length); + } +} + +inline bool Server::dispatch_request_for_content_reader( + Request &req, Response &res, ContentReader content_reader, + const HandlersForContentReader &handlers) const { + for (const auto &x : handlers) { + const auto &matcher = x.first; + const auto &handler = x.second; + + if (matcher->match(req)) { + handler(req, res, content_reader); + return true; + } + } + return false; +} + +inline bool +Server::process_request(Stream &strm, bool close_connection, + bool &connection_closed, + const std::function &setup_request) { + std::array buf{}; + + detail::stream_line_reader line_reader(strm, buf.data(), buf.size()); + + // Connection has been closed on client + if (!line_reader.getline()) { return false; } + + Request req; + + Response res; + res.version = "HTTP/1.1"; + res.headers = default_headers_; + +#ifdef _WIN32 + // TODO: Increase FD_SETSIZE statically (libzmq), dynamically (MySQL). +#else +#ifndef CPPHTTPLIB_USE_POLL + // Socket file descriptor exceeded FD_SETSIZE... + if (strm.socket() >= FD_SETSIZE) { + Headers dummy; + detail::read_headers(strm, dummy); + res.status = StatusCode::InternalServerError_500; + return write_response(strm, close_connection, req, res); + } +#endif +#endif + + // Check if the request URI doesn't exceed the limit + if (line_reader.size() > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) { + Headers dummy; + detail::read_headers(strm, dummy); + res.status = StatusCode::UriTooLong_414; + return write_response(strm, close_connection, req, res); + } + + // Request line and headers + if (!parse_request_line(line_reader.ptr(), req) || + !detail::read_headers(strm, req.headers)) { + res.status = StatusCode::BadRequest_400; + return write_response(strm, close_connection, req, res); + } + + if (req.get_header_value("Connection") == "close") { + connection_closed = true; + } + + if (req.version == "HTTP/1.0" && + req.get_header_value("Connection") != "Keep-Alive") { + connection_closed = true; + } + + strm.get_remote_ip_and_port(req.remote_addr, req.remote_port); + req.set_header("REMOTE_ADDR", req.remote_addr); + req.set_header("REMOTE_PORT", std::to_string(req.remote_port)); + + strm.get_local_ip_and_port(req.local_addr, req.local_port); + req.set_header("LOCAL_ADDR", req.local_addr); + req.set_header("LOCAL_PORT", std::to_string(req.local_port)); + + if (req.has_header("Range")) { + const auto &range_header_value = req.get_header_value("Range"); + if (!detail::parse_range_header(range_header_value, req.ranges)) { + res.status = StatusCode::RangeNotSatisfiable_416; + return write_response(strm, close_connection, req, res); + } + } + + if (setup_request) { setup_request(req); } + + if (req.get_header_value("Expect") == "100-continue") { + int status = StatusCode::Continue_100; + if (expect_100_continue_handler_) { + status = expect_100_continue_handler_(req, res); + } + switch (status) { + case StatusCode::Continue_100: + case StatusCode::ExpectationFailed_417: + strm.write_format("HTTP/1.1 %d %s\r\n\r\n", status, + status_message(status)); + break; + default: return write_response(strm, close_connection, req, res); + } + } + + // Routing + auto routed = false; +#ifdef CPPHTTPLIB_NO_EXCEPTIONS + routed = routing(req, res, strm); +#else + try { + routed = routing(req, res, strm); + } catch (std::exception &e) { + if (exception_handler_) { + auto ep = std::current_exception(); + exception_handler_(req, res, ep); + routed = true; + } else { + res.status = StatusCode::InternalServerError_500; + std::string val; + auto s = e.what(); + for (size_t i = 0; s[i]; i++) { + switch (s[i]) { + case '\r': val += "\\r"; break; + case '\n': val += "\\n"; break; + default: val += s[i]; break; + } + } + res.set_header("EXCEPTION_WHAT", val); + } + } catch (...) { + if (exception_handler_) { + auto ep = std::current_exception(); + exception_handler_(req, res, ep); + routed = true; + } else { + res.status = StatusCode::InternalServerError_500; + res.set_header("EXCEPTION_WHAT", "UNKNOWN"); + } + } +#endif + if (routed) { + if (res.status == -1) { + res.status = req.ranges.empty() ? StatusCode::OK_200 + : StatusCode::PartialContent_206; + } + + if (detail::range_error(req, res)) { + res.body.clear(); + res.content_length_ = 0; + res.content_provider_ = nullptr; + res.status = StatusCode::RangeNotSatisfiable_416; + return write_response(strm, close_connection, req, res); + } + + return write_response_with_content(strm, close_connection, req, res); + } else { + if (res.status == -1) { res.status = StatusCode::NotFound_404; } + + return write_response(strm, close_connection, req, res); + } +} + +inline bool Server::is_valid() const { return true; } + +inline bool Server::process_and_close_socket(socket_t sock) { + auto ret = detail::process_server_socket( + svr_sock_, sock, keep_alive_max_count_, keep_alive_timeout_sec_, + read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, + [this](Stream &strm, bool close_connection, bool &connection_closed) { + return process_request(strm, close_connection, connection_closed, + nullptr); + }); + + detail::shutdown_socket(sock); + detail::close_socket(sock); + return ret; +} + +// HTTP client implementation +inline ClientImpl::ClientImpl(const std::string &host) + : ClientImpl(host, 80, std::string(), std::string()) {} + +inline ClientImpl::ClientImpl(const std::string &host, int port) + : ClientImpl(host, port, std::string(), std::string()) {} + +inline ClientImpl::ClientImpl(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + : host_(host), port_(port), + host_and_port_(adjust_host_string(host) + ":" + std::to_string(port)), + client_cert_path_(client_cert_path), client_key_path_(client_key_path) {} + +inline ClientImpl::~ClientImpl() { + std::lock_guard guard(socket_mutex_); + shutdown_socket(socket_); + close_socket(socket_); +} + +inline bool ClientImpl::is_valid() const { return true; } + +inline void ClientImpl::copy_settings(const ClientImpl &rhs) { + client_cert_path_ = rhs.client_cert_path_; + client_key_path_ = rhs.client_key_path_; + connection_timeout_sec_ = rhs.connection_timeout_sec_; + read_timeout_sec_ = rhs.read_timeout_sec_; + read_timeout_usec_ = rhs.read_timeout_usec_; + write_timeout_sec_ = rhs.write_timeout_sec_; + write_timeout_usec_ = rhs.write_timeout_usec_; + basic_auth_username_ = rhs.basic_auth_username_; + basic_auth_password_ = rhs.basic_auth_password_; + bearer_token_auth_token_ = rhs.bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + digest_auth_username_ = rhs.digest_auth_username_; + digest_auth_password_ = rhs.digest_auth_password_; +#endif + keep_alive_ = rhs.keep_alive_; + follow_location_ = rhs.follow_location_; + url_encode_ = rhs.url_encode_; + address_family_ = rhs.address_family_; + tcp_nodelay_ = rhs.tcp_nodelay_; + socket_options_ = rhs.socket_options_; + compress_ = rhs.compress_; + decompress_ = rhs.decompress_; + interface_ = rhs.interface_; + proxy_host_ = rhs.proxy_host_; + proxy_port_ = rhs.proxy_port_; + proxy_basic_auth_username_ = rhs.proxy_basic_auth_username_; + proxy_basic_auth_password_ = rhs.proxy_basic_auth_password_; + proxy_bearer_token_auth_token_ = rhs.proxy_bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + proxy_digest_auth_username_ = rhs.proxy_digest_auth_username_; + proxy_digest_auth_password_ = rhs.proxy_digest_auth_password_; +#endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + ca_cert_file_path_ = rhs.ca_cert_file_path_; + ca_cert_dir_path_ = rhs.ca_cert_dir_path_; + ca_cert_store_ = rhs.ca_cert_store_; +#endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + server_certificate_verification_ = rhs.server_certificate_verification_; +#endif + logger_ = rhs.logger_; +} + +inline socket_t ClientImpl::create_client_socket(Error &error) const { + if (!proxy_host_.empty() && proxy_port_ != -1) { + return detail::create_client_socket( + proxy_host_, std::string(), proxy_port_, address_family_, tcp_nodelay_, + socket_options_, connection_timeout_sec_, connection_timeout_usec_, + read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, interface_, error); + } + + // Check is custom IP specified for host_ + std::string ip; + auto it = addr_map_.find(host_); + if (it != addr_map_.end()) { ip = it->second; } + + return detail::create_client_socket( + host_, ip, port_, address_family_, tcp_nodelay_, socket_options_, + connection_timeout_sec_, connection_timeout_usec_, read_timeout_sec_, + read_timeout_usec_, write_timeout_sec_, write_timeout_usec_, interface_, + error); +} + +inline bool ClientImpl::create_and_connect_socket(Socket &socket, + Error &error) { + auto sock = create_client_socket(error); + if (sock == INVALID_SOCKET) { return false; } + socket.sock = sock; + return true; +} + +inline void ClientImpl::shutdown_ssl(Socket & /*socket*/, + bool /*shutdown_gracefully*/) { + // If there are any requests in flight from threads other than us, then it's + // a thread-unsafe race because individual ssl* objects are not thread-safe. + assert(socket_requests_in_flight_ == 0 || + socket_requests_are_from_thread_ == std::this_thread::get_id()); +} + +inline void ClientImpl::shutdown_socket(Socket &socket) const { + if (socket.sock == INVALID_SOCKET) { return; } + detail::shutdown_socket(socket.sock); +} + +inline void ClientImpl::close_socket(Socket &socket) { + // If there are requests in flight in another thread, usually closing + // the socket will be fine and they will simply receive an error when + // using the closed socket, but it is still a bug since rarely the OS + // may reassign the socket id to be used for a new socket, and then + // suddenly they will be operating on a live socket that is different + // than the one they intended! + assert(socket_requests_in_flight_ == 0 || + socket_requests_are_from_thread_ == std::this_thread::get_id()); + + // It is also a bug if this happens while SSL is still active +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + assert(socket.ssl == nullptr); +#endif + if (socket.sock == INVALID_SOCKET) { return; } + detail::close_socket(socket.sock); + socket.sock = INVALID_SOCKET; +} + +inline bool ClientImpl::read_response_line(Stream &strm, const Request &req, + Response &res) const { + std::array buf{}; + + detail::stream_line_reader line_reader(strm, buf.data(), buf.size()); + + if (!line_reader.getline()) { return false; } + +#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR + const static std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r?\n"); +#else + const static std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r\n"); +#endif + + std::cmatch m; + if (!std::regex_match(line_reader.ptr(), m, re)) { + return req.method == "CONNECT"; + } + res.version = std::string(m[1]); + res.status = std::stoi(std::string(m[2])); + res.reason = std::string(m[3]); + + // Ignore '100 Continue' + while (res.status == StatusCode::Continue_100) { + if (!line_reader.getline()) { return false; } // CRLF + if (!line_reader.getline()) { return false; } // next response line + + if (!std::regex_match(line_reader.ptr(), m, re)) { return false; } + res.version = std::string(m[1]); + res.status = std::stoi(std::string(m[2])); + res.reason = std::string(m[3]); + } + + return true; +} + +inline bool ClientImpl::send(Request &req, Response &res, Error &error) { + std::lock_guard request_mutex_guard(request_mutex_); + auto ret = send_(req, res, error); + if (error == Error::SSLPeerCouldBeClosed_) { + assert(!ret); + ret = send_(req, res, error); + } + return ret; +} + +inline bool ClientImpl::send_(Request &req, Response &res, Error &error) { + { + std::lock_guard guard(socket_mutex_); + + // Set this to false immediately - if it ever gets set to true by the end of + // the request, we know another thread instructed us to close the socket. + socket_should_be_closed_when_request_is_done_ = false; + + auto is_alive = false; + if (socket_.is_open()) { + is_alive = detail::is_socket_alive(socket_.sock); + if (!is_alive) { + // Attempt to avoid sigpipe by shutting down nongracefully if it seems + // like the other side has already closed the connection Also, there + // cannot be any requests in flight from other threads since we locked + // request_mutex_, so safe to close everything immediately + const bool shutdown_gracefully = false; + shutdown_ssl(socket_, shutdown_gracefully); + shutdown_socket(socket_); + close_socket(socket_); + } + } + + if (!is_alive) { + if (!create_and_connect_socket(socket_, error)) { return false; } + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + // TODO: refactoring + if (is_ssl()) { + auto &scli = static_cast(*this); + if (!proxy_host_.empty() && proxy_port_ != -1) { + auto success = false; + if (!scli.connect_with_proxy(socket_, res, success, error)) { + return success; + } + } + + if (!scli.initialize_ssl(socket_, error)) { return false; } + } +#endif + } + + // Mark the current socket as being in use so that it cannot be closed by + // anyone else while this request is ongoing, even though we will be + // releasing the mutex. + if (socket_requests_in_flight_ > 1) { + assert(socket_requests_are_from_thread_ == std::this_thread::get_id()); + } + socket_requests_in_flight_ += 1; + socket_requests_are_from_thread_ = std::this_thread::get_id(); + } + + for (const auto &header : default_headers_) { + if (req.headers.find(header.first) == req.headers.end()) { + req.headers.insert(header); + } + } + + auto ret = false; + auto close_connection = !keep_alive_; + + auto se = detail::scope_exit([&]() { + // Briefly lock mutex in order to mark that a request is no longer ongoing + std::lock_guard guard(socket_mutex_); + socket_requests_in_flight_ -= 1; + if (socket_requests_in_flight_ <= 0) { + assert(socket_requests_in_flight_ == 0); + socket_requests_are_from_thread_ = std::thread::id(); + } + + if (socket_should_be_closed_when_request_is_done_ || close_connection || + !ret) { + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); + } + }); + + ret = process_socket(socket_, [&](Stream &strm) { + return handle_request(strm, req, res, close_connection, error); + }); + + if (!ret) { + if (error == Error::Success) { error = Error::Unknown; } + } + + return ret; +} + +inline Result ClientImpl::send(const Request &req) { + auto req2 = req; + return send_(std::move(req2)); +} + +inline Result ClientImpl::send_(Request &&req) { + auto res = detail::make_unique(); + auto error = Error::Success; + auto ret = send(req, *res, error); + return Result{ret ? std::move(res) : nullptr, error, std::move(req.headers)}; +} + +inline bool ClientImpl::handle_request(Stream &strm, Request &req, + Response &res, bool close_connection, + Error &error) { + if (req.path.empty()) { + error = Error::Connection; + return false; + } + + auto req_save = req; + + bool ret; + + if (!is_ssl() && !proxy_host_.empty() && proxy_port_ != -1) { + auto req2 = req; + req2.path = "http://" + host_and_port_ + req.path; + ret = process_request(strm, req2, res, close_connection, error); + req = req2; + req.path = req_save.path; + } else { + ret = process_request(strm, req, res, close_connection, error); + } + + if (!ret) { return false; } + + if (res.get_header_value("Connection") == "close" || + (res.version == "HTTP/1.0" && res.reason != "Connection established")) { + // TODO this requires a not-entirely-obvious chain of calls to be correct + // for this to be safe. + + // This is safe to call because handle_request is only called by send_ + // which locks the request mutex during the process. It would be a bug + // to call it from a different thread since it's a thread-safety issue + // to do these things to the socket if another thread is using the socket. + std::lock_guard guard(socket_mutex_); + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); + } + + if (300 < res.status && res.status < 400 && follow_location_) { + req = req_save; + ret = redirect(req, res, error); + } + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + if ((res.status == StatusCode::Unauthorized_401 || + res.status == StatusCode::ProxyAuthenticationRequired_407) && + req.authorization_count_ < 5) { + auto is_proxy = res.status == StatusCode::ProxyAuthenticationRequired_407; + const auto &username = + is_proxy ? proxy_digest_auth_username_ : digest_auth_username_; + const auto &password = + is_proxy ? proxy_digest_auth_password_ : digest_auth_password_; + + if (!username.empty() && !password.empty()) { + std::map auth; + if (detail::parse_www_authenticate(res, auth, is_proxy)) { + Request new_req = req; + new_req.authorization_count_ += 1; + new_req.headers.erase(is_proxy ? "Proxy-Authorization" + : "Authorization"); + new_req.headers.insert(detail::make_digest_authentication_header( + req, auth, new_req.authorization_count_, detail::random_string(10), + username, password, is_proxy)); + + Response new_res; + + ret = send(new_req, new_res, error); + if (ret) { res = new_res; } + } + } + } +#endif + + return ret; +} + +inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) { + if (req.redirect_count_ == 0) { + error = Error::ExceedRedirectCount; + return false; + } + + auto location = res.get_header_value("location"); + if (location.empty()) { return false; } + + const static std::regex re( + R"((?:(https?):)?(?://(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)?([^?#]*)(\?[^#]*)?(?:#.*)?)"); + + std::smatch m; + if (!std::regex_match(location, m, re)) { return false; } + + auto scheme = is_ssl() ? "https" : "http"; + + auto next_scheme = m[1].str(); + auto next_host = m[2].str(); + if (next_host.empty()) { next_host = m[3].str(); } + auto port_str = m[4].str(); + auto next_path = m[5].str(); + auto next_query = m[6].str(); + + auto next_port = port_; + if (!port_str.empty()) { + next_port = std::stoi(port_str); + } else if (!next_scheme.empty()) { + next_port = next_scheme == "https" ? 443 : 80; + } + + if (next_scheme.empty()) { next_scheme = scheme; } + if (next_host.empty()) { next_host = host_; } + if (next_path.empty()) { next_path = "/"; } + + auto path = detail::decode_url(next_path, true) + next_query; + + if (next_scheme == scheme && next_host == host_ && next_port == port_) { + return detail::redirect(*this, req, res, path, location, error); + } else { + if (next_scheme == "https") { +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + SSLClient cli(next_host, next_port); + cli.copy_settings(*this); + if (ca_cert_store_) { cli.set_ca_cert_store(ca_cert_store_); } + return detail::redirect(cli, req, res, path, location, error); +#else + return false; +#endif + } else { + ClientImpl cli(next_host, next_port); + cli.copy_settings(*this); + return detail::redirect(cli, req, res, path, location, error); + } + } +} + +inline bool ClientImpl::write_content_with_provider(Stream &strm, + const Request &req, + Error &error) const { + auto is_shutting_down = []() { return false; }; + + if (req.is_chunked_content_provider_) { + // TODO: Brotli support + std::unique_ptr compressor; +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_) { + compressor = detail::make_unique(); + } else +#endif + { + compressor = detail::make_unique(); + } + + return detail::write_content_chunked(strm, req.content_provider_, + is_shutting_down, *compressor, error); + } else { + return detail::write_content(strm, req.content_provider_, 0, + req.content_length_, is_shutting_down, error); + } +} + +inline bool ClientImpl::write_request(Stream &strm, Request &req, + bool close_connection, Error &error) { + // Prepare additional headers + if (close_connection) { + if (!req.has_header("Connection")) { + req.set_header("Connection", "close"); + } + } + + if (!req.has_header("Host")) { + if (is_ssl()) { + if (port_ == 443) { + req.set_header("Host", host_); + } else { + req.set_header("Host", host_and_port_); + } + } else { + if (port_ == 80) { + req.set_header("Host", host_); + } else { + req.set_header("Host", host_and_port_); + } + } + } + + if (!req.has_header("Accept")) { req.set_header("Accept", "*/*"); } + +#ifndef CPPHTTPLIB_NO_DEFAULT_USER_AGENT + if (!req.has_header("User-Agent")) { + auto agent = std::string("cpp-httplib/") + CPPHTTPLIB_VERSION; + req.set_header("User-Agent", agent); + } +#endif + + if (req.body.empty()) { + if (req.content_provider_) { + if (!req.is_chunked_content_provider_) { + if (!req.has_header("Content-Length")) { + auto length = std::to_string(req.content_length_); + req.set_header("Content-Length", length); + } + } + } else { + if (req.method == "POST" || req.method == "PUT" || + req.method == "PATCH") { + req.set_header("Content-Length", "0"); + } + } + } else { + if (!req.has_header("Content-Type")) { + req.set_header("Content-Type", "text/plain"); + } + + if (!req.has_header("Content-Length")) { + auto length = std::to_string(req.body.size()); + req.set_header("Content-Length", length); + } + } + + if (!basic_auth_password_.empty() || !basic_auth_username_.empty()) { + if (!req.has_header("Authorization")) { + req.headers.insert(make_basic_authentication_header( + basic_auth_username_, basic_auth_password_, false)); + } + } + + if (!proxy_basic_auth_username_.empty() && + !proxy_basic_auth_password_.empty()) { + if (!req.has_header("Proxy-Authorization")) { + req.headers.insert(make_basic_authentication_header( + proxy_basic_auth_username_, proxy_basic_auth_password_, true)); + } + } + + if (!bearer_token_auth_token_.empty()) { + if (!req.has_header("Authorization")) { + req.headers.insert(make_bearer_token_authentication_header( + bearer_token_auth_token_, false)); + } + } + + if (!proxy_bearer_token_auth_token_.empty()) { + if (!req.has_header("Proxy-Authorization")) { + req.headers.insert(make_bearer_token_authentication_header( + proxy_bearer_token_auth_token_, true)); + } + } + + // Request line and headers + { + detail::BufferStream bstrm; + + const auto &path = url_encode_ ? detail::encode_url(req.path) : req.path; + bstrm.write_format("%s %s HTTP/1.1\r\n", req.method.c_str(), path.c_str()); + + header_writer_(bstrm, req.headers); + + // Flush buffer + auto &data = bstrm.get_buffer(); + if (!detail::write_data(strm, data.data(), data.size())) { + error = Error::Write; + return false; + } + } + + // Body + if (req.body.empty()) { + return write_content_with_provider(strm, req, error); + } + + if (!detail::write_data(strm, req.body.data(), req.body.size())) { + error = Error::Write; + return false; + } + + return true; +} + +inline std::unique_ptr ClientImpl::send_with_content_provider( + Request &req, const char *body, size_t content_length, + ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const std::string &content_type, Error &error) { + if (!content_type.empty()) { req.set_header("Content-Type", content_type); } + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_) { req.set_header("Content-Encoding", "gzip"); } +#endif + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_ && !content_provider_without_length) { + // TODO: Brotli support + detail::gzip_compressor compressor; + + if (content_provider) { + auto ok = true; + size_t offset = 0; + DataSink data_sink; + + data_sink.write = [&](const char *data, size_t data_len) -> bool { + if (ok) { + auto last = offset + data_len == content_length; + + auto ret = compressor.compress( + data, data_len, last, + [&](const char *compressed_data, size_t compressed_data_len) { + req.body.append(compressed_data, compressed_data_len); + return true; + }); + + if (ret) { + offset += data_len; + } else { + ok = false; + } + } + return ok; + }; + + while (ok && offset < content_length) { + if (!content_provider(offset, content_length - offset, data_sink)) { + error = Error::Canceled; + return nullptr; + } + } + } else { + if (!compressor.compress(body, content_length, true, + [&](const char *data, size_t data_len) { + req.body.append(data, data_len); + return true; + })) { + error = Error::Compression; + return nullptr; + } + } + } else +#endif + { + if (content_provider) { + req.content_length_ = content_length; + req.content_provider_ = std::move(content_provider); + req.is_chunked_content_provider_ = false; + } else if (content_provider_without_length) { + req.content_length_ = 0; + req.content_provider_ = detail::ContentProviderAdapter( + std::move(content_provider_without_length)); + req.is_chunked_content_provider_ = true; + req.set_header("Transfer-Encoding", "chunked"); + } else { + req.body.assign(body, content_length); + } + } + + auto res = detail::make_unique(); + return send(req, *res, error) ? std::move(res) : nullptr; +} + +inline Result ClientImpl::send_with_content_provider( + const std::string &method, const std::string &path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const std::string &content_type) { + Request req; + req.method = method; + req.headers = headers; + req.path = path; + + auto error = Error::Success; + + auto res = send_with_content_provider( + req, body, content_length, std::move(content_provider), + std::move(content_provider_without_length), content_type, error); + + return Result{std::move(res), error, std::move(req.headers)}; +} + +inline std::string +ClientImpl::adjust_host_string(const std::string &host) const { + if (host.find(':') != std::string::npos) { return "[" + host + "]"; } + return host; +} + +inline bool ClientImpl::process_request(Stream &strm, Request &req, + Response &res, bool close_connection, + Error &error) { + // Send request + if (!write_request(strm, req, close_connection, error)) { return false; } + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + if (is_ssl()) { + auto is_proxy_enabled = !proxy_host_.empty() && proxy_port_ != -1; + if (!is_proxy_enabled) { + char buf[1]; + if (SSL_peek(socket_.ssl, buf, 1) == 0 && + SSL_get_error(socket_.ssl, 0) == SSL_ERROR_ZERO_RETURN) { + error = Error::SSLPeerCouldBeClosed_; + return false; + } + } + } +#endif + + // Receive response and headers + if (!read_response_line(strm, req, res) || + !detail::read_headers(strm, res.headers)) { + error = Error::Read; + return false; + } + + // Body + if ((res.status != StatusCode::NoContent_204) && req.method != "HEAD" && + req.method != "CONNECT") { + auto redirect = 300 < res.status && res.status < 400 && follow_location_; + + if (req.response_handler && !redirect) { + if (!req.response_handler(res)) { + error = Error::Canceled; + return false; + } + } + + auto out = + req.content_receiver + ? static_cast( + [&](const char *buf, size_t n, uint64_t off, uint64_t len) { + if (redirect) { return true; } + auto ret = req.content_receiver(buf, n, off, len); + if (!ret) { error = Error::Canceled; } + return ret; + }) + : static_cast( + [&](const char *buf, size_t n, uint64_t /*off*/, + uint64_t /*len*/) { + if (res.body.size() + n > res.body.max_size()) { + return false; + } + res.body.append(buf, n); + return true; + }); + + auto progress = [&](uint64_t current, uint64_t total) { + if (!req.progress || redirect) { return true; } + auto ret = req.progress(current, total); + if (!ret) { error = Error::Canceled; } + return ret; + }; + + int dummy_status; + if (!detail::read_content(strm, res, (std::numeric_limits::max)(), + dummy_status, std::move(progress), std::move(out), + decompress_)) { + if (error != Error::Canceled) { error = Error::Read; } + return false; + } + } + + // Log + if (logger_) { logger_(req, res); } + + return true; +} + +inline ContentProviderWithoutLength ClientImpl::get_multipart_content_provider( + const std::string &boundary, const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items) const { + size_t cur_item = 0; + size_t cur_start = 0; + // cur_item and cur_start are copied to within the std::function and maintain + // state between successive calls + return [&, cur_item, cur_start](size_t offset, + DataSink &sink) mutable -> bool { + if (!offset && !items.empty()) { + sink.os << detail::serialize_multipart_formdata(items, boundary, false); + return true; + } else if (cur_item < provider_items.size()) { + if (!cur_start) { + const auto &begin = detail::serialize_multipart_formdata_item_begin( + provider_items[cur_item], boundary); + offset += begin.size(); + cur_start = offset; + sink.os << begin; + } + + DataSink cur_sink; + auto has_data = true; + cur_sink.write = sink.write; + cur_sink.done = [&]() { has_data = false; }; + + if (!provider_items[cur_item].provider(offset - cur_start, cur_sink)) { + return false; + } + + if (!has_data) { + sink.os << detail::serialize_multipart_formdata_item_end(); + cur_item++; + cur_start = 0; + } + return true; + } else { + sink.os << detail::serialize_multipart_formdata_finish(boundary); + sink.done(); + return true; + } + }; +} + +inline bool +ClientImpl::process_socket(const Socket &socket, + std::function callback) { + return detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, std::move(callback)); +} + +inline bool ClientImpl::is_ssl() const { return false; } + +inline Result ClientImpl::Get(const std::string &path) { + return Get(path, Headers(), Progress()); +} + +inline Result ClientImpl::Get(const std::string &path, Progress progress) { + return Get(path, Headers(), std::move(progress)); +} + +inline Result ClientImpl::Get(const std::string &path, const Headers &headers) { + return Get(path, headers, Progress()); +} + +inline Result ClientImpl::Get(const std::string &path, const Headers &headers, + Progress progress) { + Request req; + req.method = "GET"; + req.path = path; + req.headers = headers; + req.progress = std::move(progress); + + return send_(std::move(req)); +} + +inline Result ClientImpl::Get(const std::string &path, + ContentReceiver content_receiver) { + return Get(path, Headers(), nullptr, std::move(content_receiver), nullptr); +} + +inline Result ClientImpl::Get(const std::string &path, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, Headers(), nullptr, std::move(content_receiver), + std::move(progress)); +} + +inline Result ClientImpl::Get(const std::string &path, const Headers &headers, + ContentReceiver content_receiver) { + return Get(path, headers, nullptr, std::move(content_receiver), nullptr); +} + +inline Result ClientImpl::Get(const std::string &path, const Headers &headers, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, headers, nullptr, std::move(content_receiver), + std::move(progress)); +} + +inline Result ClientImpl::Get(const std::string &path, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return Get(path, Headers(), std::move(response_handler), + std::move(content_receiver), nullptr); +} + +inline Result ClientImpl::Get(const std::string &path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return Get(path, headers, std::move(response_handler), + std::move(content_receiver), nullptr); +} + +inline Result ClientImpl::Get(const std::string &path, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, Headers(), std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} + +inline Result ClientImpl::Get(const std::string &path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + Request req; + req.method = "GET"; + req.path = path; + req.headers = headers; + req.response_handler = std::move(response_handler); + req.content_receiver = + [content_receiver](const char *data, size_t data_length, + uint64_t /*offset*/, uint64_t /*total_length*/) { + return content_receiver(data, data_length); + }; + req.progress = std::move(progress); + + return send_(std::move(req)); +} + +inline Result ClientImpl::Get(const std::string &path, const Params ¶ms, + const Headers &headers, Progress progress) { + if (params.empty()) { return Get(path, headers); } + + std::string path_with_query = append_query_params(path, params); + return Get(path_with_query, headers, std::move(progress)); +} + +inline Result ClientImpl::Get(const std::string &path, const Params ¶ms, + const Headers &headers, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, params, headers, nullptr, std::move(content_receiver), + std::move(progress)); +} + +inline Result ClientImpl::Get(const std::string &path, const Params ¶ms, + const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + if (params.empty()) { + return Get(path, headers, std::move(response_handler), + std::move(content_receiver), std::move(progress)); + } + + std::string path_with_query = append_query_params(path, params); + return Get(path_with_query, headers, std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} + +inline Result ClientImpl::Head(const std::string &path) { + return Head(path, Headers()); +} + +inline Result ClientImpl::Head(const std::string &path, + const Headers &headers) { + Request req; + req.method = "HEAD"; + req.headers = headers; + req.path = path; + + return send_(std::move(req)); +} + +inline Result ClientImpl::Post(const std::string &path) { + return Post(path, std::string(), std::string()); +} + +inline Result ClientImpl::Post(const std::string &path, + const Headers &headers) { + return Post(path, headers, nullptr, 0, std::string()); +} + +inline Result ClientImpl::Post(const std::string &path, const char *body, + size_t content_length, + const std::string &content_type) { + return Post(path, Headers(), body, content_length, content_type); +} + +inline Result ClientImpl::Post(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type) { + return send_with_content_provider("POST", path, headers, body, content_length, + nullptr, nullptr, content_type); +} + +inline Result ClientImpl::Post(const std::string &path, const std::string &body, + const std::string &content_type) { + return Post(path, Headers(), body, content_type); +} + +inline Result ClientImpl::Post(const std::string &path, const Headers &headers, + const std::string &body, + const std::string &content_type) { + return send_with_content_provider("POST", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); +} + +inline Result ClientImpl::Post(const std::string &path, const Params ¶ms) { + return Post(path, Headers(), params); +} + +inline Result ClientImpl::Post(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return Post(path, Headers(), content_length, std::move(content_provider), + content_type); +} + +inline Result ClientImpl::Post(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return Post(path, Headers(), std::move(content_provider), content_type); +} + +inline Result ClientImpl::Post(const std::string &path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return send_with_content_provider("POST", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); +} + +inline Result ClientImpl::Post(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return send_with_content_provider("POST", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); +} + +inline Result ClientImpl::Post(const std::string &path, const Headers &headers, + const Params ¶ms) { + auto query = detail::params_to_query_str(params); + return Post(path, headers, query, "application/x-www-form-urlencoded"); +} + +inline Result ClientImpl::Post(const std::string &path, + const MultipartFormDataItems &items) { + return Post(path, Headers(), items); +} + +inline Result ClientImpl::Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items) { + const auto &boundary = detail::make_multipart_data_boundary(); + const auto &content_type = + detail::serialize_multipart_formdata_get_content_type(boundary); + const auto &body = detail::serialize_multipart_formdata(items, boundary); + return Post(path, headers, body, content_type); +} + +inline Result ClientImpl::Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const std::string &boundary) { + if (!detail::is_multipart_boundary_chars_valid(boundary)) { + return Result{nullptr, Error::UnsupportedMultipartBoundaryChars}; + } + + const auto &content_type = + detail::serialize_multipart_formdata_get_content_type(boundary); + const auto &body = detail::serialize_multipart_formdata(items, boundary); + return Post(path, headers, body, content_type); +} + +inline Result +ClientImpl::Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items) { + const auto &boundary = detail::make_multipart_data_boundary(); + const auto &content_type = + detail::serialize_multipart_formdata_get_content_type(boundary); + return send_with_content_provider( + "POST", path, headers, nullptr, 0, nullptr, + get_multipart_content_provider(boundary, items, provider_items), + content_type); +} + +inline Result ClientImpl::Put(const std::string &path) { + return Put(path, std::string(), std::string()); +} + +inline Result ClientImpl::Put(const std::string &path, const char *body, + size_t content_length, + const std::string &content_type) { + return Put(path, Headers(), body, content_length, content_type); +} + +inline Result ClientImpl::Put(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type) { + return send_with_content_provider("PUT", path, headers, body, content_length, + nullptr, nullptr, content_type); +} + +inline Result ClientImpl::Put(const std::string &path, const std::string &body, + const std::string &content_type) { + return Put(path, Headers(), body, content_type); +} + +inline Result ClientImpl::Put(const std::string &path, const Headers &headers, + const std::string &body, + const std::string &content_type) { + return send_with_content_provider("PUT", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); +} + +inline Result ClientImpl::Put(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return Put(path, Headers(), content_length, std::move(content_provider), + content_type); +} + +inline Result ClientImpl::Put(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return Put(path, Headers(), std::move(content_provider), content_type); +} + +inline Result ClientImpl::Put(const std::string &path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return send_with_content_provider("PUT", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); +} + +inline Result ClientImpl::Put(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return send_with_content_provider("PUT", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); +} + +inline Result ClientImpl::Put(const std::string &path, const Params ¶ms) { + return Put(path, Headers(), params); +} + +inline Result ClientImpl::Put(const std::string &path, const Headers &headers, + const Params ¶ms) { + auto query = detail::params_to_query_str(params); + return Put(path, headers, query, "application/x-www-form-urlencoded"); +} + +inline Result ClientImpl::Put(const std::string &path, + const MultipartFormDataItems &items) { + return Put(path, Headers(), items); +} + +inline Result ClientImpl::Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items) { + const auto &boundary = detail::make_multipart_data_boundary(); + const auto &content_type = + detail::serialize_multipart_formdata_get_content_type(boundary); + const auto &body = detail::serialize_multipart_formdata(items, boundary); + return Put(path, headers, body, content_type); +} + +inline Result ClientImpl::Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const std::string &boundary) { + if (!detail::is_multipart_boundary_chars_valid(boundary)) { + return Result{nullptr, Error::UnsupportedMultipartBoundaryChars}; + } + + const auto &content_type = + detail::serialize_multipart_formdata_get_content_type(boundary); + const auto &body = detail::serialize_multipart_formdata(items, boundary); + return Put(path, headers, body, content_type); +} + +inline Result +ClientImpl::Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items) { + const auto &boundary = detail::make_multipart_data_boundary(); + const auto &content_type = + detail::serialize_multipart_formdata_get_content_type(boundary); + return send_with_content_provider( + "PUT", path, headers, nullptr, 0, nullptr, + get_multipart_content_provider(boundary, items, provider_items), + content_type); +} +inline Result ClientImpl::Patch(const std::string &path) { + return Patch(path, std::string(), std::string()); +} + +inline Result ClientImpl::Patch(const std::string &path, const char *body, + size_t content_length, + const std::string &content_type) { + return Patch(path, Headers(), body, content_length, content_type); +} + +inline Result ClientImpl::Patch(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type) { + return send_with_content_provider("PATCH", path, headers, body, + content_length, nullptr, nullptr, + content_type); +} + +inline Result ClientImpl::Patch(const std::string &path, + const std::string &body, + const std::string &content_type) { + return Patch(path, Headers(), body, content_type); +} + +inline Result ClientImpl::Patch(const std::string &path, const Headers &headers, + const std::string &body, + const std::string &content_type) { + return send_with_content_provider("PATCH", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); +} + +inline Result ClientImpl::Patch(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return Patch(path, Headers(), content_length, std::move(content_provider), + content_type); +} + +inline Result ClientImpl::Patch(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return Patch(path, Headers(), std::move(content_provider), content_type); +} + +inline Result ClientImpl::Patch(const std::string &path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return send_with_content_provider("PATCH", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); +} + +inline Result ClientImpl::Patch(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return send_with_content_provider("PATCH", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); +} + +inline Result ClientImpl::Delete(const std::string &path) { + return Delete(path, Headers(), std::string(), std::string()); +} + +inline Result ClientImpl::Delete(const std::string &path, + const Headers &headers) { + return Delete(path, headers, std::string(), std::string()); +} + +inline Result ClientImpl::Delete(const std::string &path, const char *body, + size_t content_length, + const std::string &content_type) { + return Delete(path, Headers(), body, content_length, content_type); +} + +inline Result ClientImpl::Delete(const std::string &path, + const Headers &headers, const char *body, + size_t content_length, + const std::string &content_type) { + Request req; + req.method = "DELETE"; + req.headers = headers; + req.path = path; + + if (!content_type.empty()) { req.set_header("Content-Type", content_type); } + req.body.assign(body, content_length); + + return send_(std::move(req)); +} + +inline Result ClientImpl::Delete(const std::string &path, + const std::string &body, + const std::string &content_type) { + return Delete(path, Headers(), body.data(), body.size(), content_type); +} + +inline Result ClientImpl::Delete(const std::string &path, + const Headers &headers, + const std::string &body, + const std::string &content_type) { + return Delete(path, headers, body.data(), body.size(), content_type); +} + +inline Result ClientImpl::Options(const std::string &path) { + return Options(path, Headers()); +} + +inline Result ClientImpl::Options(const std::string &path, + const Headers &headers) { + Request req; + req.method = "OPTIONS"; + req.headers = headers; + req.path = path; + + return send_(std::move(req)); +} + +inline void ClientImpl::stop() { + std::lock_guard guard(socket_mutex_); + + // If there is anything ongoing right now, the ONLY thread-safe thing we can + // do is to shutdown_socket, so that threads using this socket suddenly + // discover they can't read/write any more and error out. Everything else + // (closing the socket, shutting ssl down) is unsafe because these actions are + // not thread-safe. + if (socket_requests_in_flight_ > 0) { + shutdown_socket(socket_); + + // Aside from that, we set a flag for the socket to be closed when we're + // done. + socket_should_be_closed_when_request_is_done_ = true; + return; + } + + // Otherwise, still holding the mutex, we can shut everything down ourselves + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); +} + +inline std::string ClientImpl::host() const { return host_; } + +inline int ClientImpl::port() const { return port_; } + +inline size_t ClientImpl::is_socket_open() const { + std::lock_guard guard(socket_mutex_); + return socket_.is_open(); +} + +inline socket_t ClientImpl::socket() const { return socket_.sock; } + +inline void ClientImpl::set_connection_timeout(time_t sec, time_t usec) { + connection_timeout_sec_ = sec; + connection_timeout_usec_ = usec; +} + +inline void ClientImpl::set_read_timeout(time_t sec, time_t usec) { + read_timeout_sec_ = sec; + read_timeout_usec_ = usec; +} + +inline void ClientImpl::set_write_timeout(time_t sec, time_t usec) { + write_timeout_sec_ = sec; + write_timeout_usec_ = usec; +} + +inline void ClientImpl::set_basic_auth(const std::string &username, + const std::string &password) { + basic_auth_username_ = username; + basic_auth_password_ = password; +} + +inline void ClientImpl::set_bearer_token_auth(const std::string &token) { + bearer_token_auth_token_ = token; +} + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::set_digest_auth(const std::string &username, + const std::string &password) { + digest_auth_username_ = username; + digest_auth_password_ = password; +} +#endif + +inline void ClientImpl::set_keep_alive(bool on) { keep_alive_ = on; } + +inline void ClientImpl::set_follow_location(bool on) { follow_location_ = on; } + +inline void ClientImpl::set_url_encode(bool on) { url_encode_ = on; } + +inline void +ClientImpl::set_hostname_addr_map(std::map addr_map) { + addr_map_ = std::move(addr_map); +} + +inline void ClientImpl::set_default_headers(Headers headers) { + default_headers_ = std::move(headers); +} + +inline void ClientImpl::set_header_writer( + std::function const &writer) { + header_writer_ = writer; +} + +inline void ClientImpl::set_address_family(int family) { + address_family_ = family; +} + +inline void ClientImpl::set_tcp_nodelay(bool on) { tcp_nodelay_ = on; } + +inline void ClientImpl::set_socket_options(SocketOptions socket_options) { + socket_options_ = std::move(socket_options); +} + +inline void ClientImpl::set_compress(bool on) { compress_ = on; } + +inline void ClientImpl::set_decompress(bool on) { decompress_ = on; } + +inline void ClientImpl::set_interface(const std::string &intf) { + interface_ = intf; +} + +inline void ClientImpl::set_proxy(const std::string &host, int port) { + proxy_host_ = host; + proxy_port_ = port; +} + +inline void ClientImpl::set_proxy_basic_auth(const std::string &username, + const std::string &password) { + proxy_basic_auth_username_ = username; + proxy_basic_auth_password_ = password; +} + +inline void ClientImpl::set_proxy_bearer_token_auth(const std::string &token) { + proxy_bearer_token_auth_token_ = token; +} + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::set_proxy_digest_auth(const std::string &username, + const std::string &password) { + proxy_digest_auth_username_ = username; + proxy_digest_auth_password_ = password; +} + +inline void ClientImpl::set_ca_cert_path(const std::string &ca_cert_file_path, + const std::string &ca_cert_dir_path) { + ca_cert_file_path_ = ca_cert_file_path; + ca_cert_dir_path_ = ca_cert_dir_path; +} + +inline void ClientImpl::set_ca_cert_store(X509_STORE *ca_cert_store) { + if (ca_cert_store && ca_cert_store != ca_cert_store_) { + ca_cert_store_ = ca_cert_store; + } +} + +inline X509_STORE *ClientImpl::create_ca_cert_store(const char *ca_cert, + std::size_t size) const { + auto mem = BIO_new_mem_buf(ca_cert, static_cast(size)); + if (!mem) { return nullptr; } + + auto inf = PEM_X509_INFO_read_bio(mem, nullptr, nullptr, nullptr); + if (!inf) { + BIO_free_all(mem); + return nullptr; + } + + auto cts = X509_STORE_new(); + if (cts) { + for (auto i = 0; i < static_cast(sk_X509_INFO_num(inf)); i++) { + auto itmp = sk_X509_INFO_value(inf, i); + if (!itmp) { continue; } + + if (itmp->x509) { X509_STORE_add_cert(cts, itmp->x509); } + if (itmp->crl) { X509_STORE_add_crl(cts, itmp->crl); } + } + } + + sk_X509_INFO_pop_free(inf, X509_INFO_free); + BIO_free_all(mem); + return cts; +} + +inline void ClientImpl::enable_server_certificate_verification(bool enabled) { + server_certificate_verification_ = enabled; +} +#endif + +inline void ClientImpl::set_logger(Logger logger) { + logger_ = std::move(logger); +} + +/* + * SSL Implementation + */ +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +namespace detail { + +template +inline SSL *ssl_new(socket_t sock, SSL_CTX *ctx, std::mutex &ctx_mutex, + U SSL_connect_or_accept, V setup) { + SSL *ssl = nullptr; + { + std::lock_guard guard(ctx_mutex); + ssl = SSL_new(ctx); + } + + if (ssl) { + set_nonblocking(sock, true); + auto bio = BIO_new_socket(static_cast(sock), BIO_NOCLOSE); + BIO_set_nbio(bio, 1); + SSL_set_bio(ssl, bio, bio); + + if (!setup(ssl) || SSL_connect_or_accept(ssl) != 1) { + SSL_shutdown(ssl); + { + std::lock_guard guard(ctx_mutex); + SSL_free(ssl); + } + set_nonblocking(sock, false); + return nullptr; + } + BIO_set_nbio(bio, 0); + set_nonblocking(sock, false); + } + + return ssl; +} + +inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl, + bool shutdown_gracefully) { + // sometimes we may want to skip this to try to avoid SIGPIPE if we know + // the remote has closed the network connection + // Note that it is not always possible to avoid SIGPIPE, this is merely a + // best-efforts. + if (shutdown_gracefully) { SSL_shutdown(ssl); } + + std::lock_guard guard(ctx_mutex); + SSL_free(ssl); +} + +template +bool ssl_connect_or_accept_nonblocking(socket_t sock, SSL *ssl, + U ssl_connect_or_accept, + time_t timeout_sec, + time_t timeout_usec) { + auto res = 0; + while ((res = ssl_connect_or_accept(ssl)) != 1) { + auto err = SSL_get_error(ssl, res); + switch (err) { + case SSL_ERROR_WANT_READ: + if (select_read(sock, timeout_sec, timeout_usec) > 0) { continue; } + break; + case SSL_ERROR_WANT_WRITE: + if (select_write(sock, timeout_sec, timeout_usec) > 0) { continue; } + break; + default: break; + } + return false; + } + return true; +} + +template +inline bool process_server_socket_ssl( + const std::atomic &svr_sock, SSL *ssl, socket_t sock, + size_t keep_alive_max_count, time_t keep_alive_timeout_sec, + time_t read_timeout_sec, time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, T callback) { + return process_server_socket_core( + svr_sock, sock, keep_alive_max_count, keep_alive_timeout_sec, + [&](bool close_connection, bool &connection_closed) { + SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm, close_connection, connection_closed); + }); +} + +template +inline bool +process_client_socket_ssl(SSL *ssl, socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, T callback) { + SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm); +} + +class SSLInit { +public: + SSLInit() { + OPENSSL_init_ssl( + OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); + } +}; + +// SSL socket stream implementation +inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl, + time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec) + : sock_(sock), ssl_(ssl), read_timeout_sec_(read_timeout_sec), + read_timeout_usec_(read_timeout_usec), + write_timeout_sec_(write_timeout_sec), + write_timeout_usec_(write_timeout_usec) { + SSL_clear_mode(ssl, SSL_MODE_AUTO_RETRY); +} + +inline SSLSocketStream::~SSLSocketStream() = default; + +inline bool SSLSocketStream::is_readable() const { + return detail::select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0; +} + +inline bool SSLSocketStream::is_writable() const { + return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0 && + is_socket_alive(sock_); +} + +inline ssize_t SSLSocketStream::read(char *ptr, size_t size) { + if (SSL_pending(ssl_) > 0) { + return SSL_read(ssl_, ptr, static_cast(size)); + } else if (is_readable()) { + auto ret = SSL_read(ssl_, ptr, static_cast(size)); + if (ret < 0) { + auto err = SSL_get_error(ssl_, ret); + auto n = 1000; +#ifdef _WIN32 + while (--n >= 0 && (err == SSL_ERROR_WANT_READ || + (err == SSL_ERROR_SYSCALL && + WSAGetLastError() == WSAETIMEDOUT))) { +#else + while (--n >= 0 && err == SSL_ERROR_WANT_READ) { +#endif + if (SSL_pending(ssl_) > 0) { + return SSL_read(ssl_, ptr, static_cast(size)); + } else if (is_readable()) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + ret = SSL_read(ssl_, ptr, static_cast(size)); + if (ret >= 0) { return ret; } + err = SSL_get_error(ssl_, ret); + } else { + return -1; + } + } + } + return ret; + } + return -1; +} + +inline ssize_t SSLSocketStream::write(const char *ptr, size_t size) { + if (is_writable()) { + auto handle_size = static_cast( + std::min(size, (std::numeric_limits::max)())); + + auto ret = SSL_write(ssl_, ptr, static_cast(handle_size)); + if (ret < 0) { + auto err = SSL_get_error(ssl_, ret); + auto n = 1000; +#ifdef _WIN32 + while (--n >= 0 && (err == SSL_ERROR_WANT_WRITE || + (err == SSL_ERROR_SYSCALL && + WSAGetLastError() == WSAETIMEDOUT))) { +#else + while (--n >= 0 && err == SSL_ERROR_WANT_WRITE) { +#endif + if (is_writable()) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + ret = SSL_write(ssl_, ptr, static_cast(handle_size)); + if (ret >= 0) { return ret; } + err = SSL_get_error(ssl_, ret); + } else { + return -1; + } + } + } + return ret; + } + return -1; +} + +inline void SSLSocketStream::get_remote_ip_and_port(std::string &ip, + int &port) const { + detail::get_remote_ip_and_port(sock_, ip, port); +} + +inline void SSLSocketStream::get_local_ip_and_port(std::string &ip, + int &port) const { + detail::get_local_ip_and_port(sock_, ip, port); +} + +inline socket_t SSLSocketStream::socket() const { return sock_; } + +static SSLInit sslinit_; + +} // namespace detail + +// SSL HTTP server implementation +inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path, + const char *client_ca_cert_file_path, + const char *client_ca_cert_dir_path, + const char *private_key_password) { + ctx_ = SSL_CTX_new(TLS_server_method()); + + if (ctx_) { + SSL_CTX_set_options(ctx_, + SSL_OP_NO_COMPRESSION | + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); + + SSL_CTX_set_min_proto_version(ctx_, TLS1_1_VERSION); + + // add default password callback before opening encrypted private key + if (private_key_password != nullptr && (private_key_password[0] != '\0')) { + SSL_CTX_set_default_passwd_cb_userdata( + ctx_, + reinterpret_cast(const_cast(private_key_password))); + } + + if (SSL_CTX_use_certificate_chain_file(ctx_, cert_path) != 1 || + SSL_CTX_use_PrivateKey_file(ctx_, private_key_path, SSL_FILETYPE_PEM) != + 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } else if (client_ca_cert_file_path || client_ca_cert_dir_path) { + SSL_CTX_load_verify_locations(ctx_, client_ca_cert_file_path, + client_ca_cert_dir_path); + + SSL_CTX_set_verify( + ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); + } + } +} + +inline SSLServer::SSLServer(X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store) { + ctx_ = SSL_CTX_new(TLS_server_method()); + + if (ctx_) { + SSL_CTX_set_options(ctx_, + SSL_OP_NO_COMPRESSION | + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); + + SSL_CTX_set_min_proto_version(ctx_, TLS1_1_VERSION); + + if (SSL_CTX_use_certificate(ctx_, cert) != 1 || + SSL_CTX_use_PrivateKey(ctx_, private_key) != 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } else if (client_ca_cert_store) { + SSL_CTX_set_cert_store(ctx_, client_ca_cert_store); + + SSL_CTX_set_verify( + ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); + } + } +} + +inline SSLServer::SSLServer( + const std::function &setup_ssl_ctx_callback) { + ctx_ = SSL_CTX_new(TLS_method()); + if (ctx_) { + if (!setup_ssl_ctx_callback(*ctx_)) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } + } +} + +inline SSLServer::~SSLServer() { + if (ctx_) { SSL_CTX_free(ctx_); } +} + +inline bool SSLServer::is_valid() const { return ctx_; } + +inline SSL_CTX *SSLServer::ssl_context() const { return ctx_; } + +inline bool SSLServer::process_and_close_socket(socket_t sock) { + auto ssl = detail::ssl_new( + sock, ctx_, ctx_mutex_, + [&](SSL *ssl2) { + return detail::ssl_connect_or_accept_nonblocking( + sock, ssl2, SSL_accept, read_timeout_sec_, read_timeout_usec_); + }, + [](SSL * /*ssl2*/) { return true; }); + + auto ret = false; + if (ssl) { + ret = detail::process_server_socket_ssl( + svr_sock_, ssl, sock, keep_alive_max_count_, keep_alive_timeout_sec_, + read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, + [this, ssl](Stream &strm, bool close_connection, + bool &connection_closed) { + return process_request(strm, close_connection, connection_closed, + [&](Request &req) { req.ssl = ssl; }); + }); + + // Shutdown gracefully if the result seemed successful, non-gracefully if + // the connection appeared to be closed. + const bool shutdown_gracefully = ret; + detail::ssl_delete(ctx_mutex_, ssl, shutdown_gracefully); + } + + detail::shutdown_socket(sock); + detail::close_socket(sock); + return ret; +} + +// SSL HTTP client implementation +inline SSLClient::SSLClient(const std::string &host) + : SSLClient(host, 443, std::string(), std::string()) {} + +inline SSLClient::SSLClient(const std::string &host, int port) + : SSLClient(host, port, std::string(), std::string()) {} + +inline SSLClient::SSLClient(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + : ClientImpl(host, port, client_cert_path, client_key_path) { + ctx_ = SSL_CTX_new(TLS_client_method()); + + detail::split(&host_[0], &host_[host_.size()], '.', + [&](const char *b, const char *e) { + host_components_.emplace_back(b, e); + }); + + if (!client_cert_path.empty() && !client_key_path.empty()) { + if (SSL_CTX_use_certificate_file(ctx_, client_cert_path.c_str(), + SSL_FILETYPE_PEM) != 1 || + SSL_CTX_use_PrivateKey_file(ctx_, client_key_path.c_str(), + SSL_FILETYPE_PEM) != 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } + } +} + +inline SSLClient::SSLClient(const std::string &host, int port, + X509 *client_cert, EVP_PKEY *client_key) + : ClientImpl(host, port) { + ctx_ = SSL_CTX_new(TLS_client_method()); + + detail::split(&host_[0], &host_[host_.size()], '.', + [&](const char *b, const char *e) { + host_components_.emplace_back(b, e); + }); + + if (client_cert != nullptr && client_key != nullptr) { + if (SSL_CTX_use_certificate(ctx_, client_cert) != 1 || + SSL_CTX_use_PrivateKey(ctx_, client_key) != 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } + } +} + +inline SSLClient::~SSLClient() { + if (ctx_) { SSL_CTX_free(ctx_); } + // Make sure to shut down SSL since shutdown_ssl will resolve to the + // base function rather than the derived function once we get to the + // base class destructor, and won't free the SSL (causing a leak). + shutdown_ssl_impl(socket_, true); +} + +inline bool SSLClient::is_valid() const { return ctx_; } + +inline void SSLClient::set_ca_cert_store(X509_STORE *ca_cert_store) { + if (ca_cert_store) { + if (ctx_) { + if (SSL_CTX_get_cert_store(ctx_) != ca_cert_store) { + // Free memory allocated for old cert and use new store `ca_cert_store` + SSL_CTX_set_cert_store(ctx_, ca_cert_store); + } + } else { + X509_STORE_free(ca_cert_store); + } + } +} + +inline void SSLClient::load_ca_cert_store(const char *ca_cert, + std::size_t size) { + set_ca_cert_store(ClientImpl::create_ca_cert_store(ca_cert, size)); +} + +inline long SSLClient::get_openssl_verify_result() const { + return verify_result_; +} + +inline SSL_CTX *SSLClient::ssl_context() const { return ctx_; } + +inline bool SSLClient::create_and_connect_socket(Socket &socket, Error &error) { + return is_valid() && ClientImpl::create_and_connect_socket(socket, error); +} + +// Assumes that socket_mutex_ is locked and that there are no requests in flight +inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res, + bool &success, Error &error) { + success = true; + Response proxy_res; + if (!detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, [&](Stream &strm) { + Request req2; + req2.method = "CONNECT"; + req2.path = host_and_port_; + return process_request(strm, req2, proxy_res, false, error); + })) { + // Thread-safe to close everything because we are assuming there are no + // requests in flight + shutdown_ssl(socket, true); + shutdown_socket(socket); + close_socket(socket); + success = false; + return false; + } + + if (proxy_res.status == StatusCode::ProxyAuthenticationRequired_407) { + if (!proxy_digest_auth_username_.empty() && + !proxy_digest_auth_password_.empty()) { + std::map auth; + if (detail::parse_www_authenticate(proxy_res, auth, true)) { + proxy_res = Response(); + if (!detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, [&](Stream &strm) { + Request req3; + req3.method = "CONNECT"; + req3.path = host_and_port_; + req3.headers.insert(detail::make_digest_authentication_header( + req3, auth, 1, detail::random_string(10), + proxy_digest_auth_username_, proxy_digest_auth_password_, + true)); + return process_request(strm, req3, proxy_res, false, error); + })) { + // Thread-safe to close everything because we are assuming there are + // no requests in flight + shutdown_ssl(socket, true); + shutdown_socket(socket); + close_socket(socket); + success = false; + return false; + } + } + } + } + + // If status code is not 200, proxy request is failed. + // Set error to ProxyConnection and return proxy response + // as the response of the request + if (proxy_res.status != StatusCode::OK_200) { + error = Error::ProxyConnection; + res = std::move(proxy_res); + // Thread-safe to close everything because we are assuming there are + // no requests in flight + shutdown_ssl(socket, true); + shutdown_socket(socket); + close_socket(socket); + return false; + } + + return true; +} + +inline bool SSLClient::load_certs() { + auto ret = true; + + std::call_once(initialize_cert_, [&]() { + std::lock_guard guard(ctx_mutex_); + if (!ca_cert_file_path_.empty()) { + if (!SSL_CTX_load_verify_locations(ctx_, ca_cert_file_path_.c_str(), + nullptr)) { + ret = false; + } + } else if (!ca_cert_dir_path_.empty()) { + if (!SSL_CTX_load_verify_locations(ctx_, nullptr, + ca_cert_dir_path_.c_str())) { + ret = false; + } + } else { + auto loaded = false; +#ifdef _WIN32 + loaded = + detail::load_system_certs_on_windows(SSL_CTX_get_cert_store(ctx_)); +#elif defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN) && defined(__APPLE__) +#if TARGET_OS_OSX + loaded = detail::load_system_certs_on_macos(SSL_CTX_get_cert_store(ctx_)); +#endif // TARGET_OS_OSX +#endif // _WIN32 + if (!loaded) { SSL_CTX_set_default_verify_paths(ctx_); } + } + }); + + return ret; +} + +inline bool SSLClient::initialize_ssl(Socket &socket, Error &error) { + auto ssl = detail::ssl_new( + socket.sock, ctx_, ctx_mutex_, + [&](SSL *ssl2) { + if (server_certificate_verification_) { + if (!load_certs()) { + error = Error::SSLLoadingCerts; + return false; + } + SSL_set_verify(ssl2, SSL_VERIFY_NONE, nullptr); + } + + if (!detail::ssl_connect_or_accept_nonblocking( + socket.sock, ssl2, SSL_connect, connection_timeout_sec_, + connection_timeout_usec_)) { + error = Error::SSLConnection; + return false; + } + + if (server_certificate_verification_) { + verify_result_ = SSL_get_verify_result(ssl2); + + if (verify_result_ != X509_V_OK) { + error = Error::SSLServerVerification; + return false; + } + + auto server_cert = SSL_get1_peer_certificate(ssl2); + + if (server_cert == nullptr) { + error = Error::SSLServerVerification; + return false; + } + + if (!verify_host(server_cert)) { + X509_free(server_cert); + error = Error::SSLServerVerification; + return false; + } + X509_free(server_cert); + } + + return true; + }, + [&](SSL *ssl2) { + // NOTE: Direct call instead of using the OpenSSL macro to suppress + // -Wold-style-cast warning + // SSL_set_tlsext_host_name(ssl2, host_.c_str()); + SSL_ctrl(ssl2, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, + static_cast(const_cast(host_.c_str()))); + return true; + }); + + if (ssl) { + socket.ssl = ssl; + return true; + } + + shutdown_socket(socket); + close_socket(socket); + return false; +} + +inline void SSLClient::shutdown_ssl(Socket &socket, bool shutdown_gracefully) { + shutdown_ssl_impl(socket, shutdown_gracefully); +} + +inline void SSLClient::shutdown_ssl_impl(Socket &socket, + bool shutdown_gracefully) { + if (socket.sock == INVALID_SOCKET) { + assert(socket.ssl == nullptr); + return; + } + if (socket.ssl) { + detail::ssl_delete(ctx_mutex_, socket.ssl, shutdown_gracefully); + socket.ssl = nullptr; + } + assert(socket.ssl == nullptr); +} + +inline bool +SSLClient::process_socket(const Socket &socket, + std::function callback) { + assert(socket.ssl); + return detail::process_client_socket_ssl( + socket.ssl, socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, std::move(callback)); +} + +inline bool SSLClient::is_ssl() const { return true; } + +inline bool SSLClient::verify_host(X509 *server_cert) const { + /* Quote from RFC2818 section 3.1 "Server Identity" + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. + + Matching is performed using the matching rules specified by + [RFC2459]. If more than one identity of a given type is present in + the certificate (e.g., more than one dNSName name, a match in any one + of the set is considered acceptable.) Names may contain the wildcard + character * which is considered to match any single domain name + component or component fragment. E.g., *.a.com matches foo.a.com but + not bar.foo.a.com. f*.com matches foo.com but not bar.com. + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. + + */ + return verify_host_with_subject_alt_name(server_cert) || + verify_host_with_common_name(server_cert); +} + +inline bool +SSLClient::verify_host_with_subject_alt_name(X509 *server_cert) const { + auto ret = false; + + auto type = GEN_DNS; + + struct in6_addr addr6 {}; + struct in_addr addr {}; + size_t addr_len = 0; + +#ifndef __MINGW32__ + if (inet_pton(AF_INET6, host_.c_str(), &addr6)) { + type = GEN_IPADD; + addr_len = sizeof(struct in6_addr); + } else if (inet_pton(AF_INET, host_.c_str(), &addr)) { + type = GEN_IPADD; + addr_len = sizeof(struct in_addr); + } +#endif + + auto alt_names = static_cast( + X509_get_ext_d2i(server_cert, NID_subject_alt_name, nullptr, nullptr)); + + if (alt_names) { + auto dsn_matched = false; + auto ip_matched = false; + + auto count = sk_GENERAL_NAME_num(alt_names); + + for (decltype(count) i = 0; i < count && !dsn_matched; i++) { + auto val = sk_GENERAL_NAME_value(alt_names, i); + if (val->type == type) { + auto name = + reinterpret_cast(ASN1_STRING_get0_data(val->d.ia5)); + auto name_len = static_cast(ASN1_STRING_length(val->d.ia5)); + + switch (type) { + case GEN_DNS: dsn_matched = check_host_name(name, name_len); break; + + case GEN_IPADD: + if (!memcmp(&addr6, name, addr_len) || + !memcmp(&addr, name, addr_len)) { + ip_matched = true; + } + break; + } + } + } + + if (dsn_matched || ip_matched) { ret = true; } + } + + GENERAL_NAMES_free(const_cast( + reinterpret_cast(alt_names))); + return ret; +} + +inline bool SSLClient::verify_host_with_common_name(X509 *server_cert) const { + const auto subject_name = X509_get_subject_name(server_cert); + + if (subject_name != nullptr) { + char name[BUFSIZ]; + auto name_len = X509_NAME_get_text_by_NID(subject_name, NID_commonName, + name, sizeof(name)); + + if (name_len != -1) { + return check_host_name(name, static_cast(name_len)); + } + } + + return false; +} + +inline bool SSLClient::check_host_name(const char *pattern, + size_t pattern_len) const { + if (host_.size() == pattern_len && host_ == pattern) { return true; } + + // Wildcard match + // https://bugs.launchpad.net/ubuntu/+source/firefox-3.0/+bug/376484 + std::vector pattern_components; + detail::split(&pattern[0], &pattern[pattern_len], '.', + [&](const char *b, const char *e) { + pattern_components.emplace_back(b, e); + }); + + if (host_components_.size() != pattern_components.size()) { return false; } + + auto itr = pattern_components.begin(); + for (const auto &h : host_components_) { + auto &p = *itr; + if (p != h && p != "*") { + auto partial_match = (p.size() > 0 && p[p.size() - 1] == '*' && + !p.compare(0, p.size() - 1, h)); + if (!partial_match) { return false; } + } + ++itr; + } + + return true; +} +#endif + +// Universal client implementation +inline Client::Client(const std::string &scheme_host_port) + : Client(scheme_host_port, std::string(), std::string()) {} + +inline Client::Client(const std::string &scheme_host_port, + const std::string &client_cert_path, + const std::string &client_key_path) { + const static std::regex re( + R"((?:([a-z]+):\/\/)?(?:\[([\d:]+)\]|([^:/?#]+))(?::(\d+))?)"); + + std::smatch m; + if (std::regex_match(scheme_host_port, m, re)) { + auto scheme = m[1].str(); + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + if (!scheme.empty() && (scheme != "http" && scheme != "https")) { +#else + if (!scheme.empty() && scheme != "http") { +#endif +#ifndef CPPHTTPLIB_NO_EXCEPTIONS + std::string msg = "'" + scheme + "' scheme is not supported."; + throw std::invalid_argument(msg); +#endif + return; + } + + auto is_ssl = scheme == "https"; + + auto host = m[2].str(); + if (host.empty()) { host = m[3].str(); } + + auto port_str = m[4].str(); + auto port = !port_str.empty() ? std::stoi(port_str) : (is_ssl ? 443 : 80); + + if (is_ssl) { +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + cli_ = detail::make_unique(host, port, client_cert_path, + client_key_path); + is_ssl_ = is_ssl; +#endif + } else { + cli_ = detail::make_unique(host, port, client_cert_path, + client_key_path); + } + } else { + cli_ = detail::make_unique(scheme_host_port, 80, + client_cert_path, client_key_path); + } +} + +inline Client::Client(const std::string &host, int port) + : cli_(detail::make_unique(host, port)) {} + +inline Client::Client(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + : cli_(detail::make_unique(host, port, client_cert_path, + client_key_path)) {} + +inline Client::~Client() = default; + +inline bool Client::is_valid() const { + return cli_ != nullptr && cli_->is_valid(); +} + +inline Result Client::Get(const std::string &path) { return cli_->Get(path); } +inline Result Client::Get(const std::string &path, const Headers &headers) { + return cli_->Get(path, headers); +} +inline Result Client::Get(const std::string &path, Progress progress) { + return cli_->Get(path, std::move(progress)); +} +inline Result Client::Get(const std::string &path, const Headers &headers, + Progress progress) { + return cli_->Get(path, headers, std::move(progress)); +} +inline Result Client::Get(const std::string &path, + ContentReceiver content_receiver) { + return cli_->Get(path, std::move(content_receiver)); +} +inline Result Client::Get(const std::string &path, const Headers &headers, + ContentReceiver content_receiver) { + return cli_->Get(path, headers, std::move(content_receiver)); +} +inline Result Client::Get(const std::string &path, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const std::string &path, const Headers &headers, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, headers, std::move(content_receiver), + std::move(progress)); +} +inline Result Client::Get(const std::string &path, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return cli_->Get(path, std::move(response_handler), + std::move(content_receiver)); +} +inline Result Client::Get(const std::string &path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return cli_->Get(path, headers, std::move(response_handler), + std::move(content_receiver)); +} +inline Result Client::Get(const std::string &path, + ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const std::string &path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, headers, std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const std::string &path, const Params ¶ms, + const Headers &headers, Progress progress) { + return cli_->Get(path, params, headers, std::move(progress)); +} +inline Result Client::Get(const std::string &path, const Params ¶ms, + const Headers &headers, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, params, headers, std::move(content_receiver), + std::move(progress)); +} +inline Result Client::Get(const std::string &path, const Params ¶ms, + const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, params, headers, std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} + +inline Result Client::Head(const std::string &path) { return cli_->Head(path); } +inline Result Client::Head(const std::string &path, const Headers &headers) { + return cli_->Head(path, headers); +} + +inline Result Client::Post(const std::string &path) { return cli_->Post(path); } +inline Result Client::Post(const std::string &path, const Headers &headers) { + return cli_->Post(path, headers); +} +inline Result Client::Post(const std::string &path, const char *body, + size_t content_length, + const std::string &content_type) { + return cli_->Post(path, body, content_length, content_type); +} +inline Result Client::Post(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type) { + return cli_->Post(path, headers, body, content_length, content_type); +} +inline Result Client::Post(const std::string &path, const std::string &body, + const std::string &content_type) { + return cli_->Post(path, body, content_type); +} +inline Result Client::Post(const std::string &path, const Headers &headers, + const std::string &body, + const std::string &content_type) { + return cli_->Post(path, headers, body, content_type); +} +inline Result Client::Post(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return cli_->Post(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Post(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return cli_->Post(path, std::move(content_provider), content_type); +} +inline Result Client::Post(const std::string &path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return cli_->Post(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Post(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return cli_->Post(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Post(const std::string &path, const Params ¶ms) { + return cli_->Post(path, params); +} +inline Result Client::Post(const std::string &path, const Headers &headers, + const Params ¶ms) { + return cli_->Post(path, headers, params); +} +inline Result Client::Post(const std::string &path, + const MultipartFormDataItems &items) { + return cli_->Post(path, items); +} +inline Result Client::Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items) { + return cli_->Post(path, headers, items); +} +inline Result Client::Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const std::string &boundary) { + return cli_->Post(path, headers, items, boundary); +} +inline Result +Client::Post(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items) { + return cli_->Post(path, headers, items, provider_items); +} +inline Result Client::Put(const std::string &path) { return cli_->Put(path); } +inline Result Client::Put(const std::string &path, const char *body, + size_t content_length, + const std::string &content_type) { + return cli_->Put(path, body, content_length, content_type); +} +inline Result Client::Put(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type) { + return cli_->Put(path, headers, body, content_length, content_type); +} +inline Result Client::Put(const std::string &path, const std::string &body, + const std::string &content_type) { + return cli_->Put(path, body, content_type); +} +inline Result Client::Put(const std::string &path, const Headers &headers, + const std::string &body, + const std::string &content_type) { + return cli_->Put(path, headers, body, content_type); +} +inline Result Client::Put(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return cli_->Put(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Put(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return cli_->Put(path, std::move(content_provider), content_type); +} +inline Result Client::Put(const std::string &path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return cli_->Put(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Put(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return cli_->Put(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Put(const std::string &path, const Params ¶ms) { + return cli_->Put(path, params); +} +inline Result Client::Put(const std::string &path, const Headers &headers, + const Params ¶ms) { + return cli_->Put(path, headers, params); +} +inline Result Client::Put(const std::string &path, + const MultipartFormDataItems &items) { + return cli_->Put(path, items); +} +inline Result Client::Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items) { + return cli_->Put(path, headers, items); +} +inline Result Client::Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const std::string &boundary) { + return cli_->Put(path, headers, items, boundary); +} +inline Result +Client::Put(const std::string &path, const Headers &headers, + const MultipartFormDataItems &items, + const MultipartFormDataProviderItems &provider_items) { + return cli_->Put(path, headers, items, provider_items); +} +inline Result Client::Patch(const std::string &path) { + return cli_->Patch(path); +} +inline Result Client::Patch(const std::string &path, const char *body, + size_t content_length, + const std::string &content_type) { + return cli_->Patch(path, body, content_length, content_type); +} +inline Result Client::Patch(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type) { + return cli_->Patch(path, headers, body, content_length, content_type); +} +inline Result Client::Patch(const std::string &path, const std::string &body, + const std::string &content_type) { + return cli_->Patch(path, body, content_type); +} +inline Result Client::Patch(const std::string &path, const Headers &headers, + const std::string &body, + const std::string &content_type) { + return cli_->Patch(path, headers, body, content_type); +} +inline Result Client::Patch(const std::string &path, size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return cli_->Patch(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Patch(const std::string &path, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return cli_->Patch(path, std::move(content_provider), content_type); +} +inline Result Client::Patch(const std::string &path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const std::string &content_type) { + return cli_->Patch(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Patch(const std::string &path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const std::string &content_type) { + return cli_->Patch(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Delete(const std::string &path) { + return cli_->Delete(path); +} +inline Result Client::Delete(const std::string &path, const Headers &headers) { + return cli_->Delete(path, headers); +} +inline Result Client::Delete(const std::string &path, const char *body, + size_t content_length, + const std::string &content_type) { + return cli_->Delete(path, body, content_length, content_type); +} +inline Result Client::Delete(const std::string &path, const Headers &headers, + const char *body, size_t content_length, + const std::string &content_type) { + return cli_->Delete(path, headers, body, content_length, content_type); +} +inline Result Client::Delete(const std::string &path, const std::string &body, + const std::string &content_type) { + return cli_->Delete(path, body, content_type); +} +inline Result Client::Delete(const std::string &path, const Headers &headers, + const std::string &body, + const std::string &content_type) { + return cli_->Delete(path, headers, body, content_type); +} +inline Result Client::Options(const std::string &path) { + return cli_->Options(path); +} +inline Result Client::Options(const std::string &path, const Headers &headers) { + return cli_->Options(path, headers); +} + +inline bool Client::send(Request &req, Response &res, Error &error) { + return cli_->send(req, res, error); +} + +inline Result Client::send(const Request &req) { return cli_->send(req); } + +inline void Client::stop() { cli_->stop(); } + +inline std::string Client::host() const { return cli_->host(); } + +inline int Client::port() const { return cli_->port(); } + +inline size_t Client::is_socket_open() const { return cli_->is_socket_open(); } + +inline socket_t Client::socket() const { return cli_->socket(); } + +inline void +Client::set_hostname_addr_map(std::map addr_map) { + cli_->set_hostname_addr_map(std::move(addr_map)); +} + +inline void Client::set_default_headers(Headers headers) { + cli_->set_default_headers(std::move(headers)); +} + +inline void Client::set_header_writer( + std::function const &writer) { + cli_->set_header_writer(writer); +} + +inline void Client::set_address_family(int family) { + cli_->set_address_family(family); +} + +inline void Client::set_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); } + +inline void Client::set_socket_options(SocketOptions socket_options) { + cli_->set_socket_options(std::move(socket_options)); +} + +inline void Client::set_connection_timeout(time_t sec, time_t usec) { + cli_->set_connection_timeout(sec, usec); +} + +inline void Client::set_read_timeout(time_t sec, time_t usec) { + cli_->set_read_timeout(sec, usec); +} + +inline void Client::set_write_timeout(time_t sec, time_t usec) { + cli_->set_write_timeout(sec, usec); +} + +inline void Client::set_basic_auth(const std::string &username, + const std::string &password) { + cli_->set_basic_auth(username, password); +} +inline void Client::set_bearer_token_auth(const std::string &token) { + cli_->set_bearer_token_auth(token); +} +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_digest_auth(const std::string &username, + const std::string &password) { + cli_->set_digest_auth(username, password); +} +#endif + +inline void Client::set_keep_alive(bool on) { cli_->set_keep_alive(on); } +inline void Client::set_follow_location(bool on) { + cli_->set_follow_location(on); +} + +inline void Client::set_url_encode(bool on) { cli_->set_url_encode(on); } + +inline void Client::set_compress(bool on) { cli_->set_compress(on); } + +inline void Client::set_decompress(bool on) { cli_->set_decompress(on); } + +inline void Client::set_interface(const std::string &intf) { + cli_->set_interface(intf); +} + +inline void Client::set_proxy(const std::string &host, int port) { + cli_->set_proxy(host, port); +} +inline void Client::set_proxy_basic_auth(const std::string &username, + const std::string &password) { + cli_->set_proxy_basic_auth(username, password); +} +inline void Client::set_proxy_bearer_token_auth(const std::string &token) { + cli_->set_proxy_bearer_token_auth(token); +} +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_proxy_digest_auth(const std::string &username, + const std::string &password) { + cli_->set_proxy_digest_auth(username, password); +} +#endif + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::enable_server_certificate_verification(bool enabled) { + cli_->enable_server_certificate_verification(enabled); +} +#endif + +inline void Client::set_logger(Logger logger) { + cli_->set_logger(std::move(logger)); +} + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_ca_cert_path(const std::string &ca_cert_file_path, + const std::string &ca_cert_dir_path) { + cli_->set_ca_cert_path(ca_cert_file_path, ca_cert_dir_path); +} + +inline void Client::set_ca_cert_store(X509_STORE *ca_cert_store) { + if (is_ssl_) { + static_cast(*cli_).set_ca_cert_store(ca_cert_store); + } else { + cli_->set_ca_cert_store(ca_cert_store); + } +} + +inline void Client::load_ca_cert_store(const char *ca_cert, std::size_t size) { + set_ca_cert_store(cli_->create_ca_cert_store(ca_cert, size)); +} + +inline long Client::get_openssl_verify_result() const { + if (is_ssl_) { + return static_cast(*cli_).get_openssl_verify_result(); + } + return -1; // NOTE: -1 doesn't match any of X509_V_ERR_??? +} + +inline SSL_CTX *Client::ssl_context() const { + if (is_ssl_) { return static_cast(*cli_).ssl_context(); } + return nullptr; +} +#endif + +// ---------------------------------------------------------------------------- + +} // namespace httplib + +#if defined(_WIN32) && defined(CPPHTTPLIB_USE_POLL) +#undef poll +#endif + +#endif // CPPHTTPLIB_HTTPLIB_H diff --git a/ext/ed25519-amd64-asm/batch.c b/ext/ed25519-amd64-asm/batch.c new file mode 100644 index 0000000..955392e --- /dev/null +++ b/ext/ed25519-amd64-asm/batch.c @@ -0,0 +1,94 @@ +#include "crypto_sign.h" + +#include "crypto_verify_32.h" +#include "crypto_hash_sha512.h" +#include "randombytes.h" + +#include "ge25519.h" +#include "hram.h" + +#define MAXBATCH 64 + +int crypto_sign_open_batch( + unsigned char* const m[],unsigned long long mlen[], + unsigned char* const sm[],const unsigned long long smlen[], + unsigned char* const pk[], + unsigned long long num + ) +{ + int ret = 0; + unsigned long long i, j; + shortsc25519 r[MAXBATCH]; + sc25519 scalars[2*MAXBATCH+1]; + ge25519 points[2*MAXBATCH+1]; + unsigned char hram[crypto_hash_sha512_BYTES]; + unsigned long long batchsize; + + for (i = 0;i < num;++i) mlen[i] = -1; + + while (num >= 3) { + batchsize = num; + if (batchsize > MAXBATCH) batchsize = MAXBATCH; + + for (i = 0;i < batchsize;++i) + if (smlen[i] < 64) goto fallback; + + randombytes((unsigned char*)r,sizeof(shortsc25519) * batchsize); + + /* Computing scalars[0] = ((r1s1 + r2s2 + ...)) */ + for(i=0;icaller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: tp_stack = tp +# asm 1: movq tp_stack=stack64#8 +# asm 2: movq tp_stack=56(%rsp) +movq %rdi,56(%rsp) + +# qhasm: pos *= 768 +# asm 1: imulq $768,pos=int64#1 +# asm 2: imulq $768,pos=%rdi +imulq $768,%rsi,%rdi + +# qhasm: mask = b +# asm 1: mov mask=int64#2 +# asm 2: mov mask=%rsi +mov %rdx,%rsi + +# qhasm: (int64) mask >>= 7 +# asm 1: sar $7,u=int64#5 +# asm 2: mov u=%r8 +mov %rdx,%r8 + +# qhasm: u += mask +# asm 1: add tysubx0=int64#2 +# asm 2: mov $1,>tysubx0=%rsi +mov $1,%rsi + +# qhasm: tysubx1 = 0 +# asm 1: mov $0,>tysubx1=int64#6 +# asm 2: mov $0,>tysubx1=%r9 +mov $0,%r9 + +# qhasm: tysubx2 = 0 +# asm 1: mov $0,>tysubx2=int64#7 +# asm 2: mov $0,>tysubx2=%rax +mov $0,%rax + +# qhasm: tysubx3 = 0 +# asm 1: mov $0,>tysubx3=int64#8 +# asm 2: mov $0,>tysubx3=%r10 +mov $0,%r10 + +# qhasm: txaddy0 = 1 +# asm 1: mov $1,>txaddy0=int64#9 +# asm 2: mov $1,>txaddy0=%r11 +mov $1,%r11 + +# qhasm: txaddy1 = 0 +# asm 1: mov $0,>txaddy1=int64#10 +# asm 2: mov $0,>txaddy1=%r12 +mov $0,%r12 + +# qhasm: txaddy2 = 0 +# asm 1: mov $0,>txaddy2=int64#11 +# asm 2: mov $0,>txaddy2=%r13 +mov $0,%r13 + +# qhasm: txaddy3 = 0 +# asm 1: mov $0,>txaddy3=int64#12 +# asm 2: mov $0,>txaddy3=%r14 +mov $0,%r14 + +# qhasm: =? u - 1 +# asm 1: cmp $1,t=int64#13 +# asm 2: movq 0(t=%r15 +movq 0(%rcx,%rdi),%r15 + +# qhasm: tysubx0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 8(t=%r15 +movq 8(%rcx,%rdi),%r15 + +# qhasm: tysubx1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 16(t=%r15 +movq 16(%rcx,%rdi),%r15 + +# qhasm: tysubx2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 24(t=%r15 +movq 24(%rcx,%rdi),%r15 + +# qhasm: tysubx3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 32(t=%r15 +movq 32(%rcx,%rdi),%r15 + +# qhasm: txaddy0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 40(t=%r15 +movq 40(%rcx,%rdi),%r15 + +# qhasm: txaddy1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 48(t=%r15 +movq 48(%rcx,%rdi),%r15 + +# qhasm: txaddy2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 56(t=%r15 +movq 56(%rcx,%rdi),%r15 + +# qhasm: txaddy3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 96(t=%r15 +movq 96(%rcx,%rdi),%r15 + +# qhasm: tysubx0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 104(t=%r15 +movq 104(%rcx,%rdi),%r15 + +# qhasm: tysubx1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 112(t=%r15 +movq 112(%rcx,%rdi),%r15 + +# qhasm: tysubx2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 120(t=%r15 +movq 120(%rcx,%rdi),%r15 + +# qhasm: tysubx3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 128(t=%r15 +movq 128(%rcx,%rdi),%r15 + +# qhasm: txaddy0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 136(t=%r15 +movq 136(%rcx,%rdi),%r15 + +# qhasm: txaddy1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 144(t=%r15 +movq 144(%rcx,%rdi),%r15 + +# qhasm: txaddy2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 152(t=%r15 +movq 152(%rcx,%rdi),%r15 + +# qhasm: txaddy3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 192(t=%r15 +movq 192(%rcx,%rdi),%r15 + +# qhasm: tysubx0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 200(t=%r15 +movq 200(%rcx,%rdi),%r15 + +# qhasm: tysubx1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 208(t=%r15 +movq 208(%rcx,%rdi),%r15 + +# qhasm: tysubx2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 216(t=%r15 +movq 216(%rcx,%rdi),%r15 + +# qhasm: tysubx3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 224(t=%r15 +movq 224(%rcx,%rdi),%r15 + +# qhasm: txaddy0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 232(t=%r15 +movq 232(%rcx,%rdi),%r15 + +# qhasm: txaddy1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 240(t=%r15 +movq 240(%rcx,%rdi),%r15 + +# qhasm: txaddy2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 248(t=%r15 +movq 248(%rcx,%rdi),%r15 + +# qhasm: txaddy3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 288(t=%r15 +movq 288(%rcx,%rdi),%r15 + +# qhasm: tysubx0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 296(t=%r15 +movq 296(%rcx,%rdi),%r15 + +# qhasm: tysubx1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 304(t=%r15 +movq 304(%rcx,%rdi),%r15 + +# qhasm: tysubx2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 312(t=%r15 +movq 312(%rcx,%rdi),%r15 + +# qhasm: tysubx3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 320(t=%r15 +movq 320(%rcx,%rdi),%r15 + +# qhasm: txaddy0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 328(t=%r15 +movq 328(%rcx,%rdi),%r15 + +# qhasm: txaddy1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 336(t=%r15 +movq 336(%rcx,%rdi),%r15 + +# qhasm: txaddy2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 344(t=%r15 +movq 344(%rcx,%rdi),%r15 + +# qhasm: txaddy3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 384(t=%r15 +movq 384(%rcx,%rdi),%r15 + +# qhasm: tysubx0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 392(t=%r15 +movq 392(%rcx,%rdi),%r15 + +# qhasm: tysubx1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 400(t=%r15 +movq 400(%rcx,%rdi),%r15 + +# qhasm: tysubx2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 408(t=%r15 +movq 408(%rcx,%rdi),%r15 + +# qhasm: tysubx3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 416(t=%r15 +movq 416(%rcx,%rdi),%r15 + +# qhasm: txaddy0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 424(t=%r15 +movq 424(%rcx,%rdi),%r15 + +# qhasm: txaddy1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 432(t=%r15 +movq 432(%rcx,%rdi),%r15 + +# qhasm: txaddy2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 440(t=%r15 +movq 440(%rcx,%rdi),%r15 + +# qhasm: txaddy3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 480(t=%r15 +movq 480(%rcx,%rdi),%r15 + +# qhasm: tysubx0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 488(t=%r15 +movq 488(%rcx,%rdi),%r15 + +# qhasm: tysubx1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 496(t=%r15 +movq 496(%rcx,%rdi),%r15 + +# qhasm: tysubx2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 504(t=%r15 +movq 504(%rcx,%rdi),%r15 + +# qhasm: tysubx3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 512(t=%r15 +movq 512(%rcx,%rdi),%r15 + +# qhasm: txaddy0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 520(t=%r15 +movq 520(%rcx,%rdi),%r15 + +# qhasm: txaddy1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 528(t=%r15 +movq 528(%rcx,%rdi),%r15 + +# qhasm: txaddy2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 536(t=%r15 +movq 536(%rcx,%rdi),%r15 + +# qhasm: txaddy3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 576(t=%r15 +movq 576(%rcx,%rdi),%r15 + +# qhasm: tysubx0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 584(t=%r15 +movq 584(%rcx,%rdi),%r15 + +# qhasm: tysubx1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 592(t=%r15 +movq 592(%rcx,%rdi),%r15 + +# qhasm: tysubx2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 600(t=%r15 +movq 600(%rcx,%rdi),%r15 + +# qhasm: tysubx3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 608(t=%r15 +movq 608(%rcx,%rdi),%r15 + +# qhasm: txaddy0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 616(t=%r15 +movq 616(%rcx,%rdi),%r15 + +# qhasm: txaddy1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 624(t=%r15 +movq 624(%rcx,%rdi),%r15 + +# qhasm: txaddy2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 632(t=%r15 +movq 632(%rcx,%rdi),%r15 + +# qhasm: txaddy3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 672(t=%r15 +movq 672(%rcx,%rdi),%r15 + +# qhasm: tysubx0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 680(t=%r15 +movq 680(%rcx,%rdi),%r15 + +# qhasm: tysubx1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 688(t=%r15 +movq 688(%rcx,%rdi),%r15 + +# qhasm: tysubx2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 696(t=%r15 +movq 696(%rcx,%rdi),%r15 + +# qhasm: tysubx3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 704(t=%r15 +movq 704(%rcx,%rdi),%r15 + +# qhasm: txaddy0 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 712(t=%r15 +movq 712(%rcx,%rdi),%r15 + +# qhasm: txaddy1 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 720(t=%r15 +movq 720(%rcx,%rdi),%r15 + +# qhasm: txaddy2 = t if = +# asm 1: cmove t=int64#13 +# asm 2: movq 728(t=%r15 +movq 728(%rcx,%rdi),%r15 + +# qhasm: txaddy3 = t if = +# asm 1: cmove t=int64#13 +# asm 2: mov t=%r15 +mov %rsi,%r15 + +# qhasm: tysubx0 = txaddy0 if signed< +# asm 1: cmovl t=int64#13 +# asm 2: mov t=%r15 +mov %r9,%r15 + +# qhasm: tysubx1 = txaddy1 if signed< +# asm 1: cmovl t=int64#13 +# asm 2: mov t=%r15 +mov %rax,%r15 + +# qhasm: tysubx2 = txaddy2 if signed< +# asm 1: cmovl t=int64#13 +# asm 2: mov t=%r15 +mov %r10,%r15 + +# qhasm: tysubx3 = txaddy3 if signed< +# asm 1: cmovl tp=int64#13 +# asm 2: movq tp=%r15 +movq 56(%rsp),%r15 + +# qhasm: *(uint64 *)(tp + 0) = tysubx0 +# asm 1: movq tt2d0=int64#2 +# asm 2: mov $0,>tt2d0=%rsi +mov $0,%rsi + +# qhasm: tt2d1 = 0 +# asm 1: mov $0,>tt2d1=int64#6 +# asm 2: mov $0,>tt2d1=%r9 +mov $0,%r9 + +# qhasm: tt2d2 = 0 +# asm 1: mov $0,>tt2d2=int64#7 +# asm 2: mov $0,>tt2d2=%rax +mov $0,%rax + +# qhasm: tt2d3 = 0 +# asm 1: mov $0,>tt2d3=int64#8 +# asm 2: mov $0,>tt2d3=%r10 +mov $0,%r10 + +# qhasm: =? u - 1 +# asm 1: cmp $1,t=int64#9 +# asm 2: movq 64(t=%r11 +movq 64(%rcx,%rdi),%r11 + +# qhasm: tt2d0 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 72(t=%r11 +movq 72(%rcx,%rdi),%r11 + +# qhasm: tt2d1 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 80(t=%r11 +movq 80(%rcx,%rdi),%r11 + +# qhasm: tt2d2 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 88(t=%r11 +movq 88(%rcx,%rdi),%r11 + +# qhasm: tt2d3 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 160(t=%r11 +movq 160(%rcx,%rdi),%r11 + +# qhasm: tt2d0 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 168(t=%r11 +movq 168(%rcx,%rdi),%r11 + +# qhasm: tt2d1 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 176(t=%r11 +movq 176(%rcx,%rdi),%r11 + +# qhasm: tt2d2 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 184(t=%r11 +movq 184(%rcx,%rdi),%r11 + +# qhasm: tt2d3 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 256(t=%r11 +movq 256(%rcx,%rdi),%r11 + +# qhasm: tt2d0 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 264(t=%r11 +movq 264(%rcx,%rdi),%r11 + +# qhasm: tt2d1 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 272(t=%r11 +movq 272(%rcx,%rdi),%r11 + +# qhasm: tt2d2 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 280(t=%r11 +movq 280(%rcx,%rdi),%r11 + +# qhasm: tt2d3 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 352(t=%r11 +movq 352(%rcx,%rdi),%r11 + +# qhasm: tt2d0 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 360(t=%r11 +movq 360(%rcx,%rdi),%r11 + +# qhasm: tt2d1 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 368(t=%r11 +movq 368(%rcx,%rdi),%r11 + +# qhasm: tt2d2 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 376(t=%r11 +movq 376(%rcx,%rdi),%r11 + +# qhasm: tt2d3 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 448(t=%r11 +movq 448(%rcx,%rdi),%r11 + +# qhasm: tt2d0 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 456(t=%r11 +movq 456(%rcx,%rdi),%r11 + +# qhasm: tt2d1 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 464(t=%r11 +movq 464(%rcx,%rdi),%r11 + +# qhasm: tt2d2 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 472(t=%r11 +movq 472(%rcx,%rdi),%r11 + +# qhasm: tt2d3 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 544(t=%r11 +movq 544(%rcx,%rdi),%r11 + +# qhasm: tt2d0 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 552(t=%r11 +movq 552(%rcx,%rdi),%r11 + +# qhasm: tt2d1 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 560(t=%r11 +movq 560(%rcx,%rdi),%r11 + +# qhasm: tt2d2 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 568(t=%r11 +movq 568(%rcx,%rdi),%r11 + +# qhasm: tt2d3 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 640(t=%r11 +movq 640(%rcx,%rdi),%r11 + +# qhasm: tt2d0 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 648(t=%r11 +movq 648(%rcx,%rdi),%r11 + +# qhasm: tt2d1 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 656(t=%r11 +movq 656(%rcx,%rdi),%r11 + +# qhasm: tt2d2 = t if = +# asm 1: cmove t=int64#9 +# asm 2: movq 664(t=%r11 +movq 664(%rcx,%rdi),%r11 + +# qhasm: tt2d3 = t if = +# asm 1: cmove t=int64#5 +# asm 2: movq 736(t=%r8 +movq 736(%rcx,%rdi),%r8 + +# qhasm: tt2d0 = t if = +# asm 1: cmove t=int64#5 +# asm 2: movq 744(t=%r8 +movq 744(%rcx,%rdi),%r8 + +# qhasm: tt2d1 = t if = +# asm 1: cmove t=int64#5 +# asm 2: movq 752(t=%r8 +movq 752(%rcx,%rdi),%r8 + +# qhasm: tt2d2 = t if = +# asm 1: cmove t=int64#1 +# asm 2: movq 760(t=%rdi +movq 760(%rcx,%rdi),%rdi + +# qhasm: tt2d3 = t if = +# asm 1: cmove tt0=int64#1 +# asm 2: mov $0,>tt0=%rdi +mov $0,%rdi + +# qhasm: tt1 = 0 +# asm 1: mov $0,>tt1=int64#4 +# asm 2: mov $0,>tt1=%rcx +mov $0,%rcx + +# qhasm: tt2 = 0 +# asm 1: mov $0,>tt2=int64#5 +# asm 2: mov $0,>tt2=%r8 +mov $0,%r8 + +# qhasm: tt3 = 0 +# asm 1: mov $0,>tt3=int64#9 +# asm 2: mov $0,>tt3=%r11 +mov $0,%r11 + +# qhasm: carry? tt0 -= tt2d0 +# asm 1: sub subt0=int64#10 +# asm 2: mov $0,>subt0=%r12 +mov $0,%r12 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#11 +# asm 2: mov $38,>subt1=%r13 +mov $38,%r13 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/consts.s b/ext/ed25519-amd64-asm/consts.s new file mode 100644 index 0000000..c272383 --- /dev/null +++ b/ext/ed25519-amd64-asm/consts.s @@ -0,0 +1,39 @@ +.data + +.globl crypto_sign_ed25519_amd64_64_121666 +.globl crypto_sign_ed25519_amd64_64_MU0 +.globl crypto_sign_ed25519_amd64_64_MU1 +.globl crypto_sign_ed25519_amd64_64_MU2 +.globl crypto_sign_ed25519_amd64_64_MU3 +.globl crypto_sign_ed25519_amd64_64_MU4 +.globl crypto_sign_ed25519_amd64_64_ORDER0 +.globl crypto_sign_ed25519_amd64_64_ORDER1 +.globl crypto_sign_ed25519_amd64_64_ORDER2 +.globl crypto_sign_ed25519_amd64_64_ORDER3 +.globl crypto_sign_ed25519_amd64_64_EC2D0 +.globl crypto_sign_ed25519_amd64_64_EC2D1 +.globl crypto_sign_ed25519_amd64_64_EC2D2 +.globl crypto_sign_ed25519_amd64_64_EC2D3 +.globl crypto_sign_ed25519_amd64_64_38 + +.p2align 4 + +crypto_sign_ed25519_amd64_64_121666: .quad 121666 + +crypto_sign_ed25519_amd64_64_MU0: .quad 0xED9CE5A30A2C131B +crypto_sign_ed25519_amd64_64_MU1: .quad 0x2106215D086329A7 +crypto_sign_ed25519_amd64_64_MU2: .quad 0xFFFFFFFFFFFFFFEB +crypto_sign_ed25519_amd64_64_MU3: .quad 0xFFFFFFFFFFFFFFFF +crypto_sign_ed25519_amd64_64_MU4: .quad 0x000000000000000F + +crypto_sign_ed25519_amd64_64_ORDER0: .quad 0x5812631A5CF5D3ED +crypto_sign_ed25519_amd64_64_ORDER1: .quad 0x14DEF9DEA2F79CD6 +crypto_sign_ed25519_amd64_64_ORDER2: .quad 0x0000000000000000 +crypto_sign_ed25519_amd64_64_ORDER3: .quad 0x1000000000000000 + +crypto_sign_ed25519_amd64_64_EC2D0: .quad 0xEBD69B9426B2F146 +crypto_sign_ed25519_amd64_64_EC2D1: .quad 0x00E0149A8283B156 +crypto_sign_ed25519_amd64_64_EC2D2: .quad 0x198E80F2EEF3D130 +crypto_sign_ed25519_amd64_64_EC2D3: .quad 0xA406D9DC56DFFCE7 + +crypto_sign_ed25519_amd64_64_38: .quad 38 diff --git a/ext/ed25519-amd64-asm/fe25519.h b/ext/ed25519-amd64-asm/fe25519.h new file mode 100644 index 0000000..33ffabb --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519.h @@ -0,0 +1,64 @@ +#ifndef FE25519_H +#define FE25519_H + +#define fe25519 crypto_sign_ed25519_amd64_64_fe25519 +#define fe25519_freeze crypto_sign_ed25519_amd64_64_fe25519_freeze +#define fe25519_unpack crypto_sign_ed25519_amd64_64_fe25519_unpack +#define fe25519_pack crypto_sign_ed25519_amd64_64_fe25519_pack +#define fe25519_iszero_vartime crypto_sign_ed25519_amd64_64_fe25519_iszero_vartime +#define fe25519_iseq_vartime crypto_sign_ed25519_amd64_64_fe25519_iseq_vartime +#define fe25519_cmov crypto_sign_ed25519_amd64_64_fe25519_cmov +#define fe25519_setint crypto_sign_ed25519_amd64_64_fe25519_setint +#define fe25519_neg crypto_sign_ed25519_amd64_64_fe25519_neg +#define fe25519_getparity crypto_sign_ed25519_amd64_64_fe25519_getparity +#define fe25519_add crypto_sign_ed25519_amd64_64_fe25519_add +#define fe25519_sub crypto_sign_ed25519_amd64_64_fe25519_sub +#define fe25519_mul crypto_sign_ed25519_amd64_64_fe25519_mul +#define fe25519_mul121666 crypto_sign_ed25519_amd64_64_fe25519_mul121666 +#define fe25519_square crypto_sign_ed25519_amd64_64_fe25519_square +#define fe25519_invert crypto_sign_ed25519_amd64_64_fe25519_invert +#define fe25519_pow2523 crypto_sign_ed25519_amd64_64_fe25519_pow2523 + +typedef struct +{ + unsigned long long v[4]; +} +fe25519; + +void fe25519_freeze(fe25519 *r); + +void fe25519_unpack(fe25519 *r, const unsigned char x[32]); + +void fe25519_pack(unsigned char r[32], const fe25519 *x); + +void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b); + +void fe25519_cswap(fe25519 *r, fe25519 *x, unsigned char b); + +void fe25519_setint(fe25519 *r, unsigned int v); + +void fe25519_neg(fe25519 *r, const fe25519 *x); + +unsigned char fe25519_getparity(const fe25519 *x); + +int fe25519_iszero_vartime(const fe25519 *x); + +int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y); + +void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y); + +void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); + +void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y); + +void fe25519_mul121666(fe25519 *r, const fe25519 *x); + +void fe25519_square(fe25519 *r, const fe25519 *x); + +void fe25519_pow(fe25519 *r, const fe25519 *x, const unsigned char *e); + +void fe25519_invert(fe25519 *r, const fe25519 *x); + +void fe25519_pow2523(fe25519 *r, const fe25519 *x); + +#endif diff --git a/ext/ed25519-amd64-asm/fe25519_add.s b/ext/ed25519-amd64-asm/fe25519_add.s new file mode 100644 index 0000000..b2e5625 --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_add.s @@ -0,0 +1,189 @@ + +# qhasm: int64 rp + +# qhasm: int64 xp + +# qhasm: int64 yp + +# qhasm: input rp + +# qhasm: input xp + +# qhasm: input yp + +# qhasm: int64 r0 + +# qhasm: int64 r1 + +# qhasm: int64 r2 + +# qhasm: int64 r3 + +# qhasm: int64 addt0 + +# qhasm: int64 addt1 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_fe25519_add +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_fe25519_add +.globl crypto_sign_ed25519_amd64_64_fe25519_add +_crypto_sign_ed25519_amd64_64_fe25519_add: +crypto_sign_ed25519_amd64_64_fe25519_add: +mov %rsp,%r11 +and $31,%r11 +add $0,%r11 +sub %r11,%rsp + +# qhasm: r0 = *(uint64 *)(xp + 0) +# asm 1: movq 0(r0=int64#4 +# asm 2: movq 0(r0=%rcx +movq 0(%rsi),%rcx + +# qhasm: r1 = *(uint64 *)(xp + 8) +# asm 1: movq 8(r1=int64#5 +# asm 2: movq 8(r1=%r8 +movq 8(%rsi),%r8 + +# qhasm: r2 = *(uint64 *)(xp + 16) +# asm 1: movq 16(r2=int64#6 +# asm 2: movq 16(r2=%r9 +movq 16(%rsi),%r9 + +# qhasm: r3 = *(uint64 *)(xp + 24) +# asm 1: movq 24(r3=int64#2 +# asm 2: movq 24(r3=%rsi +movq 24(%rsi),%rsi + +# qhasm: carry? r0 += *(uint64 *)(yp + 0) +# asm 1: addq 0(addt0=int64#3 +# asm 2: mov $0,>addt0=%rdx +mov $0,%rdx + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#7 +# asm 2: mov $38,>addt1=%rax +mov $38,%rax + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: r0 = *(uint64 *) (rp + 0) +# asm 1: movq 0(r0=int64#2 +# asm 2: movq 0(r0=%rsi +movq 0(%rdi),%rsi + +# qhasm: r1 = *(uint64 *) (rp + 8) +# asm 1: movq 8(r1=int64#3 +# asm 2: movq 8(r1=%rdx +movq 8(%rdi),%rdx + +# qhasm: r2 = *(uint64 *) (rp + 16) +# asm 1: movq 16(r2=int64#4 +# asm 2: movq 16(r2=%rcx +movq 16(%rdi),%rcx + +# qhasm: r3 = *(uint64 *) (rp + 24) +# asm 1: movq 24(r3=int64#5 +# asm 2: movq 24(r3=%r8 +movq 24(%rdi),%r8 + +# qhasm: t0 = r0 +# asm 1: mov t0=int64#6 +# asm 2: mov t0=%r9 +mov %rsi,%r9 + +# qhasm: t1 = r1 +# asm 1: mov t1=int64#7 +# asm 2: mov t1=%rax +mov %rdx,%rax + +# qhasm: t2 = r2 +# asm 1: mov t2=int64#8 +# asm 2: mov t2=%r10 +mov %rcx,%r10 + +# qhasm: t3 = r3 +# asm 1: mov t3=int64#9 +# asm 2: mov t3=%r11 +mov %r8,%r11 + +# qhasm: two63 = 1 +# asm 1: mov $1,>two63=int64#10 +# asm 2: mov $1,>two63=%r12 +mov $1,%r12 + +# qhasm: two63 <<= 63 +# asm 1: shl $63,t0=int64#6 +# asm 2: mov t0=%r9 +mov %rsi,%r9 + +# qhasm: t1 = r1 +# asm 1: mov t1=int64#7 +# asm 2: mov t1=%rax +mov %rdx,%rax + +# qhasm: t2 = r2 +# asm 1: mov t2=int64#8 +# asm 2: mov t2=%r10 +mov %rcx,%r10 + +# qhasm: t3 = r3 +# asm 1: mov t3=int64#9 +# asm 2: mov t3=%r11 +mov %r8,%r11 + +# qhasm: carry? t0 += 19 +# asm 1: add $19,caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/fe25519_getparity.c b/ext/ed25519-amd64-asm/fe25519_getparity.c new file mode 100644 index 0000000..a003ec8 --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_getparity.c @@ -0,0 +1,8 @@ +#include "fe25519.h" + +unsigned char fe25519_getparity(const fe25519 *x) +{ + fe25519 t = *x; + fe25519_freeze(&t); + return (unsigned char)t.v[0] & 1; +} diff --git a/ext/ed25519-amd64-asm/fe25519_invert.c b/ext/ed25519-amd64-asm/fe25519_invert.c new file mode 100644 index 0000000..a46d141 --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_invert.c @@ -0,0 +1,60 @@ +#include "fe25519.h" + +void fe25519_invert(fe25519 *r, const fe25519 *x) +{ + fe25519 z2; + fe25519 z9; + fe25519 z11; + fe25519 z2_5_0; + fe25519 z2_10_0; + fe25519 z2_20_0; + fe25519 z2_50_0; + fe25519 z2_100_0; + fe25519 t; + int i; + + /* 2 */ fe25519_square(&z2,x); + /* 4 */ fe25519_square(&t,&z2); + /* 8 */ fe25519_square(&t,&t); + /* 9 */ fe25519_mul(&z9,&t,x); + /* 11 */ fe25519_mul(&z11,&z9,&z2); + /* 22 */ fe25519_square(&t,&z11); + /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9); + + /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0); + /* 2^20 - 2^10 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); } + /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0); + + /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0); + /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } + /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0); + + /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0); + /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); } + /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0); + + /* 2^41 - 2^1 */ fe25519_square(&t,&t); + /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } + /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0); + + /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0); + /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } + /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0); + + /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0); + /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); } + /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0); + + /* 2^201 - 2^1 */ fe25519_square(&t,&t); + /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } + /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0); + + /* 2^251 - 2^1 */ fe25519_square(&t,&t); + /* 2^252 - 2^2 */ fe25519_square(&t,&t); + /* 2^253 - 2^3 */ fe25519_square(&t,&t); + + /* 2^254 - 2^4 */ fe25519_square(&t,&t); + + /* 2^255 - 2^5 */ fe25519_square(&t,&t); + /* 2^255 - 21 */ fe25519_mul(r,&t,&z11); +} diff --git a/ext/ed25519-amd64-asm/fe25519_iseq.c b/ext/ed25519-amd64-asm/fe25519_iseq.c new file mode 100644 index 0000000..bf72f8c --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_iseq.c @@ -0,0 +1,14 @@ +#include "fe25519.h" + +int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y) +{ + fe25519 t1 = *x; + fe25519 t2 = *y; + fe25519_freeze(&t1); + fe25519_freeze(&t2); + if(t1.v[0] != t2.v[0]) return 0; + if(t1.v[1] != t2.v[1]) return 0; + if(t1.v[2] != t2.v[2]) return 0; + if(t1.v[3] != t2.v[3]) return 0; + return 1; +} diff --git a/ext/ed25519-amd64-asm/fe25519_iszero.c b/ext/ed25519-amd64-asm/fe25519_iszero.c new file mode 100644 index 0000000..99e4daf --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_iszero.c @@ -0,0 +1,12 @@ +#include "fe25519.h" + +int fe25519_iszero_vartime(const fe25519 *x) +{ + fe25519 t = *x; + fe25519_freeze(&t); + if (t.v[0]) return 0; + if (t.v[1]) return 0; + if (t.v[2]) return 0; + if (t.v[3]) return 0; + return 1; +} diff --git a/ext/ed25519-amd64-asm/fe25519_mul.s b/ext/ed25519-amd64-asm/fe25519_mul.s new file mode 100644 index 0000000..1478428 --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_mul.s @@ -0,0 +1,865 @@ + +# qhasm: int64 rp + +# qhasm: int64 xp + +# qhasm: int64 yp + +# qhasm: input rp + +# qhasm: input xp + +# qhasm: input yp + +# qhasm: int64 r0 + +# qhasm: int64 r1 + +# qhasm: int64 r2 + +# qhasm: int64 r3 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 mulr4 + +# qhasm: int64 mulr5 + +# qhasm: int64 mulr6 + +# qhasm: int64 mulr7 + +# qhasm: int64 mulr8 + +# qhasm: int64 mulrax + +# qhasm: int64 mulrdx + +# qhasm: int64 mulx0 + +# qhasm: int64 mulx1 + +# qhasm: int64 mulx2 + +# qhasm: int64 mulx3 + +# qhasm: int64 mulc + +# qhasm: int64 mulzero + +# qhasm: int64 muli38 + +# qhasm: enter crypto_sign_ed25519_amd64_64_fe25519_mul +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_fe25519_mul +.globl crypto_sign_ed25519_amd64_64_fe25519_mul +_crypto_sign_ed25519_amd64_64_fe25519_mul: +crypto_sign_ed25519_amd64_64_fe25519_mul: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: yp = yp +# asm 1: mov yp=int64#4 +# asm 2: mov yp=%rcx +mov %rdx,%rcx + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = *(uint64 *)(xp + 0) +# asm 1: movq 0(mulx0=int64#10 +# asm 2: movq 0(mulx0=%r12 +movq 0(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(yp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul r0=int64#11 +# asm 2: mov r0=%r13 +mov %rax,%r13 + +# qhasm: r1 = mulrdx +# asm 1: mov r1=int64#12 +# asm 2: mov r1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(yp + 8) +# asm 1: movq 8(mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul r2=int64#13 +# asm 2: mov $0,>r2=%r15 +mov $0,%r15 + +# qhasm: r2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul r3=int64#14 +# asm 2: mov $0,>r3=%rbx +mov $0,%rbx + +# qhasm: r3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq 8(mulx1=%r12 +movq 8(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(yp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq 16(mulx2=%r12 +movq 16(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(yp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#2 +# asm 2: movq 24(mulx3=%rsi +movq 24(%rsi),%rsi + +# qhasm: mulrax = *(uint64 *)(yp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? r0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: r0 += mulzero +# asm 1: add caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/fe25519_neg.c b/ext/ed25519-amd64-asm/fe25519_neg.c new file mode 100644 index 0000000..235b209 --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_neg.c @@ -0,0 +1,8 @@ +#include "fe25519.h" + +void fe25519_neg(fe25519 *r, const fe25519 *x) +{ + fe25519 t; + fe25519_setint(&t,0); + fe25519_sub(r,&t,x); +} diff --git a/ext/ed25519-amd64-asm/fe25519_pack.c b/ext/ed25519-amd64-asm/fe25519_pack.c new file mode 100644 index 0000000..caf5185 --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_pack.c @@ -0,0 +1,13 @@ +#include "fe25519.h" + +/* Assumes input x being reduced below 2^255 */ +void fe25519_pack(unsigned char r[32], const fe25519 *x) +{ + int i; + fe25519 t; + t = *x; + fe25519_freeze(&t); + /* assuming little-endian */ + for(i=0;i<32;i++) r[i] = i[(unsigned char *)&t.v]; +} + diff --git a/ext/ed25519-amd64-asm/fe25519_pow2523.c b/ext/ed25519-amd64-asm/fe25519_pow2523.c new file mode 100644 index 0000000..60042a0 --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_pow2523.c @@ -0,0 +1,55 @@ +#include "fe25519.h" + +void fe25519_pow2523(fe25519 *r, const fe25519 *x) +{ + fe25519 z2; + fe25519 z9; + fe25519 z11; + fe25519 z2_5_0; + fe25519 z2_10_0; + fe25519 z2_20_0; + fe25519 z2_50_0; + fe25519 z2_100_0; + fe25519 t; + int i; + + /* 2 */ fe25519_square(&z2,x); + /* 4 */ fe25519_square(&t,&z2); + /* 8 */ fe25519_square(&t,&t); + /* 9 */ fe25519_mul(&z9,&t,x); + /* 11 */ fe25519_mul(&z11,&z9,&z2); + /* 22 */ fe25519_square(&t,&z11); + /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9); + + /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0); + /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); } + /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0); + + /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0); + /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } + /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0); + + /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0); + /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); } + /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0); + + /* 2^41 - 2^1 */ fe25519_square(&t,&t); + /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } + /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0); + + /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0); + /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } + /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0); + + /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0); + /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); } + /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0); + + /* 2^201 - 2^1 */ fe25519_square(&t,&t); + /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } + /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0); + + /* 2^251 - 2^1 */ fe25519_square(&t,&t); + /* 2^252 - 2^2 */ fe25519_square(&t,&t); + /* 2^252 - 3 */ fe25519_mul(r,&t,x); +} diff --git a/ext/ed25519-amd64-asm/fe25519_setint.c b/ext/ed25519-amd64-asm/fe25519_setint.c new file mode 100644 index 0000000..585c4bd --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_setint.c @@ -0,0 +1,9 @@ +#include "fe25519.h" + +void fe25519_setint(fe25519 *r, unsigned int v) +{ + r->v[0] = v; + r->v[1] = 0; + r->v[2] = 0; + r->v[3] = 0; +} diff --git a/ext/ed25519-amd64-asm/fe25519_square.s b/ext/ed25519-amd64-asm/fe25519_square.s new file mode 100644 index 0000000..a74d9e8 --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_square.s @@ -0,0 +1,639 @@ + +# qhasm: int64 rp + +# qhasm: int64 xp + +# qhasm: input rp + +# qhasm: input xp + +# qhasm: int64 r0 + +# qhasm: int64 r1 + +# qhasm: int64 r2 + +# qhasm: int64 r3 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 squarer4 + +# qhasm: int64 squarer5 + +# qhasm: int64 squarer6 + +# qhasm: int64 squarer7 + +# qhasm: int64 squarer8 + +# qhasm: int64 squarerax + +# qhasm: int64 squarerdx + +# qhasm: int64 squaret1 + +# qhasm: int64 squaret2 + +# qhasm: int64 squaret3 + +# qhasm: int64 squarec + +# qhasm: int64 squarezero + +# qhasm: int64 squarei38 + +# qhasm: enter crypto_sign_ed25519_amd64_64_fe25519_square +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_fe25519_square +.globl crypto_sign_ed25519_amd64_64_fe25519_square +_crypto_sign_ed25519_amd64_64_fe25519_square: +crypto_sign_ed25519_amd64_64_fe25519_square: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#4 +# asm 2: mov $0,>squarer7=%rcx +mov $0,%rcx + +# qhasm: squarerax = *(uint64 *)(xp + 8) +# asm 1: movq 8(squarerax=int64#7 +# asm 2: movq 8(squarerax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 0) +# asm 1: mulq 0(r1=int64#5 +# asm 2: mov r1=%r8 +mov %rax,%r8 + +# qhasm: r2 = squarerdx +# asm 1: mov r2=int64#6 +# asm 2: mov r2=%r9 +mov %rdx,%r9 + +# qhasm: squarerax = *(uint64 *)(xp + 16) +# asm 1: movq 16(squarerax=int64#7 +# asm 2: movq 16(squarerax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 8) +# asm 1: mulq 8(r3=int64#8 +# asm 2: mov r3=%r10 +mov %rax,%r10 + +# qhasm: squarer4 = squarerdx +# asm 1: mov squarer4=int64#9 +# asm 2: mov squarer4=%r11 +mov %rdx,%r11 + +# qhasm: squarerax = *(uint64 *)(xp + 24) +# asm 1: movq 24(squarerax=int64#7 +# asm 2: movq 24(squarerax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 16) +# asm 1: mulq 16(squarer5=int64#10 +# asm 2: mov squarer5=%r12 +mov %rax,%r12 + +# qhasm: squarer6 = squarerdx +# asm 1: mov squarer6=int64#11 +# asm 2: mov squarer6=%r13 +mov %rdx,%r13 + +# qhasm: squarerax = *(uint64 *)(xp + 16) +# asm 1: movq 16(squarerax=int64#7 +# asm 2: movq 16(squarerax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 0) +# asm 1: mulq 0(squarerax=int64#7 +# asm 2: movq 24(squarerax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 8) +# asm 1: mulq 8(squarerax=int64#7 +# asm 2: movq 24(squarerax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 0) +# asm 1: mulq 0(squarerax=int64#7 +# asm 2: movq 0(squarerax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 0) +# asm 1: mulq 0(r0=int64#12 +# asm 2: mov r0=%r14 +mov %rax,%r14 + +# qhasm: squaret1 = squarerdx +# asm 1: mov squaret1=int64#13 +# asm 2: mov squaret1=%r15 +mov %rdx,%r15 + +# qhasm: squarerax = *(uint64 *)(xp + 8) +# asm 1: movq 8(squarerax=int64#7 +# asm 2: movq 8(squarerax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 8) +# asm 1: mulq 8(squaret2=int64#14 +# asm 2: mov squaret2=%rbx +mov %rax,%rbx + +# qhasm: squaret3 = squarerdx +# asm 1: mov squaret3=int64#15 +# asm 2: mov squaret3=%rbp +mov %rdx,%rbp + +# qhasm: squarerax = *(uint64 *)(xp + 16) +# asm 1: movq 16(squarerax=int64#7 +# asm 2: movq 16(squarerax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 16) +# asm 1: mulq 16(squarerax=int64#7 +# asm 2: movq 24(squarerax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 24) +# asm 1: mulq 24(squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r11,%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: squarer4 = squarerax +# asm 1: mov squarer4=int64#2 +# asm 2: mov squarer4=%rsi +mov %rax,%rsi + +# qhasm: squarerax = squarer5 +# asm 1: mov squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r12,%rax + +# qhasm: squarer5 = squarerdx +# asm 1: mov squarer5=int64#9 +# asm 2: mov squarer5=%r11 +mov %rdx,%r11 + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? squarer5 += squarerax +# asm 1: add squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r13,%rax + +# qhasm: squarer6 = 0 +# asm 1: mov $0,>squarer6=int64#10 +# asm 2: mov $0,>squarer6=%r12 +mov $0,%r12 + +# qhasm: squarer6 += squarerdx + carry +# asm 1: adc squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %rcx,%rax + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#4 +# asm 2: mov $0,>squarer7=%rcx +mov $0,%rcx + +# qhasm: squarer7 += squarerdx + carry +# asm 1: adc squarer8=int64#7 +# asm 2: mov $0,>squarer8=%rax +mov $0,%rax + +# qhasm: squarer8 += squarerdx + carry +# asm 1: adc squarezero=int64#2 +# asm 2: mov $0,>squarezero=%rsi +mov $0,%rsi + +# qhasm: squarer8 += squarezero + carry +# asm 1: adc squarer8=int64#3 +# asm 2: imulq $38,squarer8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? r0 += squarer8 +# asm 1: add squarezero=int64#2 +# asm 2: imulq $38,squarezero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: r0 += squarezero +# asm 1: add caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/fe25519_sub.s b/ext/ed25519-amd64-asm/fe25519_sub.s new file mode 100644 index 0000000..0b395bc --- /dev/null +++ b/ext/ed25519-amd64-asm/fe25519_sub.s @@ -0,0 +1,189 @@ + +# qhasm: int64 rp + +# qhasm: int64 xp + +# qhasm: int64 yp + +# qhasm: input rp + +# qhasm: input xp + +# qhasm: input yp + +# qhasm: int64 r0 + +# qhasm: int64 r1 + +# qhasm: int64 r2 + +# qhasm: int64 r3 + +# qhasm: int64 subt0 + +# qhasm: int64 subt1 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_fe25519_sub +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_fe25519_sub +.globl crypto_sign_ed25519_amd64_64_fe25519_sub +_crypto_sign_ed25519_amd64_64_fe25519_sub: +crypto_sign_ed25519_amd64_64_fe25519_sub: +mov %rsp,%r11 +and $31,%r11 +add $0,%r11 +sub %r11,%rsp + +# qhasm: r0 = *(uint64 *)(xp + 0) +# asm 1: movq 0(r0=int64#4 +# asm 2: movq 0(r0=%rcx +movq 0(%rsi),%rcx + +# qhasm: r1 = *(uint64 *)(xp + 8) +# asm 1: movq 8(r1=int64#5 +# asm 2: movq 8(r1=%r8 +movq 8(%rsi),%r8 + +# qhasm: r2 = *(uint64 *)(xp + 16) +# asm 1: movq 16(r2=int64#6 +# asm 2: movq 16(r2=%r9 +movq 16(%rsi),%r9 + +# qhasm: r3 = *(uint64 *)(xp + 24) +# asm 1: movq 24(r3=int64#2 +# asm 2: movq 24(r3=%rsi +movq 24(%rsi),%rsi + +# qhasm: carry? r0 -= *(uint64 *)(yp + 0) +# asm 1: subq 0(subt0=int64#3 +# asm 2: mov $0,>subt0=%rdx +mov $0,%rdx + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#7 +# asm 2: mov $38,>subt1=%rax +mov $38,%rax + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae v[0] = *(unsigned long long *)x; + r->v[1] = *(((unsigned long long *)x)+1); + r->v[2] = *(((unsigned long long *)x)+2); + r->v[3] = *(((unsigned long long *)x)+3); + r->v[3] &= 0x7fffffffffffffffULL; +} diff --git a/ext/ed25519-amd64-asm/ge25519.h b/ext/ed25519-amd64-asm/ge25519.h new file mode 100644 index 0000000..0b15136 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519.h @@ -0,0 +1,95 @@ +#ifndef GE25519_H +#define GE25519_H + +#include "fe25519.h" +#include "sc25519.h" + +#define ge25519 crypto_sign_ed25519_amd64_64_ge25519 +#define ge25519_base crypto_sign_ed25519_amd64_64_ge25519_base +#define ge25519_unpackneg_vartime crypto_sign_ed25519_amd64_64_unpackneg_vartime +#define ge25519_pack crypto_sign_ed25519_amd64_64_pack +#define ge25519_isneutral_vartime crypto_sign_ed25519_amd64_64_isneutral_vartime +#define ge25519_add crypto_sign_ed25519_amd64_64_ge25519_add +#define ge25519_double crypto_sign_ed25519_amd64_64_ge25519_double +#define ge25519_double_scalarmult_vartime crypto_sign_ed25519_amd64_64_double_scalarmult_vartime +#define ge25519_multi_scalarmult_vartime crypto_sign_ed25519_amd64_64_ge25519_multi_scalarmult_vartime +#define ge25519_scalarmult_base crypto_sign_ed25519_amd64_64_scalarmult_base +#define ge25519_p1p1_to_p2 crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2 +#define ge25519_p1p1_to_p3 crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3 +#define ge25519_add_p1p1 crypto_sign_ed25519_amd64_64_ge25519_add_p1p1 +#define ge25519_dbl_p1p1 crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1 +#define choose_t crypto_sign_ed25519_amd64_64_choose_t +#define ge25519_nielsadd2 crypto_sign_ed25519_amd64_64_ge25519_nielsadd2 +#define ge25519_nielsadd_p1p1 crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1 +#define ge25519_pnielsadd_p1p1 crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1 + + +#define ge25519_p3 ge25519 + +typedef struct +{ + fe25519 x; + fe25519 y; + fe25519 z; + fe25519 t; +} ge25519; + +typedef struct +{ + fe25519 x; + fe25519 z; + fe25519 y; + fe25519 t; +} ge25519_p1p1; + +typedef struct +{ + fe25519 x; + fe25519 y; + fe25519 z; +} ge25519_p2; + +typedef struct +{ + fe25519 ysubx; + fe25519 xaddy; + fe25519 t2d; +} ge25519_niels; + +typedef struct +{ + fe25519 ysubx; + fe25519 xaddy; + fe25519 z; + fe25519 t2d; +} ge25519_pniels; + +extern void ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p); +extern void ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p); +extern void ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q); +extern void ge25519_dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p); +extern void choose_t(ge25519_niels *t, unsigned long long pos, signed long long b, const ge25519_niels *base_multiples); +extern void ge25519_nielsadd2(ge25519_p3 *r, const ge25519_niels *q); +extern void ge25519_nielsadd_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_niels *q); +extern void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_pniels *q); + +extern const ge25519 ge25519_base; + +extern int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]); + +extern void ge25519_pack(unsigned char r[32], const ge25519 *p); + +extern int ge25519_isneutral_vartime(const ge25519 *p); + +extern void ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q); + +extern void ge25519_double(ge25519 *r, const ge25519 *p); + +/* computes [s1]p1 + [s2]ge25519_base */ +extern void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const sc25519 *s2); + +extern void ge25519_multi_scalarmult_vartime(ge25519 *r, ge25519 *p, sc25519 *s, const unsigned long long npoints); + +extern void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s); + +#endif diff --git a/ext/ed25519-amd64-asm/ge25519_add.c b/ext/ed25519-amd64-asm/ge25519_add.c new file mode 100644 index 0000000..c4d1c68 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_add.c @@ -0,0 +1,8 @@ +#include "ge25519.h" + +void ge25519_add(ge25519_p3 *r, const ge25519_p3 *p, const ge25519_p3 *q) +{ + ge25519_p1p1 grp1p1; + ge25519_add_p1p1(&grp1p1, p, q); + ge25519_p1p1_to_p3(r, &grp1p1); +} diff --git a/ext/ed25519-amd64-asm/ge25519_add_p1p1.s b/ext/ed25519-amd64-asm/ge25519_add_p1p1.s new file mode 100644 index 0000000..0cb1389 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_add_p1p1.s @@ -0,0 +1,4554 @@ + +# qhasm: int64 rp + +# qhasm: int64 pp + +# qhasm: int64 qp + +# qhasm: input rp + +# qhasm: input pp + +# qhasm: input qp + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 a0 + +# qhasm: int64 a1 + +# qhasm: int64 a2 + +# qhasm: int64 a3 + +# qhasm: stack64 a0_stack + +# qhasm: stack64 a1_stack + +# qhasm: stack64 a2_stack + +# qhasm: stack64 a3_stack + +# qhasm: int64 b0 + +# qhasm: int64 b1 + +# qhasm: int64 b2 + +# qhasm: int64 b3 + +# qhasm: stack64 b0_stack + +# qhasm: stack64 b1_stack + +# qhasm: stack64 b2_stack + +# qhasm: stack64 b3_stack + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: stack64 c0_stack + +# qhasm: stack64 c1_stack + +# qhasm: stack64 c2_stack + +# qhasm: stack64 c3_stack + +# qhasm: int64 d0 + +# qhasm: int64 d1 + +# qhasm: int64 d2 + +# qhasm: int64 d3 + +# qhasm: stack64 d0_stack + +# qhasm: stack64 d1_stack + +# qhasm: stack64 d2_stack + +# qhasm: stack64 d3_stack + +# qhasm: int64 t10 + +# qhasm: int64 t11 + +# qhasm: int64 t12 + +# qhasm: int64 t13 + +# qhasm: stack64 t10_stack + +# qhasm: stack64 t11_stack + +# qhasm: stack64 t12_stack + +# qhasm: stack64 t13_stack + +# qhasm: int64 t20 + +# qhasm: int64 t21 + +# qhasm: int64 t22 + +# qhasm: int64 t23 + +# qhasm: stack64 t20_stack + +# qhasm: stack64 t21_stack + +# qhasm: stack64 t22_stack + +# qhasm: stack64 t23_stack + +# qhasm: int64 rx0 + +# qhasm: int64 rx1 + +# qhasm: int64 rx2 + +# qhasm: int64 rx3 + +# qhasm: int64 ry0 + +# qhasm: int64 ry1 + +# qhasm: int64 ry2 + +# qhasm: int64 ry3 + +# qhasm: int64 rz0 + +# qhasm: int64 rz1 + +# qhasm: int64 rz2 + +# qhasm: int64 rz3 + +# qhasm: int64 rt0 + +# qhasm: int64 rt1 + +# qhasm: int64 rt2 + +# qhasm: int64 rt3 + +# qhasm: int64 x0 + +# qhasm: int64 x1 + +# qhasm: int64 x2 + +# qhasm: int64 x3 + +# qhasm: int64 mulr4 + +# qhasm: int64 mulr5 + +# qhasm: int64 mulr6 + +# qhasm: int64 mulr7 + +# qhasm: int64 mulr8 + +# qhasm: int64 mulrax + +# qhasm: int64 mulrdx + +# qhasm: int64 mulx0 + +# qhasm: int64 mulx1 + +# qhasm: int64 mulx2 + +# qhasm: int64 mulx3 + +# qhasm: int64 mulc + +# qhasm: int64 mulzero + +# qhasm: int64 muli38 + +# qhasm: int64 addt0 + +# qhasm: int64 addt1 + +# qhasm: int64 subt0 + +# qhasm: int64 subt1 + +# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_add_p1p1 +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_ge25519_add_p1p1 +.globl crypto_sign_ed25519_amd64_64_ge25519_add_p1p1 +_crypto_sign_ed25519_amd64_64_ge25519_add_p1p1: +crypto_sign_ed25519_amd64_64_ge25519_add_p1p1: +mov %rsp,%r11 +and $31,%r11 +add $192,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: qp = qp +# asm 1: mov qp=int64#4 +# asm 2: mov qp=%rcx +mov %rdx,%rcx + +# qhasm: a0 = *(uint64 *)(pp + 32) +# asm 1: movq 32(a0=int64#3 +# asm 2: movq 32(a0=%rdx +movq 32(%rsi),%rdx + +# qhasm: a1 = *(uint64 *)(pp + 40) +# asm 1: movq 40(a1=int64#5 +# asm 2: movq 40(a1=%r8 +movq 40(%rsi),%r8 + +# qhasm: a2 = *(uint64 *)(pp + 48) +# asm 1: movq 48(a2=int64#6 +# asm 2: movq 48(a2=%r9 +movq 48(%rsi),%r9 + +# qhasm: a3 = *(uint64 *)(pp + 56) +# asm 1: movq 56(a3=int64#7 +# asm 2: movq 56(a3=%rax +movq 56(%rsi),%rax + +# qhasm: b0 = a0 +# asm 1: mov b0=int64#8 +# asm 2: mov b0=%r10 +mov %rdx,%r10 + +# qhasm: b1 = a1 +# asm 1: mov b1=int64#9 +# asm 2: mov b1=%r11 +mov %r8,%r11 + +# qhasm: b2 = a2 +# asm 1: mov b2=int64#10 +# asm 2: mov b2=%r12 +mov %r9,%r12 + +# qhasm: b3 = a3 +# asm 1: mov b3=int64#11 +# asm 2: mov b3=%r13 +mov %rax,%r13 + +# qhasm: carry? a0 -= *(uint64 *)(pp + 0) +# asm 1: subq 0(subt0=int64#12 +# asm 2: mov $0,>subt0=%r14 +mov $0,%r14 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#13 +# asm 2: mov $38,>subt1=%r15 +mov $38,%r15 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#12 +# asm 2: mov $0,>addt0=%r14 +mov $0,%r14 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#13 +# asm 2: mov $38,>addt1=%r15 +mov $38,%r15 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %rdx,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %r8,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r9,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %rax,80(%rsp) + +# qhasm: b0_stack = b0 +# asm 1: movq b0_stack=stack64#12 +# asm 2: movq b0_stack=88(%rsp) +movq %r10,88(%rsp) + +# qhasm: b1_stack = b1 +# asm 1: movq b1_stack=stack64#13 +# asm 2: movq b1_stack=96(%rsp) +movq %r11,96(%rsp) + +# qhasm: b2_stack = b2 +# asm 1: movq b2_stack=stack64#14 +# asm 2: movq b2_stack=104(%rsp) +movq %r12,104(%rsp) + +# qhasm: b3_stack = b3 +# asm 1: movq b3_stack=stack64#15 +# asm 2: movq b3_stack=112(%rsp) +movq %r13,112(%rsp) + +# qhasm: t10 = *(uint64 *)(qp + 32) +# asm 1: movq 32(t10=int64#3 +# asm 2: movq 32(t10=%rdx +movq 32(%rcx),%rdx + +# qhasm: t11 = *(uint64 *)(qp + 40) +# asm 1: movq 40(t11=int64#5 +# asm 2: movq 40(t11=%r8 +movq 40(%rcx),%r8 + +# qhasm: t12 = *(uint64 *)(qp + 48) +# asm 1: movq 48(t12=int64#6 +# asm 2: movq 48(t12=%r9 +movq 48(%rcx),%r9 + +# qhasm: t13 = *(uint64 *)(qp + 56) +# asm 1: movq 56(t13=int64#7 +# asm 2: movq 56(t13=%rax +movq 56(%rcx),%rax + +# qhasm: t20 = t10 +# asm 1: mov t20=int64#8 +# asm 2: mov t20=%r10 +mov %rdx,%r10 + +# qhasm: t21 = t11 +# asm 1: mov t21=int64#9 +# asm 2: mov t21=%r11 +mov %r8,%r11 + +# qhasm: t22 = t12 +# asm 1: mov t22=int64#10 +# asm 2: mov t22=%r12 +mov %r9,%r12 + +# qhasm: t23 = t13 +# asm 1: mov t23=int64#11 +# asm 2: mov t23=%r13 +mov %rax,%r13 + +# qhasm: carry? t10 -= *(uint64 *) (qp + 0) +# asm 1: subq 0(subt0=int64#12 +# asm 2: mov $0,>subt0=%r14 +mov $0,%r14 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#13 +# asm 2: mov $38,>subt1=%r15 +mov $38,%r15 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#12 +# asm 2: mov $0,>addt0=%r14 +mov $0,%r14 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#13 +# asm 2: mov $38,>addt1=%r15 +mov $38,%r15 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae t10_stack=stack64#16 +# asm 2: movq t10_stack=120(%rsp) +movq %rdx,120(%rsp) + +# qhasm: t11_stack = t11 +# asm 1: movq t11_stack=stack64#17 +# asm 2: movq t11_stack=128(%rsp) +movq %r8,128(%rsp) + +# qhasm: t12_stack = t12 +# asm 1: movq t12_stack=stack64#18 +# asm 2: movq t12_stack=136(%rsp) +movq %r9,136(%rsp) + +# qhasm: t13_stack = t13 +# asm 1: movq t13_stack=stack64#19 +# asm 2: movq t13_stack=144(%rsp) +movq %rax,144(%rsp) + +# qhasm: t20_stack = t20 +# asm 1: movq t20_stack=stack64#20 +# asm 2: movq t20_stack=152(%rsp) +movq %r10,152(%rsp) + +# qhasm: t21_stack = t21 +# asm 1: movq t21_stack=stack64#21 +# asm 2: movq t21_stack=160(%rsp) +movq %r11,160(%rsp) + +# qhasm: t22_stack = t22 +# asm 1: movq t22_stack=stack64#22 +# asm 2: movq t22_stack=168(%rsp) +movq %r12,168(%rsp) + +# qhasm: t23_stack = t23 +# asm 1: movq t23_stack=stack64#23 +# asm 2: movq t23_stack=176(%rsp) +movq %r13,176(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = a0_stack +# asm 1: movq mulx0=int64#10 +# asm 2: movq mulx0=%r12 +movq 56(%rsp),%r12 + +# qhasm: mulrax = t10_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 120(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a0=int64#11 +# asm 2: mov a0=%r13 +mov %rax,%r13 + +# qhasm: a1 = mulrdx +# asm 1: mov a1=int64#12 +# asm 2: mov a1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = t11_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 128(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a2=int64#13 +# asm 2: mov $0,>a2=%r15 +mov $0,%r15 + +# qhasm: a2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 136(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a3=int64#14 +# asm 2: mov $0,>a3=%rbx +mov $0,%rbx + +# qhasm: a3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 144(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq mulx1=%r12 +movq 64(%rsp),%r12 + +# qhasm: mulrax = t10_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 120(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 128(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 136(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 144(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq mulx2=%r12 +movq 72(%rsp),%r12 + +# qhasm: mulrax = t10_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 120(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 128(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 136(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 144(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq mulx3=%r12 +movq 80(%rsp),%r12 + +# qhasm: mulrax = t10_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 120(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 128(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 136(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 144(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? a0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: a0 += mulzero +# asm 1: add a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %r13,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %r14,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r15,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %rbx,80(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = b0_stack +# asm 1: movq mulx0=int64#10 +# asm 2: movq mulx0=%r12 +movq 88(%rsp),%r12 + +# qhasm: mulrax = t20_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx0=int64#11 +# asm 2: mov rx0=%r13 +mov %rax,%r13 + +# qhasm: rx1 = mulrdx +# asm 1: mov rx1=int64#12 +# asm 2: mov rx1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = t21_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx2=int64#13 +# asm 2: mov $0,>rx2=%r15 +mov $0,%r15 + +# qhasm: rx2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx3=int64#14 +# asm 2: mov $0,>rx3=%rbx +mov $0,%rbx + +# qhasm: rx3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq mulx1=%r12 +movq 96(%rsp),%r12 + +# qhasm: mulrax = t20_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq mulx2=%r12 +movq 104(%rsp),%r12 + +# qhasm: mulrax = t20_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq mulx3=%r12 +movq 112(%rsp),%r12 + +# qhasm: mulrax = t20_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? rx0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: rx0 += mulzero +# asm 1: add ry0=int64#3 +# asm 2: mov ry0=%rdx +mov %r13,%rdx + +# qhasm: ry1 = rx1 +# asm 1: mov ry1=int64#5 +# asm 2: mov ry1=%r8 +mov %r14,%r8 + +# qhasm: ry2 = rx2 +# asm 1: mov ry2=int64#6 +# asm 2: mov ry2=%r9 +mov %r15,%r9 + +# qhasm: ry3 = rx3 +# asm 1: mov ry3=int64#7 +# asm 2: mov ry3=%rax +mov %rbx,%rax + +# qhasm: carry? ry0 += a0_stack +# asm 1: addq addt0=int64#8 +# asm 2: mov $0,>addt0=%r10 +mov $0,%r10 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#9 +# asm 2: mov $38,>addt1=%r11 +mov $38,%r11 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae subt0=int64#8 +# asm 2: mov $0,>subt0=%r10 +mov $0,%r10 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#9 +# asm 2: mov $38,>subt1=%r11 +mov $38,%r11 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulx0=int64#10 +# asm 2: movq 96(mulx0=%r12 +movq 96(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c0=int64#11 +# asm 2: mov c0=%r13 +mov %rax,%r13 + +# qhasm: c1 = mulrdx +# asm 1: mov c1=int64#12 +# asm 2: mov c1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 104) +# asm 1: movq 104(mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c2=int64#13 +# asm 2: mov $0,>c2=%r15 +mov $0,%r15 + +# qhasm: c2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c3=int64#14 +# asm 2: mov $0,>c3=%rbx +mov $0,%rbx + +# qhasm: c3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq 104(mulx1=%r12 +movq 104(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq 112(mulx2=%r12 +movq 112(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq 120(mulx3=%r12 +movq 120(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? c0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: c0 += mulzero +# asm 1: add c0_stack=stack64#8 +# asm 2: movq c0_stack=56(%rsp) +movq %r13,56(%rsp) + +# qhasm: c1_stack = c1 +# asm 1: movq c1_stack=stack64#9 +# asm 2: movq c1_stack=64(%rsp) +movq %r14,64(%rsp) + +# qhasm: c2_stack = c2 +# asm 1: movq c2_stack=stack64#10 +# asm 2: movq c2_stack=72(%rsp) +movq %r15,72(%rsp) + +# qhasm: c3_stack = c3 +# asm 1: movq c3_stack=stack64#11 +# asm 2: movq c3_stack=80(%rsp) +movq %rbx,80(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = c0_stack +# asm 1: movq mulx0=int64#10 +# asm 2: movq mulx0=%r12 +movq 56(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D0 +# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D0(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c0=int64#11 +# asm 2: mov c0=%r13 +mov %rax,%r13 + +# qhasm: c1 = mulrdx +# asm 1: mov c1=int64#12 +# asm 2: mov c1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D1 +# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D1(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c2=int64#13 +# asm 2: mov $0,>c2=%r15 +mov $0,%r15 + +# qhasm: c2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D2,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D2(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c3=int64#14 +# asm 2: mov $0,>c3=%rbx +mov $0,%rbx + +# qhasm: c3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D3,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D3(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq mulx1=%r12 +movq 64(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D0 +# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D0(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D1(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D2,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D2(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D3,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D3(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq mulx2=%r12 +movq 72(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D0 +# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D0(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D1(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D2,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D2(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D3,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D3(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq mulx3=%r12 +movq 80(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D0 +# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D0(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D1(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D2,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D2(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D3,>mulrax=%rax +movq crypto_sign_ed25519_amd64_64_EC2D3(%rip),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? c0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: c0 += mulzero +# asm 1: add c0_stack=stack64#8 +# asm 2: movq c0_stack=56(%rsp) +movq %r13,56(%rsp) + +# qhasm: c1_stack = c1 +# asm 1: movq c1_stack=stack64#9 +# asm 2: movq c1_stack=64(%rsp) +movq %r14,64(%rsp) + +# qhasm: c2_stack = c2 +# asm 1: movq c2_stack=stack64#10 +# asm 2: movq c2_stack=72(%rsp) +movq %r15,72(%rsp) + +# qhasm: c3_stack = c3 +# asm 1: movq c3_stack=stack64#11 +# asm 2: movq c3_stack=80(%rsp) +movq %rbx,80(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = *(uint64 *)(pp + 64) +# asm 1: movq 64(mulx0=int64#10 +# asm 2: movq 64(mulx0=%r12 +movq 64(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt0=int64#11 +# asm 2: mov rt0=%r13 +mov %rax,%r13 + +# qhasm: rt1 = mulrdx +# asm 1: mov rt1=int64#12 +# asm 2: mov rt1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 72) +# asm 1: movq 72(mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt2=int64#13 +# asm 2: mov $0,>rt2=%r15 +mov $0,%r15 + +# qhasm: rt2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt3=int64#14 +# asm 2: mov $0,>rt3=%rbx +mov $0,%rbx + +# qhasm: rt3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq 72(mulx1=%r12 +movq 72(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq 80(mulx2=%r12 +movq 80(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#2 +# asm 2: movq 88(mulx3=%rsi +movq 88(%rsi),%rsi + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? rt0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: rt0 += mulzero +# asm 1: add addt0=int64#2 +# asm 2: mov $0,>addt0=%rsi +mov $0,%rsi + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#3 +# asm 2: mov $38,>addt1=%rdx +mov $38,%rdx + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae rz0=int64#2 +# asm 2: mov rz0=%rsi +mov %r13,%rsi + +# qhasm: rz1 = rt1 +# asm 1: mov rz1=int64#3 +# asm 2: mov rz1=%rdx +mov %r14,%rdx + +# qhasm: rz2 = rt2 +# asm 1: mov rz2=int64#4 +# asm 2: mov rz2=%rcx +mov %r15,%rcx + +# qhasm: rz3 = rt3 +# asm 1: mov rz3=int64#5 +# asm 2: mov rz3=%r8 +mov %rbx,%r8 + +# qhasm: carry? rz0 += c0_stack +# asm 1: addq addt0=int64#6 +# asm 2: mov $0,>addt0=%r9 +mov $0,%r9 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#7 +# asm 2: mov $38,>addt1=%rax +mov $38,%rax + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae subt0=int64#6 +# asm 2: mov $0,>subt0=%r9 +mov $0,%r9 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#7 +# asm 2: mov $38,>subt1=%rax +mov $38,%rax + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/ge25519_base.c b/ext/ed25519-amd64-asm/ge25519_base.c new file mode 100644 index 0000000..a7ae978 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_base.c @@ -0,0 +1,7 @@ +#include "ge25519.h" + +const ge25519 ge25519_base = {{{0xC9562D608F25D51A, 0x692CC7609525A7B2, 0xC0A4E231FDD6DC5C, 0x216936D3CD6E53FE}}, + {{0x6666666666666658, 0x6666666666666666, 0x6666666666666666, 0x6666666666666666}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 000000000000000000}}, + {{0x6DDE8AB3A5B7DDA3, 0x20F09F80775152F5, 0x66EA4E8E64ABE37D, 0x67875F0FD78B7665}}}; + diff --git a/ext/ed25519-amd64-asm/ge25519_base_niels.data b/ext/ed25519-amd64-asm/ge25519_base_niels.data new file mode 100644 index 0000000..8e3300c --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_base_niels.data @@ -0,0 +1,1536 @@ +{{{0x9d103905d740913e, 0xfd399f05d140beb3, 0xa5c18434688f8a09, 0x44fd2f9298f81267}}, + {{0x2fbc93c6f58c3b85, 0xcf932dc6fb8c0e19, 0x270b4898643d42c2, 0x07cf9d3a33d4ba65}}, + {{0xdbbd15674b6fbb59, 0x41e13f00eea2a5ea, 0xcdd49d1cc957c6fa, 0x4f0ebe1faf16ecca}}}, +{{{0x8a99a56042b4d5a8, 0x8f2b810c4e60acf6, 0xe09e236bb16e37aa, 0x6bb595a669c92555}}, + {{0x9224e7fc933c71d7, 0x9f469d967a0ff5b5, 0x5aa69a65e1d60702, 0x590c063fa87d2e2e}}, + {{0x6e347eaadad36802, 0xbaf3599383ee4805, 0x3bcabe10e6076826, 0x49314f0a165ed1b8}}}, +{{{0x56611fe8a4fcd265, 0x3bd353fde5c1ba7d, 0x8131f31a214bd6bd, 0x2ab91587555bda62}}, + {{0xaf25b0a84cee9730, 0x025a8430e8864b8a, 0xc11b50029f016732, 0x7a164e1b9a80f8f4}}, + {{0x9bf211f4f1674834, 0xb84e6b17f62df895, 0xd7de6f075b722a4e, 0x549a04b963bb2a21}}}, +{{{0x95fe050a056818bf, 0x327e89715660faa9, 0xc3e8e3cd06a05073, 0x27933f4c7445a49a}}, + {{0x287351b98efc099f, 0x6765c6f47dfd2538, 0xca348d3dfb0a9265, 0x680e910321e58727}}, + {{0xbf1e45ece51426b0, 0xe32bc63d6dba0f94, 0xe42974d58cf852c0, 0x44f079b1b0e64c18}}}, +{{{0x7f9182c3a447d6ba, 0xd50014d14b2729b7, 0xe33cf11cb864a087, 0x154a7e73eb1b55f3}}, + {{0xa212bc4408a5bb33, 0x8d5048c3c75eed02, 0xdd1beb0c5abfec44, 0x2945ccf146e206eb}}, + {{0xc832a179e7d003b3, 0x5f729d0a00124d7e, 0x62c1d4a10e6d8ff3, 0x68b8ac5938b27a98}}}, +{{{0x499806b67b7d8ca4, 0x575be28427d22739, 0xbb085ce7204553b9, 0x38b64c41ae417884}}, + {{0x3a0ceeeb77157131, 0x9b27158900c8af88, 0x8065b668da59a736, 0x51e57bb6a2cc38bd}}, + {{0x8f9dad91689de3a4, 0x175f2428f8fb9137, 0x050ab5329fcfb988, 0x7865dfa21354c09f}}}, +{{{0xba6f2c9aaa3221b1, 0x6ca021533bba23a7, 0x9dea764f92192c3a, 0x1d6edd5d2e5317e0}}, + {{0x6b1a5cd0944ea3bf, 0x7470353ab39dc0d2, 0x71b2528228542e49, 0x461bea69283c927e}}, + {{0x217a8aacab0fda36, 0xa528c6543d3549c8, 0x37d05b8b13ab7568, 0x233cef623a2cbc37}}}, +{{{0xe2a75dedf39234d9, 0x963d7680e1b558f9, 0x2c2741ac6e3c23fb, 0x3a9024a1320e01c3}}, + {{0x59b7596604dd3e8f, 0x6cb30377e288702c, 0xb1339c665ed9c323, 0x0915e76061bce52f}}, + {{0xdf7de835a834a37e, 0x8be19cda689857ea, 0x2c1185367167b326, 0x589eb3d9dbefd5c2}}}, +{{{0x7ec851ca553e2df3, 0xa71284cba64878b3, 0xe6b5e4193288d1e7, 0x4cf210ec5a9a8883}}, + {{0x322d04a52d9021f6, 0xb9c19f3375c6bf9c, 0x587a3a4342d20b09, 0x143b1cf8aa64fe61}}, + {{0x9f867c7d968acaab, 0x5f54258e27092729, 0xd0a7d34bea180975, 0x21b546a3374126e1}}}, +{{{0xa94ff858a2888343, 0xce0ed4565313ed3c, 0xf55c3dcfb5bf34fa, 0x0a653ca5c9eab371}}, + {{0x490a7a45d185218f, 0x9a15377846049335, 0x0060ea09cc31e1f6, 0x7e041577f86ee965}}, + {{0x66b2a496ce5b67f3, 0xff5492d8bd569796, 0x503cec294a592cd0, 0x566943650813acb2}}}, +{{{0xb818db0c26620798, 0x5d5c31d9606e354a, 0x0982fa4f00a8cdc7, 0x17e12bcd4653e2d4}}, + {{0x5672f9eb1dabb69d, 0xba70b535afe853fc, 0x47ac0f752796d66d, 0x32a5351794117275}}, + {{0xd3a644a6df648437, 0x703b6559880fbfdd, 0xcb852540ad3a1aa5, 0x0900b3f78e4c6468}}}, +{{{0x0a851b9f679d651b, 0xe108cb61033342f2, 0xd601f57fe88b30a3, 0x371f3acaed2dd714}}, + {{0xed280fbec816ad31, 0x52d9595bd8e6efe3, 0x0fe71772f6c623f5, 0x4314030b051e293c}}, + {{0xd560005efbf0bcad, 0x8eb70f2ed1870c5e, 0x201f9033d084e6a0, 0x4c3a5ae1ce7b6670}}}, +{{{0x4138a434dcb8fa95, 0x870cf67d6c96840b, 0xde388574297be82c, 0x7c814db27262a55a}}, + {{0xbaf875e4c93da0dd, 0xb93282a771b9294d, 0x80d63fb7f4c6c460, 0x6de9c73dea66c181}}, + {{0x478904d5a04df8f2, 0xfafbae4ab10142d3, 0xf6c8ac63555d0998, 0x5aac4a412f90b104}}}, +{{{0xc64f326b3ac92908, 0x5551b282e663e1e0, 0x476b35f54a1a4b83, 0x1b9da3fe189f68c2}}, + {{0x603a0d0abd7f5134, 0x8089c932e1d3ae46, 0xdf2591398798bd63, 0x1c145cd274ba0235}}, + {{0x32e8386475f3d743, 0x365b8baf6ae5d9ef, 0x825238b6385b681e, 0x234929c1167d65e1}}}, +{{{0x984decaba077ade8, 0x383f77ad19eb389d, 0xc7ec6b7e2954d794, 0x59c77b3aeb7c3a7a}}, + {{0x48145cc21d099fcf, 0x4535c192cc28d7e5, 0x80e7c1e548247e01, 0x4a5f28743b2973ee}}, + {{0xd3add725225ccf62, 0x911a3381b2152c5d, 0xd8b39fad5b08f87d, 0x6f05606b4799fe3b}}}, +{{{0x9ffe9e92177ba962, 0x98aee71d0de5cae1, 0x3ff4ae942d831044, 0x714de12e58533ac8}}, + {{0x5b433149f91b6483, 0xadb5dc655a2cbf62, 0x87fa8412632827b3, 0x60895e91ab49f8d8}}, + {{0xe9ecf2ed0cf86c18, 0xb46d06120735dfd4, 0xbc9da09804b96be7, 0x73e2e62fd96dc26b}}}, +{{{0xed5b635449aa515e, 0xa865c49f0bc6823a, 0x850c1fe95b42d1c4, 0x30d76d6f03d315b9}}, + {{0x2eccdd0e632f9c1d, 0x51d0b69676893115, 0x52dfb76ba8637a58, 0x6dd37d49a00eef39}}, + {{0x6c4444172106e4c7, 0xfb53d680928d7f69, 0xb4739ea4694d3f26, 0x10c697112e864bb0}}}, +{{{0x6493c4277dbe5fde, 0x265d4fad19ad7ea2, 0x0e00dfc846304590, 0x25e61cabed66fe09}}, + {{0x0ca62aa08358c805, 0x6a3d4ae37a204247, 0x7464d3a63b11eddc, 0x03bf9baf550806ef}}, + {{0x3f13e128cc586604, 0x6f5873ecb459747e, 0xa0b63dedcc1268f5, 0x566d78634586e22c}}}, +{{{0x1637a49f9cc10834, 0xbc8e56d5a89bc451, 0x1cb5ec0f7f7fd2db, 0x33975bca5ecc35d9}}, + {{0xa1054285c65a2fd0, 0x6c64112af31667c3, 0x680ae240731aee58, 0x14fba5f34793b22a}}, + {{0x3cd746166985f7d4, 0x593e5e84c9c80057, 0x2fc3f2b67b61131e, 0x14829cea83fc526c}}}, +{{{0xff437b8497dd95c2, 0x6c744e30aa4eb5a7, 0x9e0c5d613c85e88b, 0x2fd9c71e5f758173}}, + {{0x21e70b2f4e71ecb8, 0xe656ddb940a477e3, 0xbf6556cece1d4f80, 0x05fc3bc4535d7b7e}}, + {{0x24b8b3ae52afdedd, 0x3495638ced3b30cf, 0x33a4bc83a9be8195, 0x373767475c651f04}}}, +{{{0x2fba99fd40d1add9, 0xb307166f96f4d027, 0x4363f05215f03bae, 0x1fbea56c3b18f999}}, + {{0x634095cb14246590, 0xef12144016c15535, 0x9e38140c8910bc60, 0x6bf5905730907c8c}}, + {{0x0fa778f1e1415b8a, 0x06409ff7bac3a77e, 0x6f52d7b89aa29a50, 0x02521cf67a635a56}}}, +{{{0x513fee0b0a9d5294, 0x8f98e75c0fdf5a66, 0xd4618688bfe107ce, 0x3fa00a7e71382ced}}, + {{0xb1146720772f5ee4, 0xe8f894b196079ace, 0x4af8224d00ac824a, 0x001753d9f7cd6cc4}}, + {{0x3c69232d963ddb34, 0x1dde87dab4973858, 0xaad7d1f9a091f285, 0x12b5fe2fa048edb6}}}, +{{{0x71f0fbc496fce34d, 0x73b9826badf35bed, 0xd2047261ff28c561, 0x749b76f96fb1206f}}, + {{0xdf2b7c26ad6f1e92, 0x4b66d323504b8913, 0x8c409dc0751c8bc3, 0x6f7e93c20796c7b8}}, + {{0x1f5af604aea6ae05, 0xc12351f1bee49c99, 0x61a808b5eeff6b66, 0x0fcec10f01e02151}}}, +{{{0x644d58a649fe1e44, 0x21fcaea231ad777e, 0x02441c5a887fd0d2, 0x4901aa7183c511f3}}, + {{0x3df2d29dc4244e45, 0x2b020e7493d8de0a, 0x6cc8067e820c214d, 0x413779166feab90a}}, + {{0x08b1b7548c1af8f0, 0xce0f7a7c246299b4, 0xf760b0f91e06d939, 0x41bb887b726d1213}}}, +{{{0x9267806c567c49d8, 0x066d04ccca791e6a, 0xa69f5645e3cc394b, 0x5c95b686a0788cd2}}, + {{0x97d980e0aa39f7d2, 0x35d0384252c6b51c, 0x7d43f49307cd55aa, 0x56bd36cfb78ac362}}, + {{0x2ac519c10d14a954, 0xeaf474b494b5fa90, 0xe6af8382a9f87a5a, 0x0dea6db1879be094}}}, +{{{0xaa66bf547344e5ab, 0xda1258888f1b4309, 0x5e87d2b3fd564b2f, 0x5b2c78885483b1dd}}, + {{0x15baeb74d6a8797a, 0x7ef55cf1fac41732, 0x29001f5a3c8b05c5, 0x0ad7cc8752eaccfb}}, + {{0x52151362793408cf, 0xeb0f170319963d94, 0xa833b2fa883d9466, 0x093a7fa775003c78}}}, +{{{0xe5107de63a16d7be, 0xa377ffdc9af332cf, 0x70d5bf18440b677f, 0x6a252b19a4a31403}}, + {{0xb8e9604460a91286, 0x7f3fd8047778d3de, 0x67d01e31bf8a5e2d, 0x7b038a06c27b653e}}, + {{0x9ed919d5d36990f3, 0x5213aebbdb4eb9f2, 0xc708ea054cb99135, 0x58ded57f72260e56}}}, +{{{0x78e79dade9413d77, 0xf257f9d59729e67d, 0x59db910ee37aa7e6, 0x6aa11b5bbb9e039c}}, + {{0xda6d53265b0fd48b, 0x8960823193bfa988, 0xd78ac93261d57e28, 0x79f2942d3a5c8143}}, + {{0x97da2f25b6c88de9, 0x251ba7eaacf20169, 0x09b44f87ef4eb4e4, 0x7d90ab1bbc6a7da5}}}, +{{{0x9acca683a7016bfe, 0x90505f4df2c50b6d, 0x6b610d5fcce435aa, 0x19a10d446198ff96}}, + {{0x1a07a3f496b3c397, 0x11ceaa188f4e2532, 0x7d9498d5a7751bf0, 0x19ed161f508dd8a0}}, + {{0x560a2cd687dce6ca, 0x7f3568c48664cf4d, 0x8741e95222803a38, 0x483bdab1595653fc}}}, +{{{0xfa780f148734fa49, 0x106f0b70360534e0, 0x2210776fe3e307bd, 0x3286c109dde6a0fe}}, + {{0xd6cf4d0ab4da80f6, 0x82483e45f8307fe0, 0x05005269ae6f9da4, 0x1c7052909cf7877a}}, + {{0x32ee7de2874e98d4, 0x14c362e9b97e0c60, 0x5781dcde6a60a38a, 0x217dd5eaaa7aa840}}}, +{{{0x9db7c4d0248e1eb0, 0xe07697e14d74bf52, 0x1e6a9b173c562354, 0x7fa7c21f795a4965}}, + {{0x8bdf1fb9be8c0ec8, 0x00bae7f8e30a0282, 0x4963991dad6c4f6c, 0x07058a6e5df6f60a}}, + {{0xe9eb02c4db31f67f, 0xed25fd8910bcfb2b, 0x46c8131f5c5cddb4, 0x33b21c13a0cb9bce}}}, +{{{0x360692f8087d8e31, 0xf4dcc637d27163f7, 0x25a4e62065ea5963, 0x659bf72e5ac160d9}}, + {{0x9aafb9b05ee38c5b, 0xbf9d2d4e071a13c7, 0x8eee6e6de933290a, 0x1c3bab17ae109717}}, + {{0x1c9ab216c7cab7b0, 0x7d65d37407bbc3cc, 0x52744750504a58d5, 0x09f2606b131a2990}}}, +{{{0x40e87d44744346be, 0x1d48dad415b52b25, 0x7c3a8a18a13b603e, 0x4eb728c12fcdbdf7}}, + {{0x7e234c597c6691ae, 0x64889d3d0a85b4c8, 0xdae2c90c354afae7, 0x0a871e070c6a9e1d}}, + {{0x3301b5994bbc8989, 0x736bae3a5bdd4260, 0x0d61ade219d59e3c, 0x3ee7300f2685d464}}}, +{{{0xf5d255e49e7dd6b7, 0x8016115c610b1eac, 0x3c99975d92e187ca, 0x13815762979125c2}}, + {{0x43fa7947841e7518, 0xe5c6fa59639c46d7, 0xa1065e1de3052b74, 0x7d47c6a2cfb89030}}, + {{0x3fdad0148ef0d6e0, 0x9d3e749a91546f3c, 0x71ec621026bb8157, 0x148cf58d34c9ec80}}}, +{{{0x46a492f67934f027, 0x469984bef6840aa9, 0x5ca1bc2a89611854, 0x3ff2fa1ebd5dbbd4}}, + {{0xe2572f7d9ae4756d, 0x56c345bb88f3487f, 0x9fd10b6d6960a88d, 0x278febad4eaea1b9}}, + {{0xb1aa681f8c933966, 0x8c21949c20290c98, 0x39115291219d3c52, 0x4104dd02fe9c677b}}}, +{{{0x72b2bf5e1124422a, 0xa1fa0c3398a33ab5, 0x94cb6101fa52b666, 0x2c863b00afaf53d5}}, + {{0x81214e06db096ab8, 0x21a8b6c90ce44f35, 0x6524c12a409e2af5, 0x0165b5a48efca481}}, + {{0xf190a474a0846a76, 0x12eff984cd2f7cc0, 0x695e290658aa2b8f, 0x591b67d9bffec8b8}}}, +{{{0x312f0d1c80b49bfa, 0x5979515eabf3ec8a, 0x727033c09ef01c88, 0x3de02ec7ca8f7bcb}}, + {{0x99b9b3719f18b55d, 0xe465e5faa18c641e, 0x61081136c29f05ed, 0x489b4f867030128b}}, + {{0xd232102d3aeb92ef, 0xe16253b46116a861, 0x3d7eabe7190baa24, 0x49f5fbba496cbebf}}}, +{{{0x30949a108a5bcfd4, 0xdc40dd70bc6473eb, 0x92c294c1307c0d1c, 0x5604a86dcbfa6e74}}, + {{0x155d628c1e9c572e, 0x8a4d86acc5884741, 0x91a352f6515763eb, 0x06a1a6c28867515b}}, + {{0x7288d1d47c1764b6, 0x72541140e0418b51, 0x9f031a6018acf6d1, 0x20989e89fe2742c6}}}, +{{{0x499777fd3a2dcc7f, 0x32857c2ca54fd892, 0xa279d864d207e3a0, 0x0403ed1d0ca67e29}}, + {{0x1674278b85eaec2e, 0x5621dc077acb2bdf, 0x640a4c1661cbf45a, 0x730b9950f70595d3}}, + {{0xc94b2d35874ec552, 0xc5e6c8cf98246f8d, 0xf7cb46fa16c035ce, 0x5bd7454308303dcc}}}, +{{{0x7f9ad19528b24cc2, 0x7f6b54656335c181, 0x66b8b66e4fc07236, 0x133a78007380ad83}}, + {{0x85c4932115e7792a, 0xc64c89a2bdcdddc9, 0x9d1e3da8ada3d762, 0x5bb7db123067f82c}}, + {{0x0961f467c6ca62be, 0x04ec21d6211952ee, 0x182360779bd54770, 0x740dca6d58f0e0d2}}}, +{{{0x50b70bf5d3f0af0b, 0x4feaf48ae32e71f7, 0x60e84ed3a55bbd34, 0x00ed489b3f50d1ed}}, + {{0x3906c72aed261ae5, 0x9ab68fd988e100f7, 0xf5e9059af3360197, 0x0e53dc78bf2b6d47}}, + {{0xb90829bf7971877a, 0x5e4444636d17e631, 0x4d05c52e18276893, 0x27632d9a5a4a4af5}}}, +{{{0xd11ff05154b260ce, 0xd86dc38e72f95270, 0x601fcd0d267cc138, 0x2b67916429e90ccd}}, + {{0xa98285d187eaffdb, 0xa5b4fbbbd8d0a864, 0xb658f27f022663f7, 0x3bbc2b22d99ce282}}, + {{0xb917c952583c0a58, 0x653ff9b80fe4c6f3, 0x9b0da7d7bcdf3c0c, 0x43a0eeb6ab54d60e}}}, +{{{0x396966a46d4a5487, 0xf811a18aac2bb3ba, 0x66e4685b5628b26b, 0x70a477029d929b92}}, + {{0x3ac6322357875fe8, 0xd9d4f4ecf5fbcb8f, 0x8dee8493382bb620, 0x50c5eaa14c799fdc}}, + {{0xdd0edc8bd6f2fb3c, 0x54c63aa79cc7b7a0, 0xae0b032b2c8d9f1a, 0x6f9ce107602967fb}}}, +{{{0xad1054b1cde1c22a, 0xc4a8e90248eb32df, 0x5f3e7b33accdc0ea, 0x72364713fc79963e}}, + {{0x139693063520e0b5, 0x437fcf7c88ea03fe, 0xf7d4c40bd3c959bc, 0x699154d1f893ded9}}, + {{0x315d5c75b4b27526, 0xcccb842d0236daa5, 0x22f0c8a3345fee8e, 0x73975a617d39dbed}}}, +{{{0xe4024df96375da10, 0x78d3251a1830c870, 0x902b1948658cd91c, 0x7e18b10b29b7438a}}, + {{0x6f37f392f4433e46, 0x0e19b9a11f566b18, 0x220fb78a1fd1d662, 0x362a4258a381c94d}}, + {{0x9071d9132b6beb2f, 0x0f26e9ad28418247, 0xeab91ec9bdec925d, 0x4be65bc8f48af2de}}}, +{{{0x78487feba36e7028, 0x5f3f13001dd8ce34, 0x934fb12d4b30c489, 0x056c244d397f0a2b}}, + {{0x1d50fba257c26234, 0x7bd4823adeb0678b, 0xc2b0dc6ea6538af5, 0x5665eec6351da73e}}, + {{0xdb3ee00943bfb210, 0x4972018720800ac2, 0x26ab5d6173bd8667, 0x20b209c2ab204938}}}, +{{{0x549e342ac07fb34b, 0x02d8220821373d93, 0xbc262d70acd1f567, 0x7a92c9fdfbcac784}}, + {{0x1fcca94516bd3289, 0x448d65aa41420428, 0x59c3b7b216a55d62, 0x49992cc64e612cd8}}, + {{0x65bd1bea70f801de, 0x1befb7c0fe49e28a, 0xa86306cdb1b2ae4a, 0x3b7ac0cd265c2a09}}}, +{{{0x822bee438c01bcec, 0x530cb525c0fbc73b, 0x48519034c1953fe9, 0x265cc261e09a0f5b}}, + {{0xf0d54e4f22ed39a7, 0xa2aae91e5608150a, 0xf421b2e9eddae875, 0x31bc531d6b7de992}}, + {{0xdf3d134da980f971, 0x7a4fb8d1221a22a7, 0x3df7d42035aad6d8, 0x2a14edcc6a1a125e}}}, +{{{0xdf48ee0752cfce4e, 0xc3fffaf306ec08b7, 0x05710b2ab95459c4, 0x161d25fa963ea38d}}, + {{0x231a8c570478433c, 0xb7b5270ec281439d, 0xdbaa99eae3d9079f, 0x2c03f5256c2b03d9}}, + {{0x790f18757b53a47d, 0x307b0130cf0c5879, 0x31903d77257ef7f9, 0x699468bdbd96bbaf}}}, +{{{0xbd1f2f46f4dafecf, 0x7cef0114a47fd6f7, 0xd31ffdda4a47b37f, 0x525219a473905785}}, + {{0xd8dd3de66aa91948, 0x485064c22fc0d2cc, 0x9b48246634fdea2f, 0x293e1c4e6c4a2e3a}}, + {{0x376e134b925112e1, 0x703778b5dca15da0, 0xb04589af461c3111, 0x5b605c447f032823}}}, +{{{0xb965805920c47c89, 0xe7f0100c923b8fcc, 0x0001256502e2ef77, 0x24a76dcea8aeb3ee}}, + {{0x3be9fec6f0e7f04c, 0x866a579e75e34962, 0x5542ef161e1de61a, 0x2f12fef4cc5abdd5}}, + {{0x0a4522b2dfc0c740, 0x10d06e7f40c9a407, 0xc6cf144178cff668, 0x5e607b2518a43790}}}, +{{{0x58b31d8f6cdf1818, 0x35cfa74fc36258a2, 0xe1b3ff4f66e61d6e, 0x5067acab6ccdd5f7}}, + {{0xa02c431ca596cf14, 0xe3c42d40aed3e400, 0xd24526802e0f26db, 0x201f33139e457068}}, + {{0xfd527f6b08039d51, 0x18b14964017c0006, 0xd5220eb02e25a4a8, 0x397cba8862460375}}}, +{{{0x30c13093f05959b2, 0xe23aa18de9a97976, 0x222fd491721d5e26, 0x2339d320766e6c3a}}, + {{0x7815c3fbc81379e7, 0xa6619420dde12af1, 0xffa9c0f885a8fdd5, 0x771b4022c1e1c252}}, + {{0xd87dd986513a2fa7, 0xf5ac9b71f9d4cf08, 0xd06bc31b1ea283b3, 0x331a189219971a76}}}, +{{{0xf5166f45fb4f80c6, 0x9c36c7de61c775cf, 0xe3d4e81b9041d91c, 0x31167c6b83bdfe21}}, + {{0x26512f3a9d7572af, 0x5bcbe28868074a9e, 0x84edc1c11180f7c4, 0x1ac9619ff649a67b}}, + {{0xf22b3842524b1068, 0x5068343bee9ce987, 0xfc9d71844a6250c8, 0x612436341f08b111}}}, +{{{0xd99d41db874e898d, 0x09fea5f16c07dc20, 0x793d2c67d00f9bbc, 0x46ebe2309e5eff40}}, + {{0x8b6349e31a2d2638, 0x9ddfb7009bd3fd35, 0x7f8bf1b8a3a06ba4, 0x1522aa3178d90445}}, + {{0x2c382f5369614938, 0xdafe409ab72d6d10, 0xe8c83391b646f227, 0x45fe70f50524306c}}}, +{{{0xda4875a6960c0b8c, 0x5b68d076ef0e2f20, 0x07fb51cf3d0b8fd4, 0x428d1623a0e392d4}}, + {{0x62f24920c8951491, 0x05f007c83f630ca2, 0x6fbb45d2f5c9d4b8, 0x16619f6db57a2245}}, + {{0x084f4a4401a308fd, 0xa82219c376a5caac, 0xdeb8de4643d1bc7d, 0x1d81592d60bd38c6}}}, +{{{0xd833d7beec2a4c38, 0x2c9162830acc20ed, 0xe93a47aa92df7581, 0x702d67a3333c4a81}}, + {{0x3a4a369a2f89c8a1, 0x63137a1d7c8de80d, 0xbcac008a78eda015, 0x2cb8b3a5b483b03f}}, + {{0x36e417cbcb1b90a1, 0x33b3ddaa7f11794e, 0x3f510808885bc607, 0x24141dc0e6a8020d}}}, +{{{0x59f73c773fefee9d, 0xb3f1ef89c1cf989d, 0xe35dfb42e02e545f, 0x5766120b47a1b47c}}, + {{0x91925dccbd83157d, 0x3ca1205322cc8094, 0x28e57f183f90d6e4, 0x1a4714cede2e767b}}, + {{0xdb20ba0fb8b6b7ff, 0xb732c3b677511fa1, 0xa92b51c099f02d89, 0x4f3875ad489ca5f1}}}, +{{{0xc7fc762f4932ab22, 0x7ac0edf72f4c3c1b, 0x5f6b55aa9aa895e8, 0x3680274dad0a0081}}, + {{0x79ed13f6ee73eec0, 0xa5c6526d69110bb1, 0xe48928c38603860c, 0x722a1446fd7059f5}}, + {{0xd0959fe9a8cf8819, 0xd0a995508475a99c, 0x6eac173320b09cc5, 0x628ecf04331b1095}}}, +{{{0x98bcb118a9d0ddbc, 0xee449e3408b4802b, 0x87089226b8a6b104, 0x685f349a45c7915d}}, + {{0x9b41acf85c74ccf1, 0xb673318108265251, 0x99c92aed11adb147, 0x7a47d70d34ecb40f}}, + {{0x60a0c4cbcc43a4f5, 0x775c66ca3677bea9, 0xa17aa1752ff8f5ed, 0x11ded9020e01fdc0}}}, +{{{0x890e7809caefe704, 0x8728296de30e8c6c, 0x4c5cd2a392aeb1c9, 0x194263d15771531f}}, + {{0x471f95b03bea93b7, 0x0552d7d43313abd3, 0xbd9370e2e17e3f7b, 0x7b120f1db20e5bec}}, + {{0x17d2fb3d86502d7a, 0xb564d84450a69352, 0x7da962c8a60ed75d, 0x00d0f85b318736aa}}}, +{{{0x978b142e777c84fd, 0xf402644705a8c062, 0xa67ad51be7e612c7, 0x2f7b459698dd6a33}}, + {{0xa6753c1efd7621c1, 0x69c0b4a7445671f5, 0x971f527405b23c11, 0x387bc74851a8c7cd}}, + {{0x81894b4d4a52a9a8, 0xadd93e12f6b8832f, 0x184d8548b61bd638, 0x3f1c62dbd6c9f6cd}}}, +{{{0x2e8f1f0091910c1f, 0xa4df4fe0bff2e12c, 0x60c6560aee927438, 0x6338283facefc8fa}}, + {{0x3fad3e40148f693d, 0x052656e194eb9a72, 0x2f4dcbfd184f4e2f, 0x406f8db1c482e18b}}, + {{0x9e630d2c7f191ee4, 0x4fbf8301bc3ff670, 0x787d8e4e7afb73c4, 0x50d83d5be8f58fa5}}}, +{{{0x85683916c11a1897, 0x2d69a4efe506d008, 0x39af1378f664bd01, 0x65942131361517c6}}, + {{0xc0accf90b4d3b66d, 0xa7059de561732e60, 0x033d1f7870c6b0ba, 0x584161cd26d946e4}}, + {{0xbbf2b1a072d27ca2, 0xbf393c59fbdec704, 0xe98dbbcee262b81e, 0x02eebd0b3029b589}}}, +{{{0x61368756a60dac5f, 0x17e02f6aebabdc57, 0x7f193f2d4cce0f7d, 0x20234a7789ecdcf0}}, + {{0x8765b69f7b85c5e8, 0x6ff0678bd168bab2, 0x3a70e77c1d330f9b, 0x3a5f6d51b0af8e7c}}, + {{0x76d20db67178b252, 0x071c34f9d51ed160, 0xf62a4a20b3e41170, 0x7cd682353cffe366}}}, +{{{0x0be1a45bd887fab6, 0x2a846a32ba403b6e, 0xd9921012e96e6000, 0x2838c8863bdc0943}}, + {{0xa665cd6068acf4f3, 0x42d92d183cd7e3d3, 0x5759389d336025d9, 0x3ef0253b2b2cd8ff}}, + {{0xd16bb0cf4a465030, 0xfa496b4115c577ab, 0x82cfae8af4ab419d, 0x21dcb8a606a82812}}}, +{{{0x5c6004468c9d9fc8, 0x2540096ed42aa3cb, 0x125b4d4c12ee2f9c, 0x0bc3d08194a31dab}}, + {{0x9a8d00fabe7731ba, 0x8203607e629e1889, 0xb2cc023743f3d97f, 0x5d840dbf6c6f678b}}, + {{0x706e380d309fe18b, 0x6eb02da6b9e165c7, 0x57bbba997dae20ab, 0x3a4276232ac196dd}}}, +{{{0x4b42432c8a7084fa, 0x898a19e3dfb9e545, 0xbe9f00219c58e45d, 0x1ff177cea16debd1}}, + {{0x3bf8c172db447ecb, 0x5fcfc41fc6282dbd, 0x80acffc075aa15fe, 0x0770c9e824e1a9f9}}, + {{0xcf61d99a45b5b5fd, 0x860984e91b3a7924, 0xe7300919303e3e89, 0x39f264fd41500b1e}}}, +{{{0xa7ad3417dbe7e29c, 0xbd94376a2b9c139c, 0xa0e91b8e93597ba9, 0x1712d73468889840}}, + {{0xd19b4aabfe097be1, 0xa46dfce1dfe01929, 0xc3c908942ca6f1ff, 0x65c621272c35f14e}}, + {{0xe72b89f8ce3193dd, 0x4d103356a125c0bb, 0x0419a93d2e1cfe83, 0x22f9800ab19ce272}}}, +{{{0x605a368a3e9ef8cb, 0xe3e9c022a5504715, 0x553d48b05f24248f, 0x13f416cd647626e5}}, + {{0x42029fdd9a6efdac, 0xb912cebe34a54941, 0x640f64b987bdf37b, 0x4171a4d38598cab4}}, + {{0xfa2758aa99c94c8c, 0x23006f6fb000b807, 0xfbd291ddadda5392, 0x508214fa574bd1ab}}}, +{{{0xc20269153ed6fe4b, 0xa65a6739511d77c4, 0xcbde26462c14af94, 0x22f960ec6faba74b}}, + {{0x461a15bb53d003d6, 0xb2102888bcf3c965, 0x27c576756c683a5a, 0x3a7758a4c86cb447}}, + {{0x548111f693ae5076, 0x1dae21df1dfd54a6, 0x12248c90f3115e65, 0x5d9fd15f8de7f494}}}, +{{{0x031408d36d63727f, 0x6a379aefd7c7b533, 0xa9e18fc5ccaee24b, 0x332f35914f8fbed3}}, + {{0x3f244d2aeed7521e, 0x8e3a9028432e9615, 0xe164ba772e9c16d4, 0x3bc187fa47eb98d8}}, + {{0x6d470115ea86c20c, 0x998ab7cb6c46d125, 0xd77832b53a660188, 0x450d81ce906fba03}}}, +{{{0xf8ae4d2ad8453902, 0x7018058ee8db2d1d, 0xaab3995fc7d2c11e, 0x53b16d2324ccca79}}, + {{0x23264d66b2cae0b5, 0x7dbaed33ebca6576, 0x030ebed6f0d24ac8, 0x2a887f78f7635510}}, + {{0x2a23b9e75c012d4f, 0x0c974651cae1f2ea, 0x2fb63273675d70ca, 0x0ba7250b864403f5}}}, +{{{0xbb0d18fd029c6421, 0xbc2d142189298f02, 0x8347f8e68b250e96, 0x7b9f2fe8032d71c9}}, + {{0xdd63589386f86d9c, 0x61699176e13a85a4, 0x2e5111954eaa7d57, 0x32c21b57fb60bdfb}}, + {{0xd87823cd319e0780, 0xefc4cfc1897775c5, 0x4854fb129a0ab3f7, 0x12c49d417238c371}}}, +{{{0x0950b533ffe83769, 0x21861c1d8e1d6bd1, 0xf022d8381302e510, 0x2509200c6391cab4}}, + {{0x09b3a01783799542, 0x626dd08faad5ee3f, 0xba00bceeeb70149f, 0x1421b246a0a444c9}}, + {{0x4aa43a8e8c24a7c7, 0x04c1f540d8f05ef5, 0xadba5e0c0b3eb9dc, 0x2ab5504448a49ce3}}}, +{{{0x2ed227266f0f5dec, 0x9824ee415ed50824, 0x807bec7c9468d415, 0x7093bae1b521e23f}}, + {{0xdc07ac631c5d3afa, 0x58615171f9df8c6c, 0x72a079d89d73e2b0, 0x7301f4ceb4eae15d}}, + {{0x6409e759d6722c41, 0xa674e1cf72bf729b, 0xbc0a24eb3c21e569, 0x390167d24ebacb23}}}, +{{{0x27f58e3bba353f1c, 0x4c47764dbf6a4361, 0xafbbc4e56e562650, 0x07db2ee6aae1a45d}}, + {{0xd7bb054ba2f2120b, 0xe2b9ceaeb10589b7, 0x3fe8bac8f3c0edbe, 0x4cbd40767112cb69}}, + {{0x0b603cc029c58176, 0x5988e3825cb15d61, 0x2bb61413dcf0ad8d, 0x7b8eec6c74183287}}}, +{{{0xe4ca40782cd27cb0, 0xdaf9c323fbe967bd, 0xb29bd34a8ad41e9e, 0x72810497626ede4d}}, + {{0x32fee570fc386b73, 0xda8b0141da3a8cc7, 0x975ffd0ac8968359, 0x6ee809a1b132a855}}, + {{0x9444bb31fcfd863a, 0x2fe3690a3e4e48c5, 0xdc29c867d088fa25, 0x13bd1e38d173292e}}}, +{{{0xd32b4cd8696149b5, 0xe55937d781d8aab7, 0x0bcb2127ae122b94, 0x41e86fcfb14099b0}}, + {{0x223fb5cf1dfac521, 0x325c25316f554450, 0x030b98d7659177ac, 0x1ed018b64f88a4bd}}, + {{0x3630dfa1b802a6b0, 0x880f874742ad3bd5, 0x0af90d6ceec5a4d4, 0x746a247a37cdc5d9}}}, +{{{0xd531b8bd2b7b9af6, 0x5005093537fc5b51, 0x232fcf25c593546d, 0x20a365142bb40f49}}, + {{0x6eccd85278d941ed, 0x2254ae83d22f7843, 0xc522d02e7bbfcdb7, 0x681e3351bff0e4e2}}, + {{0x8b64b59d83034f45, 0x2f8b71f21fa20efb, 0x69249495ba6550e4, 0x539ef98e45d5472b}}}, +{{{0x6e7bb6a1a6205275, 0xaa4f21d7413c8e83, 0x6f56d155e88f5cb2, 0x2de25d4ba6345be1}}, + {{0xd074d8961cae743f, 0xf86d18f5ee1c63ed, 0x97bdc55be7f4ed29, 0x4cbad279663ab108}}, + {{0x80d19024a0d71fcd, 0xc525c20afb288af8, 0xb1a3974b5f3a6419, 0x7d7fbcefe2007233}}}, +{{{0xfaef1e6a266b2801, 0x866c68c4d5739f16, 0xf68a2fbc1b03762c, 0x5975435e87b75a8d}}, + {{0xcd7c5dc5f3c29094, 0xc781a29a2a9105ab, 0x80c61d36421c3058, 0x4f9cd196dcd8d4d7}}, + {{0x199297d86a7b3768, 0xd0d058241ad17a63, 0xba029cad5c1c0c17, 0x7ccdd084387a0307}}}, +{{{0xdca6422c6d260417, 0xae153d50948240bd, 0xa9c0c1b4fb68c677, 0x428bd0ed61d0cf53}}, + {{0x9b0c84186760cc93, 0xcdae007a1ab32a99, 0xa88dec86620bda18, 0x3593ca848190ca44}}, + {{0x9213189a5e849aa7, 0xd4d8c33565d8facd, 0x8c52545b53fdbbd1, 0x27398308da2d63e6}}}, +{{{0x42c38d28435ed413, 0xbd50f3603278ccc9, 0xbb07ab1a79da03ef, 0x269597aebe8c3355}}, + {{0xb9a10e4c0a702453, 0x0fa25866d57d1bde, 0xffb9d9b5cd27daf7, 0x572c2945492c33fd}}, + {{0xc77fc745d6cd30be, 0xe4dfe8d3e3baaefb, 0xa22c8830aa5dda0c, 0x7f985498c05bca80}}}, +{{{0x3849ce889f0be117, 0x8005ad1b7b54a288, 0x3da3c39f23fc921c, 0x76c2ec470a31f304}}, + {{0xd35615520fbf6363, 0x08045a45cf4dfba6, 0xeec24fbc873fa0c2, 0x30f2653cd69b12e7}}, + {{0x8a08c938aac10c85, 0x46179b60db276bcb, 0xa920c01e0e6fac70, 0x2f1273f1596473da}}}, +{{{0x4739fc7c8ae01e11, 0xfd5274904a6aab9f, 0x41d98a8287728f2e, 0x5d9e572ad85b69f2}}, + {{0x30488bd755a70bc0, 0x06d6b5a4f1d442e7, 0xead1a69ebc596162, 0x38ac1997edc5f784}}, + {{0x0666b517a751b13b, 0x747d06867e9b858c, 0xacacc011454dde49, 0x22dfcd9cbfe9e69c}}}, +{{{0x8ddbd2e0c30d0cd9, 0xad8e665facbb4333, 0x8f6b258c322a961f, 0x6b2916c05448c1c7}}, + {{0x56ec59b4103be0a1, 0x2ee3baecd259f969, 0x797cb29413f5cd32, 0x0fe9877824cde472}}, + {{0x7edb34d10aba913b, 0x4ea3cd822e6dac0e, 0x66083dff6578f815, 0x4c303f307ff00a17}}}, +{{{0xd30a3bd617b28c85, 0xc5d377b739773bea, 0xc6c6e78c1e6a5cbf, 0x0d61b8f78b2ab7c4}}, + {{0x29fc03580dd94500, 0xecd27aa46fbbec93, 0x130a155fc2e2a7f8, 0x416b151ab706a1d5}}, + {{0x56a8d7efe9c136b0, 0xbd07e5cd58e44b20, 0xafe62fda1b57e0ab, 0x191a2af74277e8d2}}}, +{{{0xd550095bab6f4985, 0x04f4cd5b4fbfaf1a, 0x9d8e2ed12a0c7540, 0x2bc24e04b2212286}}, + {{0x09d4b60b2fe09a14, 0xc384f0afdbb1747e, 0x58e2ea8978b5fd6e, 0x519ef577b5e09b0a}}, + {{0x1863d7d91124cca9, 0x7ac08145b88a708e, 0x2bcd7309857031f5, 0x62337a6e8ab8fae5}}}, +{{{0x4bcef17f06ffca16, 0xde06e1db692ae16a, 0x0753702d614f42b0, 0x5f6041b45b9212d0}}, + {{0xd1ab324e1b3a1273, 0x18947cf181055340, 0x3b5d9567a98c196e, 0x7fa00425802e1e68}}, + {{0x7d531574028c2705, 0x80317d69db0d75fe, 0x30fface8ef8c8ddd, 0x7e9de97bb6c3e998}}}, +{{{0x1558967b9e6585a3, 0x97c99ce098e98b92, 0x10af149b6eb3adad, 0x42181fe8f4d38cfa}}, + {{0xf004be62a24d40dd, 0xba0659910452d41f, 0x81c45ee162a44234, 0x4cb829d8a22266ef}}, + {{0x1dbcaa8407b86681, 0x081f001e8b26753b, 0x3cd7ce6a84048e81, 0x78af11633f25f22c}}}, +{{{0x8416ebd40b50babc, 0x1508722628208bee, 0xa3148fafb9c1c36d, 0x0d07daacd32d7d5d}}, + {{0x3241c00e7d65318c, 0xe6bee5dcd0e86de7, 0x118b2dc2fbc08c26, 0x680d04a7fc603dc3}}, + {{0xf9c2414a695aa3eb, 0xdaa42c4c05a68f21, 0x7c6c23987f93963e, 0x210e8cd30c3954e3}}}, +{{{0xac4201f210a71c06, 0x6a65e0aef3bfb021, 0xbc42c35c393632f7, 0x56ea8db1865f0742}}, + {{0x2b50f16137fe6c26, 0xe102bcd856e404d8, 0x12b0f1414c561f6b, 0x51b17bc8d028ec91}}, + {{0xfff5fb4bcf535119, 0xf4989d79df1108a0, 0xbdfcea659a3ba325, 0x18a11f1174d1a6f2}}}, +{{{0x407375ab3f6bba29, 0x9ec3b6d8991e482e, 0x99c80e82e55f92e9, 0x307c13b6fb0c0ae1}}, + {{0xfbd63cdad27a5f2c, 0xf00fc4bc8aa106d7, 0x53fb5c1a8e64a430, 0x04eaabe50c1a2e85}}, + {{0x24751021cb8ab5e7, 0xfc2344495c5010eb, 0x5f1e717b4e5610a1, 0x44da5f18c2710cd5}}}, +{{{0x033cc55ff1b82eb5, 0xb15ae36d411cae52, 0xba40b6198ffbacd3, 0x768edce1532e861f}}, + {{0x9156fe6b89d8eacc, 0xe6b79451e23126a1, 0xbd7463d93944eb4e, 0x726373f6767203ae}}, + {{0xe305ca72eb7ef68a, 0x662cf31f70eadb23, 0x18f026fdb4c45b68, 0x513b5384b5d2ecbd}}}, +{{{0x46d46280c729989e, 0x4b93fbd05368a5dd, 0x63df3f81d1765a89, 0x34cebd64b9a0a223}}, + {{0x5e2702878af34ceb, 0x900b0409b946d6ae, 0x6512ebf7dabd8512, 0x61d9b76988258f81}}, + {{0xa6c5a71349b7d94b, 0xa3f3d15823eb9446, 0x0416fbd277484834, 0x69d45e6f2c70812f}}}, +{{{0xce16f74bc53c1431, 0x2b9725ce2072edde, 0xb8b9c36fb5b23ee7, 0x7e2e0e450b5cc908}}, + {{0x9fe62b434f460efb, 0xded303d4a63607d6, 0xf052210eb7a0da24, 0x237e7dbe00545b93}}, + {{0x013575ed6701b430, 0x231094e69f0bfd10, 0x75320f1583e47f22, 0x71afa699b11155e3}}}, +{{{0x65ce6f9b3953b61d, 0xc65839eaafa141e6, 0x0f435ffda9f759fe, 0x021142e9c2b1c28e}}, + {{0xea423c1c473b50d6, 0x51e87a1f3b38ef10, 0x9b84bf5fb2c9be95, 0x00731fbc78f89a1c}}, + {{0xe430c71848f81880, 0xbf960c225ecec119, 0xb6dae0836bba15e3, 0x4c4d6f3347e15808}}}, +{{{0x18f7eccfc17d1fc9, 0x6c75f5a651403c14, 0xdbde712bf7ee0cdf, 0x193fddaaa7e47a22}}, + {{0x2f0cddfc988f1970, 0x6b916227b0b9f51b, 0x6ec7b6c4779176be, 0x38bf9500a88f9fa8}}, + {{0x1fd2c93c37e8876f, 0xa2f61e5a18d1462c, 0x5080f58239241276, 0x6a6fb99ebf0d4969}}}, +{{{0x6a46c1bb560855eb, 0x2416bb38f893f09d, 0xd71d11378f71acc1, 0x75f76914a31896ea}}, + {{0xeeb122b5b6e423c6, 0x939d7010f286ff8e, 0x90a92a831dcf5d8c, 0x136fda9f42c5eb10}}, + {{0xf94cdfb1a305bdd1, 0x0f364b9d9ff82c08, 0x2a87d8a5c3bb588a, 0x022183510be8dcba}}}, +{{{0x4af766385ead2d14, 0xa08ed880ca7c5830, 0x0d13a6e610211e3d, 0x6a071ce17b806c03}}, + {{0x9d5a710143307a7f, 0xb063de9ec47da45f, 0x22bbfe52be927ad3, 0x1387c441fd40426c}}, + {{0xb5d3c3d187978af8, 0x722b5a3d7f0e4413, 0x0d7b4848bb477ca0, 0x3171b26aaf1edc92}}}, +{{{0xa92f319097564ca8, 0xff7bb84c2275e119, 0x4f55fe37a4875150, 0x221fd4873cf0835a}}, + {{0xa60db7d8b28a47d1, 0xa6bf14d61770a4f1, 0xd4a1f89353ddbd58, 0x6c514a63344243e9}}, + {{0x2322204f3a156341, 0xfb73e0e9ba0a032d, 0xfce0dd4c410f030e, 0x48daa596fb924aaa}}}, +{{{0x6eca8e665ca59cc7, 0xa847254b2e38aca0, 0x31afc708d21e17ce, 0x676dd6fccad84af7}}, + {{0x14f61d5dc84c9793, 0x9941f9e3ef418206, 0xcdf5b88f346277ac, 0x58c837fa0e8a79a9}}, + {{0x0cf9688596fc9058, 0x1ddcbbf37b56a01b, 0xdcc2e77d4935d66a, 0x1c4f73f2c6a57f0a}}}, +{{{0x0e7a4fbd305fa0bb, 0x829d4ce054c663ad, 0xf421c3832fe33848, 0x795ac80d1bf64c42}}, + {{0xb36e706efc7c3484, 0x73dfc9b4c3c1cf61, 0xeb1d79c9781cc7e5, 0x70459adb7daf675c}}, + {{0x1b91db4991b42bb3, 0x572696234b02dcca, 0x9fdf9ee51f8c78dc, 0x5fe162848ce21fd3}}}, +{{{0xe2790aae4d077c41, 0x8b938270db7469a3, 0x6eb632dc8abd16a2, 0x720814ecaa064b72}}, + {{0x315c29c795115389, 0xd7e0e507862f74ce, 0x0c4a762185927432, 0x72de6c984a25a1e4}}, + {{0xae9ab553bf6aa310, 0x050a50a9806d6e1b, 0x92bb7403adff5139, 0x0394d27645be618b}}}, +{{{0x4d572251857eedf4, 0xe3724edde19e93c5, 0x8a71420e0b797035, 0x3b3c833687abe743}}, + {{0xf5396425b23545a4, 0x15a7a27e98fbb296, 0xab6c52bc636fdd86, 0x79d995a8419334ee}}, + {{0xcd8a8ea61195dd75, 0xa504d8a81dd9a82f, 0x540dca81a35879b6, 0x60dd16a379c86a8a}}}, +{{{0x35a2c8487381e559, 0x596ffea6d78082cb, 0xcb9771ebdba7b653, 0x5a08b5019b4da685}}, + {{0x3501d6f8153e47b8, 0xb7a9675414a2f60c, 0x112ee8b6455d9523, 0x4e62a3c18112ea8a}}, + {{0xc8d4ac04516ab786, 0x595af3215295b23d, 0xd6edd234db0230c1, 0x0929efe8825b41cc}}}, +{{{0x5f0601d1cbd0f2d3, 0x736e412f6132bb7f, 0x83604432238dde87, 0x1e3a5272f5c0753c}}, + {{0x8b3172b7ad56651d, 0x01581b7a3fabd717, 0x2dc94df6424df6e4, 0x30376e5d2c29284f}}, + {{0xd2918da78159a59c, 0x6bdc1cd93f0713f3, 0x565f7a934acd6590, 0x53daacec4cb4c128}}}, +{{{0x4ca73bd79cc8a7d6, 0x4d4a738f47e9a9b2, 0xf4cbf12942f5fe00, 0x01a13ff9bdbf0752}}, + {{0x99852bc3852cfdb0, 0x2cc12e9559d6ed0b, 0x70f9e2bf9b5ac27b, 0x4f3b8c117959ae99}}, + {{0x55b6c9c82ff26412, 0x1ac4a8c91fb667a8, 0xd527bfcfeb778bf2, 0x303337da7012a3be}}}, +{{{0x955422228c1c9d7c, 0x01fac1371a9b340f, 0x7e8d9177925b48d7, 0x53f8ad5661b3e31b}}, + {{0x976d3ccbfad2fdd1, 0xcb88839737a640a8, 0x2ff00c1d6734cb25, 0x269ff4dc789c2d2b}}, + {{0x0c003fbdc08d678d, 0x4d982fa37ead2b17, 0xc07e6bcdb2e582f1, 0x296c7291df412a44}}}, +{{{0x7903de2b33daf397, 0xd0ff0619c9a624b3, 0x8a1d252b555b3e18, 0x2b6d581c52e0b7c0}}, + {{0xdfb23205dab8b59e, 0x465aeaa0c8092250, 0xd133c1189a725d18, 0x2327370261f117d1}}, + {{0x3d0543d3623e7986, 0x679414c2c278a354, 0xae43f0cc726196f6, 0x7836c41f8245eaba}}}, +{{{0xe7a254db49e95a81, 0x5192d5d008b0ad73, 0x4d20e5b1d00afc07, 0x5d55f8012cf25f38}}, + {{0xca651e848011937c, 0xc6b0c46e6ef41a28, 0xb7021ba75f3f8d52, 0x119dff99ead7b9fd}}, + {{0x43eadfcbf4b31d4d, 0xc6503f7411148892, 0xfeee68c5060d3b17, 0x329293b3dd4a0ac8}}}, +{{{0x4e59214fe194961a, 0x49be7dc70d71cd4f, 0x9300cfd23b50f22d, 0x4789d446fc917232}}, + {{0x2879852d5d7cb208, 0xb8dedd70687df2e7, 0xdc0bffab21687891, 0x2b44c043677daa35}}, + {{0x1a1c87ab074eb78e, 0xfac6d18e99daf467, 0x3eacbbcd484f9067, 0x60c52eef2bb9a4e4}}}, +{{{0x0b5d89bc3bfd8bf1, 0xb06b9237c9f3551a, 0x0e4c16b0d53028f5, 0x10bc9c312ccfcaab}}, + {{0x702bc5c27cae6d11, 0x44c7699b54a48cab, 0xefbc4056ba492eb2, 0x70d77248d9b6676d}}, + {{0xaa8ae84b3ec2a05b, 0x98699ef4ed1781e0, 0x794513e4708e85d1, 0x63755bd3a976f413}}}, +{{{0xb55fa03e2ad10853, 0x356f75909ee63569, 0x9ff9f1fdbe69b890, 0x0d8cc1c48bc16f84}}, + {{0x3dc7101897f1acb7, 0x5dda7d5ec165bbd8, 0x508e5b9c0fa1020f, 0x2763751737c52a56}}, + {{0x029402d36eb419a9, 0xf0b44e7e77b460a5, 0xcfa86230d43c4956, 0x70c2dd8a7ad166e7}}}, +{{{0x656194509f6fec0e, 0xee2e7ea946c6518d, 0x9733c1f367e09b5c, 0x2e0fac6363948495}}, + {{0x91d4967db8ed7e13, 0x74252f0ad776817a, 0xe40982e00d852564, 0x32b8613816a53ce5}}, + {{0x79e7f7bee448cd64, 0x6ac83a67087886d0, 0xf89fd4d9a0e4db2e, 0x4179215c735a4f41}}}, +{{{0x8c7094e7d7dced2a, 0x97fb8ac347d39c70, 0xe13be033a906d902, 0x700344a30cd99d76}}, + {{0xe4ae33b9286bcd34, 0xb7ef7eb6559dd6dc, 0x278b141fb3d38e1f, 0x31fa85662241c286}}, + {{0xaf826c422e3622f4, 0xc12029879833502d, 0x9bc1b7e12b389123, 0x24bb2312a9952489}}}, +{{{0xb1a8ed1732de67c3, 0x3cb49418461b4948, 0x8ebd434376cfbcd2, 0x0fee3e871e188008}}, + {{0x41f80c2af5f85c6b, 0x687284c304fa6794, 0x8945df99a3ba1bad, 0x0d1d2af9ffeb5d16}}, + {{0xa9da8aa132621edf, 0x30b822a159226579, 0x4004197ba79ac193, 0x16acd79718531d76}}}, +{{{0x72df72af2d9b1d3d, 0x63462a36a432245a, 0x3ecea07916b39637, 0x123e0ef6b9302309}}, + {{0xc959c6c57887b6ad, 0x94e19ead5f90feba, 0x16e24e62a342f504, 0x164ed34b18161700}}, + {{0x487ed94c192fe69a, 0x61ae2cea3a911513, 0x877bf6d3b9a4de27, 0x78da0fc61073f3eb}}}, +{{{0x5bf15d28e52bc66a, 0x2c47e31870f01a8e, 0x2419afbc06c28bdd, 0x2d25deeb256b173a}}, + {{0xa29f80f1680c3a94, 0x71f77e151ae9e7e6, 0x1100f15848017973, 0x054aa4b316b38ddd}}, + {{0xdfc8468d19267cb8, 0x0b28789c66e54daf, 0x2aeb1d2a666eec17, 0x134610a6ab7da760}}}, +{{{0xcaf55ec27c59b23f, 0x99aeed3e154d04f2, 0x68441d72e14141f4, 0x140345133932a0a2}}, + {{0xd91430e0dc028c3c, 0x0eb955a85217c771, 0x4b09e1ed2c99a1fa, 0x42881af2bd6a743c}}, + {{0x7bfec69aab5cad3d, 0xc23e8cd34cb2cfad, 0x685dd14bfb37d6a2, 0x0ad6d64415677a18}}}, +{{{0x781a439e417becb5, 0x4ac5938cd10e0266, 0x5da385110692ac24, 0x11b065a2ade31233}}, + {{0x7914892847927e9f, 0x33dad6ef370aa877, 0x1f8f24fa11122703, 0x5265ac2f2adf9592}}, + {{0x405fdd309afcb346, 0xd9723d4428e63f54, 0x94c01df05f65aaae, 0x43e4dc3ae14c0809}}}, +{{{0xbc12c7f1a938a517, 0x473028ab3180b2e1, 0x3f78571efbcd254a, 0x74e534426ff6f90f}}, + {{0xea6f7ac3adc2c6a3, 0xd0e928f6e9717c94, 0xe2d379ead645eaf5, 0x46dd8785c51ffbbe}}, + {{0x709801be375c8898, 0x4b06dab5e3fd8348, 0x75880ced27230714, 0x2b09468fdd2f4c42}}}, +{{{0x97c749eeb701cb96, 0x83f438d4b6a369c3, 0x62962b8b9a402cd9, 0x6976c7509888df7b}}, + {{0x5b97946582ffa02a, 0xda096a51fea8f549, 0xa06351375f77af9b, 0x1bcfde61201d1e76}}, + {{0x4a4a5490246a59a2, 0xd63ebddee87fdd90, 0xd9437c670d2371fa, 0x69e87308d30f8ed6}}}, +{{{0x435a8bb15656beb0, 0xf8fac9ba4f4d5bca, 0xb9b278c41548c075, 0x3eb0ef76e892b622}}, + {{0x0f80bf028bc80303, 0x6aae16b37a18cefb, 0xdd47ea47d72cd6a3, 0x61943588f4ed39aa}}, + {{0xd26e5c3e91039f85, 0xc0e9e77df6f33aa9, 0xe8968c5570066a93, 0x3c34d1881faaaddd}}}, +{{{0x3f9d2b5ea09f9ec0, 0x1dab3b6fb623a890, 0xa09ba3ea72d926c4, 0x374193513fd8b36d}}, + {{0xbd5b0b8f2fffe0d9, 0x6aa254103ed24fb9, 0x2ac7d7bcb26821c4, 0x605b394b60dca36a}}, + {{0xb4e856e45a9d1ed2, 0xefe848766c97a9a2, 0xb104cf641e5eee7d, 0x2f50b81c88a71c8f}}}, +{{{0x31723c61fc6811bb, 0x9cb450486211800f, 0x768933d347995753, 0x3491a53502752fcd}}, + {{0x2b552ca0a7da522a, 0x3230b336449b0250, 0xf2c4c5bca4b99fb9, 0x7b2c674958074a22}}, + {{0xd55165883ed28cdf, 0x12d84fd2d362de39, 0x0a874ad3e3378e4f, 0x000d2b1f7c763e74}}}, +{{{0x3d420811d06d4a67, 0xbefc048590e0ffe3, 0xf870c6b7bd487bde, 0x6e2a7316319afa28}}, + {{0x9624778c3e94a8ab, 0x0ad6f3cee9a78bec, 0x948ac7810d743c4f, 0x76627935aaecfccc}}, + {{0x56a8ac24d6d59a9f, 0xc8db753e3096f006, 0x477f41e68f4c5299, 0x588d851cf6c86114}}}, +{{{0x51138ec78df6b0fe, 0x5397da89e575f51b, 0x09207a1d717af1b9, 0x2102fdba2b20d650}}, + {{0xcd2a65e777d1f515, 0x548991878faa60f1, 0xb1b73bbcdabc06e5, 0x654878cba97cc9fb}}, + {{0x969ee405055ce6a1, 0x36bca7681251ad29, 0x3a1af517aa7da415, 0x0ad725db29ecb2ba}}}, +{{{0xdc4267b1834e2457, 0xb67544b570ce1bc5, 0x1af07a0bf7d15ed7, 0x4aefcffb71a03650}}, + {{0xfec7bc0c9b056f85, 0x537d5268e7f5ffd7, 0x77afc6624312aefa, 0x4f675f5302399fd9}}, + {{0xc32d36360415171e, 0xcd2bef118998483b, 0x870a6eadd0945110, 0x0bccbb72a2a86561}}}, +{{{0x185e962feab1a9c8, 0x86e7e63565147dcd, 0xb092e031bb5b6df2, 0x4024f0ab59d6b73e}}, + {{0x186d5e4c50fe1296, 0xe0397b82fee89f7e, 0x3bc7f6c5507031b0, 0x6678fd69108f37c2}}, + {{0x1586fa31636863c2, 0x07f68c48572d33f2, 0x4f73cc9f789eaefc, 0x2d42e2108ead4701}}}, +{{{0x97f5131594dfd29b, 0x6155985d313f4c6a, 0xeba13f0708455010, 0x676b2608b8d2d322}}, + {{0x21717b0d0f537593, 0x914e690b131e064c, 0x1bb687ae752ae09f, 0x420bf3a79b423c6e}}, + {{0x8138ba651c5b2b47, 0x8671b6ec311b1b80, 0x7bff0cb1bc3135b0, 0x745d2ffa9c0cf1e0}}}, +{{{0xbf525a1e2bc9c8bd, 0xea5b260826479d81, 0xd511c70edf0155db, 0x1ae23ceb960cf5d0}}, + {{0x6036df5721d34e6a, 0xb1db8827997bb3d0, 0xd3c209c3c8756afa, 0x06e15be54c1dc839}}, + {{0x5b725d871932994a, 0x32351cb5ceb1dab0, 0x7dc41549dab7ca05, 0x58ded861278ec1f7}}}, +{{{0xd8173793f266c55c, 0xc8c976c5cc454e49, 0x5ce382f8bc26c3a8, 0x2ff39de85485f6f9}}, + {{0x2dfb5ba8b6c2c9a8, 0x48eeef8ef52c598c, 0x33809107f12d1573, 0x08ba696b531d5bd8}}, + {{0x77ed3eeec3efc57a, 0x04e05517d4ff4811, 0xea3d7a3ff1a671cb, 0x120633b4947cfe54}}}, +{{{0x0b94987891610042, 0x4ee7b13cecebfae8, 0x70be739594f0a4c0, 0x35d30a99b4d59185}}, + {{0x82bd31474912100a, 0xde237b6d7e6fbe06, 0xe11e761911ea79c6, 0x07433be3cb393bde}}, + {{0xff7944c05ce997f4, 0x575d3de4b05c51a3, 0x583381fd5a76847c, 0x2d873ede7af6da9f}}}, +{{{0x157a316443373409, 0xfab8b7eef4aa81d9, 0xb093fee6f5a64806, 0x2e773654707fa7b6}}, + {{0xaa6202e14e5df981, 0xa20d59175015e1f5, 0x18a275d3bae21d6c, 0x0543618a01600253}}, + {{0x0deabdf4974c23c1, 0xaa6f0a259dce4693, 0x04202cb8a29aba2c, 0x4b1443362d07960d}}}, +{{{0x47b837f753242cec, 0x256dc48cc04212f2, 0xe222fbfbe1d928c5, 0x48ea295bad8a2c07}}, + {{0x299b1c3f57c5715e, 0x96cb929e6b686d90, 0x3004806447235ab3, 0x2c435c24a44d9fe1}}, + {{0x0607c97c80f8833f, 0x0e851578ca25ec5b, 0x54f7450b161ebb6f, 0x7bcb4792a0def80e}}}, +{{{0x8487e3d02bc73659, 0x4baf8445059979df, 0xd17c975adcad6fbf, 0x57369f0bdefc96b6}}, + {{0x1cecd0a0045224c2, 0x757f1b1b69e53952, 0x775b7a925289f681, 0x1b6cc62016736148}}, + {{0xf1a9990175638698, 0x353dd1beeeaa60d3, 0x849471334c9ba488, 0x63fa6e6843ade311}}}, +{{{0xd15c20536597c168, 0x9f73740098d28789, 0x18aee7f13257ba1f, 0x3418bfda07346f14}}, + {{0x2195becdd24b5eb7, 0x5e41f18cc0cd44f9, 0xdf28074441ca9ede, 0x07073b98f35b7d67}}, + {{0xd03c676c4ce530d4, 0x0b64c0473b5df9f4, 0x065cef8b19b3a31e, 0x3084d661533102c9}}}, +{{{0xe1f6b79ebf8469ad, 0x15801004e2663135, 0x9a498330af74181b, 0x3ba2504f049b673c}}, + {{0x9a6ce876760321fd, 0x7fe2b5109eb63ad8, 0x00e7d4ae8ac80592, 0x73d86b7abb6f723a}}, + {{0x0b52b5606dba5ab6, 0xa9134f0fbbb1edab, 0x30a9520d9b04a635, 0x6813b8f37973e5db}}}, +{{{0x9854b054334127c1, 0x105d047882fbff25, 0xdb49f7f944186f4f, 0x1768e838bed0b900}}, + {{0xf194ca56f3157e29, 0x136d35705ef528a5, 0xdd4cef778b0599bc, 0x7d5472af24f833ed}}, + {{0xd0ef874daf33da47, 0x00d3be5db6e339f9, 0x3f2a8a2f9c9ceece, 0x5d1aeb792352435a}}}, +{{{0xf59e6bb319cd63ca, 0x670c159221d06839, 0xb06d565b2150cab6, 0x20fb199d104f12a3}}, + {{0x12c7bfaeb61ba775, 0xb84e621fe263bffd, 0x0b47a5c35c840dcf, 0x7e83be0bccaf8634}}, + {{0x61943dee6d99c120, 0x86101f2e460b9fe0, 0x6bb2f1518ee8598d, 0x76b76289fcc475cc}}}, +{{{0x791b4cc1756286fa, 0xdbced317d74a157c, 0x7e732421ea72bde6, 0x01fe18491131c8e9}}, + {{0x4245f1a1522ec0b3, 0x558785b22a75656d, 0x1d485a2548a1b3c0, 0x60959eccd58fe09f}}, + {{0x3ebfeb7ba8ed7a09, 0x49fdc2bbe502789c, 0x44ebce5d3c119428, 0x35e1eb55be947f4a}}}, +{{{0xdbdae701c5738dd3, 0xf9c6f635b26f1bee, 0x61e96a8042f15ef4, 0x3aa1d11faf60a4d8}}, + {{0x14fd6dfa726ccc74, 0x3b084cfe2f53b965, 0xf33ae4f552a2c8b4, 0x59aab07a0d40166a}}, + {{0x77bcec4c925eac25, 0x1848718460137738, 0x5b374337fea9f451, 0x1865e78ec8e6aa46}}}, +{{{0xccc4b7c7b66e1f7a, 0x44157e25f50c2f7e, 0x3ef06dfc713eaf1c, 0x582f446752da63f7}}, + {{0x967c54e91c529ccb, 0x30f6269264c635fb, 0x2747aff478121965, 0x17038418eaf66f5c}}, + {{0xc6317bd320324ce4, 0xa81042e8a4488bc4, 0xb21ef18b4e5a1364, 0x0c2a1c4bcda28dc9}}}, +{{{0xd24dc7d06f1f0447, 0xb2269e3edb87c059, 0xd15b0272fbb2d28f, 0x7c558bd1c6f64877}}, + {{0xedc4814869bd6945, 0x0d6d907dbe1c8d22, 0xc63bd212d55cc5ab, 0x5a6a9b30a314dc83}}, + {{0xd0ec1524d396463d, 0x12bb628ac35a24f0, 0xa50c3a791cbc5fa4, 0x0404a5ca0afbafc3}}}, +{{{0x8c1f40070aa743d6, 0xccbad0cb5b265ee8, 0x574b046b668fd2de, 0x46395bfdcadd9633}}, + {{0x62bc9e1b2a416fd1, 0xb5c6f728e350598b, 0x04343fd83d5d6967, 0x39527516e7f8ee98}}, + {{0x117fdb2d1a5d9a9c, 0x9c7745bcd1005c2a, 0xefd4bef154d56fea, 0x76579a29e822d016}}}, +{{{0x45b68e7e49c02a17, 0x23cd51a2bca9a37f, 0x3ed65f11ec224c1b, 0x43a384dc9e05bdb1}}, + {{0x333cb51352b434f2, 0xd832284993de80e1, 0xb5512887750d35ce, 0x02c514bb2a2777c1}}, + {{0x684bd5da8bf1b645, 0xfb8bd37ef6b54b53, 0x313916d7a9b0d253, 0x1160920961548059}}}, +{{{0xb44d166929dacfaa, 0xda529f4c8413598f, 0xe9ef63ca453d5559, 0x351e125bc5698e0b}}, + {{0x7a385616369b4dcd, 0x75c02ca7655c3563, 0x7dc21bf9d4f18021, 0x2f637d7491e6e042}}, + {{0xd4b49b461af67bbe, 0xd603037ac8ab8961, 0x71dee19ff9a699fb, 0x7f182d06e7ce2a9a}}}, +{{{0x7a7c8e64ab0168ec, 0xcb5a4a5515edc543, 0x095519d347cd0eda, 0x67d4ac8c343e93b0}}, + {{0x09454b728e217522, 0xaa58e8f4d484b8d8, 0xd358254d7f46903c, 0x44acc043241c5217}}, + {{0x1c7d6bbb4f7a5777, 0x8b35fed4918313e1, 0x4adca1c6c96b4684, 0x556d1c8312ad71bd}}}, +{{{0x17ef40e30c8d3982, 0x31f7073e15a3fa34, 0x4f21f3cb0773646e, 0x746c6c6d1d824eff}}, + {{0x81f06756b11be821, 0x0faff82310a3f3dd, 0xf8b2d0556a99465d, 0x097abe38cc8c7f05}}, + {{0x0c49c9877ea52da4, 0x4c4369559bdc1d43, 0x022c3809f7ccebd2, 0x577e14a34bee84bd}}}, +{{{0xf0e268ac61a73b0a, 0xf2fafa103791a5f5, 0xc1e13e826b6d00e9, 0x60fa7ee96fd78f42}}, + {{0x94fecebebd4dd72b, 0xf46a4fda060f2211, 0x124a5977c0c8d1ff, 0x705304b8fb009295}}, + {{0xb63d1d354d296ec6, 0xf3c3053e5fad31d8, 0x670b958cb4bd42ec, 0x21398e0ca16353fd}}}, +{{{0x216ab2ca8da7d2ef, 0x366ad9dd99f42827, 0xae64b9004fdd3c75, 0x403a395b53909e62}}, + {{0x86c5fc16861b7e9a, 0xf6a330476a27c451, 0x01667267a1e93597, 0x05ffb9cd6082dfeb}}, + {{0xa617fa9ff53f6139, 0x60f2b5e513e66cb6, 0xd7a8beefb3448aa4, 0x7a2932856f5ea192}}}, +{{{0x0b39d761b02de888, 0x5f550e7ed2414e1f, 0xa6bfa45822e1a940, 0x050a2f7dfd447b99}}, + {{0xb89c444879639302, 0x4ae4f19350c67f2c, 0xf0b35da8c81af9c6, 0x39d0003546871017}}, + {{0x437c3b33a650db77, 0x6bafe81dbac52bb2, 0xfe99402d2db7d318, 0x2b5b7eec372ba6ce}}}, +{{{0xb3bc4bbd83f50eef, 0x508f0c998c927866, 0x43e76587c8b7e66e, 0x0f7655a3a47f98d9}}, + {{0xa694404d613ac8f4, 0x500c3c2bfa97e72c, 0x874104d21fcec210, 0x1b205fb38604a8ee}}, + {{0x55ecad37d24b133c, 0x441e147d6038c90b, 0x656683a1d62c6fee, 0x0157d5dc87e0ecae}}}, +{{{0xf2a7af510354c13d, 0xd7a0b145aa372b60, 0x2869b96a05a3d470, 0x6528e42d82460173}}, + {{0x95265514d71eb524, 0xe603d8815df14593, 0x147cdf410d4de6b7, 0x5293b1730437c850}}, + {{0x23d0e0814bccf226, 0x92c745cd8196fb93, 0x8b61796c59541e5b, 0x40a44df0c021f978}}}, +{{{0xdaa869894f20ea6a, 0xea14a3d14c620618, 0x6001fccb090bf8be, 0x35f4e822947e9cf0}}, + {{0x86c96e514bc5d095, 0xf20d4098fca6804a, 0x27363d89c826ea5d, 0x39ca36565719cacf}}, + {{0x97506f2f6f87b75c, 0xc624aea0034ae070, 0x1ec856e3aad34dd6, 0x055b0be0e440e58f}}}, +{{{0x6469a17d89735d12, 0xdb6f27d5e662b9f1, 0x9fcba3286a395681, 0x363b8004d269af25}}, + {{0x4d12a04b6ea33da2, 0x57cf4c15e36126dd, 0x90ec9675ee44d967, 0x64ca348d2a985aac}}, + {{0x99588e19e4c4912d, 0xefcc3b4e1ca5ce6b, 0x4522ea60fa5b98d5, 0x7064bbab1de4a819}}}, +{{{0xb919e1515a770641, 0xa9a2e2c74e7f8039, 0x7527250b3df23109, 0x756a7330ac27b78b}}, + {{0xa290c06142542129, 0xf2e2c2aebe8d5b90, 0xcf2458db76abfe1b, 0x02157ade83d626bf}}, + {{0x3e46972a1b9a038b, 0x2e4ee66a7ee03fb4, 0x81a248776edbb4ca, 0x1a944ee88ecd0563}}}, +{{{0xd5a91d1151039372, 0x2ed377b799ca26de, 0xa17202acfd366b6b, 0x0730291bd6901995}}, + {{0xbb40a859182362d6, 0xb99f55778a4d1abb, 0x8d18b427758559f6, 0x26c20fe74d26235a}}, + {{0x648d1d9fe9cc22f5, 0x66bc561928dd577c, 0x47d3ed21652439d1, 0x49d271acedaf8b49}}}, +{{{0x89f5058a382b33f3, 0x5ae2ba0bad48c0b4, 0x8f93b503a53db36e, 0x5aa3ed9d95a232e6}}, + {{0x2798aaf9b4b75601, 0x5eac72135c8dad72, 0xd2ceaa6161b7a023, 0x1bbfb284e98f7d4e}}, + {{0x656777e9c7d96561, 0xcb2b125472c78036, 0x65053299d9506eee, 0x4a07e14e5e8957cc}}}, +{{{0x4ee412cb980df999, 0xa315d76f3c6ec771, 0xbba5edde925c77fd, 0x3f0bac391d313402}}, + {{0x240b58cdc477a49b, 0xfd38dade6447f017, 0x19928d32a7c86aad, 0x50af7aed84afa081}}, + {{0x6e4fde0115f65be5, 0x29982621216109b2, 0x780205810badd6d9, 0x1921a316baebd006}}}, +{{{0x89422f7edfb870fc, 0x2c296beb4f76b3bd, 0x0738f1d436c24df7, 0x6458df41e273aeb0}}, + {{0xd75aad9ad9f3c18b, 0x566a0eef60b1c19c, 0x3e9a0bac255c0ed9, 0x7b049deca062c7f5}}, + {{0xdccbe37a35444483, 0x758879330fedbe93, 0x786004c312c5dd87, 0x6093dccbc2950e64}}}, +{{{0x1ff39a8585e0706d, 0x36d0a5d8b3e73933, 0x43b9f2e1718f453b, 0x57d1ea084827a97c}}, + {{0x6bdeeebe6084034b, 0x3199c2b6780fb854, 0x973376abb62d0695, 0x6e3180c98b647d90}}, + {{0xee7ab6e7a128b071, 0xa4c1596d93a88baa, 0xf7b4de82b2216130, 0x363e999ddd97bd18}}}, +{{{0x96a843c135ee1fc4, 0x976eb35508e4c8cf, 0xb42f6801b58cd330, 0x48ee9b78693a052b}}, + {{0x2f1848dce24baec6, 0x769b7255babcaf60, 0x90cb3c6e3cefe931, 0x231f979bc6f9b355}}, + {{0x5c31de4bcc2af3c6, 0xb04bb030fe208d1f, 0xb78d7009c14fb466, 0x079bfa9b08792413}}}, +{{{0xe3903a51da300df4, 0x843964233da95ab0, 0xed3cf12d0b356480, 0x038c77f684817194}}, + {{0xf3c9ed80a2d54245, 0x0aa08b7877f63952, 0xd76dac63d1085475, 0x1ef4fb159470636b}}, + {{0x854e5ee65b167bec, 0x59590a4296d0cdc2, 0x72b2df3498102199, 0x575ee92a4a0bff56}}}, +{{{0xd4c080908a182fcf, 0x30e170c299489dbd, 0x05babd5752f733de, 0x43d4e7112cd3fd00}}, + {{0x5d46bc450aa4d801, 0xc3af1227a533b9d8, 0x389e3b262b8906c2, 0x200a1e7e382f581b}}, + {{0x518db967eaf93ac5, 0x71bc989b056652c0, 0xfe2b85d9567197f5, 0x050eca52651e4e38}}}, +{{{0xc3431ade453f0c9c, 0xe9f5045eff703b9b, 0xfcd97ac9ed847b3d, 0x4b0ee6c21c58f4c6}}, + {{0x97ac397660e668ea, 0x9b19bbfe153ab497, 0x4cb179b534eca79f, 0x6151c09fa131ae57}}, + {{0x3af55c0dfdf05d96, 0xdd262ee02ab4ee7a, 0x11b2bb8712171709, 0x1fef24fa800f030b}}}, +{{{0xb496123a6b6c6609, 0xa750fe8580ab5938, 0xf471bf39b7c27a5f, 0x507903ce77ac193c}}, + {{0xff91a66a90166220, 0xf22552ae5bf1e009, 0x7dff85d87f90df7c, 0x4f620ffe0c736fb9}}, + {{0x62f90d65dfde3e34, 0xcf28c592b9fa5fad, 0x99c86ef9c6164510, 0x25d448044a256c84}}}, +{{{0xbd68230ec7e9b16f, 0x0eb1b9c1c1c5795d, 0x7943c8c495b6b1ff, 0x2f9faf620bbacf5e}}, + {{0x2c7c4415c9022b55, 0x56a0d241812eb1fe, 0xf02ea1c9d7b65e0d, 0x4180512fd5323b26}}, + {{0xa4ff3e698a48a5db, 0xba6a3806bd95403b, 0x9f7ce1af47d5b65d, 0x15e087e55939d2fb}}}, +{{{0x12207543745c1496, 0xdaff3cfdda38610c, 0xe4e797272c71c34f, 0x39c07b1934bdede9}}, + {{0x8894186efb963f38, 0x48a00e80dc639bd5, 0xa4e8092be96c1c99, 0x5a097d54ca573661}}, + {{0x2d45892b17c9e755, 0xd033fd7289308df8, 0x6c2fe9d9525b8bd9, 0x2edbecf1c11cc079}}}, +{{{0x1616a4e3c715a0d2, 0x53623cb0f8341d4d, 0x96ef5329c7e899cb, 0x3d4e8dbba668baa6}}, + {{0xee0f0fddd087a25f, 0x9c7531555c3e34ee, 0x660c572e8fab3ab5, 0x0854fc44544cd3b2}}, + {{0x61eba0c555edad19, 0x24b533fef0a83de6, 0x3b77042883baa5f8, 0x678f82b898a47e8d}}}, +{{{0xb1491d0bd6900c54, 0x3539722c9d132636, 0x4db928920b362bc9, 0x4d7cd1fea68b69df}}, + {{0x1e09d94057775696, 0xeed1265c3cd951db, 0xfa9dac2b20bce16f, 0x0f7f76e0e8d089f4}}, + {{0x36d9ebc5d485b00c, 0xa2596492e4adb365, 0xc1659480c2119ccd, 0x45306349186e0d5f}}}, +{{{0x94ddd0c1a6cdff1d, 0x55f6f115e84213ae, 0x6c935f85992fcf6a, 0x067ee0f54a37f16f}}, + {{0x96a414ec2b072491, 0x1bb2218127a7b65b, 0x6d2849596e8a4af0, 0x65f3b08ccd27765f}}, + {{0xecb29fff199801f7, 0x9d361d1fa2a0f72f, 0x25f11d2375fd2f49, 0x124cefe80fe10fe2}}}, +{{{0x4c126cf9d18df255, 0xc1d471e9147a63b6, 0x2c6d3c73f3c93b5f, 0x6be3a6a2e3ff86a2}}, + {{0x1518e85b31b16489, 0x8faadcb7db710bfb, 0x39b0bdf4a14ae239, 0x05f4cbea503d20c1}}, + {{0xce040e9ec04145bc, 0xc71ff4e208f6834c, 0xbd546e8dab8847a3, 0x64666aa0a4d2aba5}}}, +{{{0x6841435a7c06d912, 0xca123c21bb3f830b, 0xd4b37b27b1cbe278, 0x1d753b84c76f5046}}, + {{0xb0c53bf73337e94c, 0x7cb5697e11e14f15, 0x4b84abac1930c750, 0x28dd4abfe0640468}}, + {{0x7dc0b64c44cb9f44, 0x18a3e1ace3925dbf, 0x7a3034862d0457c4, 0x4c498bf78a0c892e}}}, +{{{0x37d653fb1aa73196, 0x0f9495303fd76418, 0xad200b09fb3a17b2, 0x544d49292fc8613e}}, + {{0x22d2aff530976b86, 0x8d90b806c2d24604, 0xdca1896c4de5bae5, 0x28005fe6c8340c17}}, + {{0x6aefba9f34528688, 0x5c1bff9425107da1, 0xf75bbbcd66d94b36, 0x72e472930f316dfa}}}, +{{{0x2695208c9781084f, 0xb1502a0b23450ee1, 0xfd9daea603efde02, 0x5a9d2e8c2733a34c}}, + {{0x07f3f635d32a7627, 0x7aaa4d865f6566f0, 0x3c85e79728d04450, 0x1fee7f000fe06438}}, + {{0x765305da03dbf7e5, 0xa4daf2491434cdbd, 0x7b4ad5cdd24a88ec, 0x00f94051ee040543}}}, +{{{0x8d356b23c3d330b2, 0xf21c8b9bb0471b06, 0xb36c316c6e42b83c, 0x07d79c7e8beab10d}}, + {{0xd7ef93bb07af9753, 0x583ed0cf3db766a7, 0xce6998bf6e0b1ec5, 0x47b7ffd25dd40452}}, + {{0x87fbfb9cbc08dd12, 0x8a066b3ae1eec29b, 0x0d57242bdb1fc1bf, 0x1c3520a35ea64bb6}}}, +{{{0x80d253a6bccba34a, 0x3e61c3a13838219b, 0x90c3b6019882e396, 0x1c3d05775d0ee66f}}, + {{0xcda86f40216bc059, 0x1fbb231d12bcd87e, 0xb4956a9e17c70990, 0x38750c3b66d12e55}}, + {{0x692ef1409422e51a, 0xcbc0c73c2b5df671, 0x21014fe7744ce029, 0x0621e2c7d330487c}}}, +{{{0xaf9860cc8259838d, 0x90ea48c1c69f9adc, 0x6526483765581e30, 0x0007d6097bd3a5bc}}, + {{0xb7ae1796b0dbf0f3, 0x54dfafb9e17ce196, 0x25923071e9aaa3b4, 0x5d8e589ca1002e9d}}, + {{0xc0bf1d950842a94b, 0xb2d3c363588f2e3e, 0x0a961438bb51e2ef, 0x1583d7783c1cbf86}}}, +{{{0xeceea2ef5da27ae1, 0x597c3a1455670174, 0xc9a62a126609167a, 0x252a5f2e81ed8f70}}, + {{0x90034704cc9d28c7, 0x1d1b679ef72cc58f, 0x16e12b5fbe5b8726, 0x4958064e83c5580a}}, + {{0x0d2894265066e80d, 0xfcc3f785307c8c6b, 0x1b53da780c1112fd, 0x079c170bd843b388}}}, +{{{0x0506ece464fa6fff, 0xbee3431e6205e523, 0x3579422451b8ea42, 0x6dec05e34ac9fb00}}, + {{0xcdd6cd50c0d5d056, 0x9af7686dbb03573b, 0x3ca6723ff3c3ef48, 0x6768c0d7317b8acc}}, + {{0x94b625e5f155c1b3, 0x417bf3a7997b7b91, 0xc22cbddc6d6b2600, 0x51445e14ddcd52f4}}}, +{{{0x57502b4b3b144951, 0x8e67ff6b444bbcb3, 0xb8bd6927166385db, 0x13186f31e39295c8}}, + {{0x893147ab2bbea455, 0x8c53a24f92079129, 0x4b49f948be30f7a7, 0x12e990086e4fd43d}}, + {{0xf10c96b37fdfbb2e, 0x9f9a935e121ceaf9, 0xdf1136c43a5b983f, 0x77b2e3f05d3e99af}}}, +{{{0xfd0d75879cf12657, 0xe82fef94e53a0e29, 0xcc34a7f05bbb4be7, 0x0b251172a50c38a2}}, + {{0x9532f48fcc5cd29b, 0x2ba851bea3ce3671, 0x32dacaa051122941, 0x478d99d9350004f2}}, + {{0x1d5ad94890bb02c0, 0x50e208b10ec25115, 0xa26a22894ef21702, 0x4dc923343b524805}}}, +{{{0xe3828c400f8086b6, 0x3f77e6f7979f0dc8, 0x7ef6de304df42cb4, 0x5265797cb6abd784}}, + {{0x3ad3e3ebf36c4975, 0xd75d25a537862125, 0xe873943da025a516, 0x6bbc7cb4c411c847}}, + {{0x3c6f9cd1d4a50d56, 0xb6244077c6feab7e, 0x6ff9bf483580972e, 0x00375883b332acfb}}}, +{{{0x0001b2cd28cb0940, 0x63fb51a06f1c24c9, 0xb5ad8691dcd5ca31, 0x67238dbd8c450660}}, + {{0xc98bec856c75c99c, 0xe44184c000e33cf4, 0x0a676b9bba907634, 0x669e2cb571f379d7}}, + {{0xcb116b73a49bd308, 0x025aad6b2392729e, 0xb4793efa3f55d9b1, 0x72a1056140678bb9}}}, +{{{0xa2b6812b1cc9249d, 0x62866eee21211f58, 0x2cb5c5b85df10ece, 0x03a6b259e263ae00}}, + {{0x0d8d2909e2e505b6, 0x98ca78abc0291230, 0x77ef5569a9b12327, 0x7c77897b81439b47}}, + {{0xf1c1b5e2de331cb5, 0x5a9f5d8e15fca420, 0x9fa438f17bd932b1, 0x2a381bf01c6146e7}}}, +{{{0xac9b9879cfc811c1, 0x8b7d29813756e567, 0x50da4e607c70edfc, 0x5dbca62f884400b6}}, + {{0xf7c0be32b534166f, 0x27e6ca6419cf70d4, 0x934df7d7a957a759, 0x5701461dabdec2aa}}, + {{0x2c6747402c915c25, 0x1bdcd1a80b0d340a, 0x5e5601bd07b43f5f, 0x2555b4e05539a242}}}, +{{{0x6fc09f5266ddd216, 0xdce560a7c8e37048, 0xec65939da2df62fd, 0x7a869ae7e52ed192}}, + {{0x78409b1d87e463d4, 0xad4da95acdfb639d, 0xec28773755259b9c, 0x69c806e9c31230ab}}, + {{0x7b48f57414bb3f22, 0x68c7cee4aedccc88, 0xed2f936179ed80be, 0x25d70b885f77bc4b}}}, +{{{0x4151c3d9762bf4de, 0x083f435f2745d82b, 0x29775a2e0d23ddd5, 0x138e3a6269a5db24}}, + {{0x98459d29bb1ae4d4, 0x56b9c4c739f954ec, 0x832743f6c29b4b3e, 0x21ea8e2798b6878a}}, + {{0x87bef4b46a5a7b9c, 0xd2299d1b5fc1d062, 0x82409818dd321648, 0x5c5abeb1e5a2e03d}}}, +{{{0x14722af4b73c2ddb, 0xbc470c5f5a05060d, 0x00943eac2581b02e, 0x0e434b3b1f499c8f}}, + {{0x02cde6de1306a233, 0x7b5a52a2116f8ec7, 0xe1c681f4c1163b5b, 0x241d350660d32643}}, + {{0x6be4404d0ebc52c7, 0xae46233bb1a791f5, 0x2aec170ed25db42b, 0x1d8dfd966645d694}}}, +{{{0x296fa9c59c2ec4de, 0xbc8b61bf4f84f3cb, 0x1c7706d917a8f908, 0x63b795fc7ad3255d}}, + {{0xd598639c12ddb0a4, 0xa5d19f30c024866b, 0xd17c2f0358fce460, 0x07a195152e095e8a}}, + {{0xa8368f02389e5fc8, 0x90433b02cf8de43b, 0xafa1fd5dc5412643, 0x3e8fe83d032f0137}}}, +{{{0x2f8b15b90570a294, 0x94f2427067084549, 0xde1c5ae161bbfd84, 0x75ba3b797fac4007}}, + {{0x08704c8de8efd13c, 0xdfc51a8e33e03731, 0xa59d5da51260cde3, 0x22d60899a6258c86}}, + {{0x6239dbc070cdd196, 0x60fe8a8b6c7d8a9a, 0xb38847bceb401260, 0x0904d07b87779e5e}}}, +{{{0xb4ce1fd4ddba919c, 0xcf31db3ec74c8daa, 0x2c63cc63ad86cc51, 0x43e2143fbc1dde07}}, + {{0xf4322d6648f940b9, 0x06952f0cbd2d0c39, 0x167697ada081f931, 0x6240aacebaf72a6c}}, + {{0xf834749c5ba295a0, 0xd6947c5bca37d25a, 0x66f13ba7e7c9316a, 0x56bdaf238db40cac}}}, +{{{0x362ab9e3f53533eb, 0x338568d56eb93d40, 0x9e0e14521d5a5572, 0x1d24a86d83741318}}, + {{0x1310d36cc19d3bb2, 0x062a6bb7622386b9, 0x7c9b8591d7a14f5c, 0x03aa31507e1e5754}}, + {{0xf4ec7648ffd4ce1f, 0xe045eaf054ac8c1c, 0x88d225821d09357c, 0x43b261dc9aeb4859}}}, +{{{0xe55b1e1988bb79bb, 0xa09ed07dc17a359d, 0xb02c2ee2603dea33, 0x326055cf5b276bc2}}, + {{0x19513d8b6c951364, 0x94fe7126000bf47b, 0x028d10ddd54f9567, 0x02b4d5e242940964}}, + {{0xb4a155cb28d18df2, 0xeacc4646186ce508, 0xc49cf4936c824389, 0x27a6c809ae5d3410}}}, +{{{0x8ba6ebcd1f0db188, 0x37d3d73a675a5be8, 0xf22edfa315f5585a, 0x2cb67174ff60a17e}}, + {{0xcd2c270ac43d6954, 0xdd4a3e576a66cab2, 0x79fa592469d7036c, 0x221503603d8c2599}}, + {{0x59eecdf9390be1d0, 0xa9422044728ce3f1, 0x82891c667a94f0f4, 0x7b1df4b73890f436}}}, +{{{0xe492f2e0b3b2a224, 0x7c6c9e062b551160, 0x15eb8fe20d7f7b0e, 0x61fcef2658fc5992}}, + {{0x5f2e221807f8f58c, 0xe3555c9fd49409d4, 0xb2aaa88d1fb6a630, 0x68698245d352e03d}}, + {{0xdbb15d852a18187a, 0xf3e4aad386ddacd7, 0x44bae2810ff6c482, 0x46cf4c473daf01cf}}}, +{{{0x426525ed9ec4e5f9, 0x0e5eda0116903303, 0x72b1a7f2cbe5cadc, 0x29387bcd14eb5f40}}, + {{0x213c6ea7f1498140, 0x7c1e7ef8392b4854, 0x2488c38c5629ceba, 0x1065aae50d8cc5bb}}, + {{0x1c2c4525df200d57, 0x5c3b2dd6bfca674a, 0x0a07e7b1e1834030, 0x69a198e64f1ce716}}}, +{{{0x7afcd613efa9d697, 0x0cc45aa41c067959, 0xa56fe104c1fada96, 0x3a73b70472e40365}}, + {{0x7b26e56b9e2d4734, 0xc4c7132b81c61675, 0xef5c9525ec9cde7f, 0x39c80b16e71743ad}}, + {{0x0f196e0d1b826c68, 0xf71ff0e24960e3db, 0x6113167023b7436c, 0x0cf0ea5877da7282}}}, +{{{0x196c80a4ddd4ccbd, 0x22e6f55d95f2dd9d, 0xc75e33c740d6c71b, 0x7bb51279cb3c042f}}, + {{0xe332ced43ba6945a, 0xde0b1361e881c05d, 0x1ad40f095e67ed3b, 0x5da8acdab8c63d5d}}, + {{0xc4b6664a3a70159f, 0x76194f0f0a904e14, 0xa5614c39a4096c13, 0x6cd0ff50979feced}}}, +{{{0xc0e067e78f4428ac, 0x14835ab0a61135e3, 0xf21d14f338062935, 0x6390a4c8df04849c}}, + {{0x7fecfabdb04ba18e, 0xd0fc7bfc3bddbcf7, 0xa41d486e057a131c, 0x641a4391f2223a61}}, + {{0xc5c6b95aa606a8db, 0x914b7f9eb06825f1, 0x2a731f6b44fc9eff, 0x30ddf38562705cfc}}}, +{{{0x4e3dcbdad1bff7f9, 0xc9118e8220645717, 0xbacccebc0f189d56, 0x1b4822e9d4467668}}, + {{0x33bef2bd68bcd52c, 0xc649dbb069482ef2, 0xb5b6ee0c41cb1aee, 0x5c294d270212a7e5}}, + {{0xab360a7f25563781, 0x2512228a480f7958, 0xc75d05276114b4e3, 0x222d9625d976fe2a}}}, +{{{0x1c717f85b372ace1, 0x81930e694638bf18, 0x239cad056bc08b58, 0x0b34271c87f8fff4}}, + {{0x0f94be7e0a344f85, 0xeb2faa8c87f22c38, 0x9ce1e75e4ee16f0f, 0x43e64e5418a08dea}}, + {{0x8155e2521a35ce63, 0xbe100d4df912028e, 0xbff80bf8a57ddcec, 0x57342dc96d6bc6e4}}}, +{{{0xefeef065c8ce5998, 0xbf029510b5cbeaa2, 0x8c64a10620b7c458, 0x35134fb231c24855}}, + {{0xf3c3bcb71e707bf6, 0x351d9b8c7291a762, 0x00502e6edad69a33, 0x522f521f1ec8807f}}, + {{0x272c1f46f9a3902b, 0xc91ba3b799657bcc, 0xae614b304f8a1c0e, 0x7afcaad70b99017b}}}, +{{{0xc25ded54a4b8be41, 0x902d13e11bb0e2dd, 0x41f43233cde82ab2, 0x1085faa5c3aae7cb}}, + {{0xa88141ecef842b6b, 0x55e7b14797abe6c5, 0x8c748f9703784ffe, 0x5b50a1f7afcd00b7}}, + {{0x9b840f66f1361315, 0x18462242701003e9, 0x65ed45fae4a25080, 0x0a2862393fda7320}}}, +{{{0x46ab13c8347cbc9d, 0x3849e8d499c12383, 0x4cea314087d64ac9, 0x1f354134b1a29ee7}}, + {{0x960e737b6ecb9d17, 0xfaf24948d67ceae1, 0x37e7a9b4d55e1b89, 0x5cb7173cb46c59eb}}, + {{0x4a89e68b82b7abf0, 0xf41cd9279ba6b7b9, 0x16e6c210e18d876f, 0x7cacdb0f7f1b09c6}}}, +{{{0x9062b2e0d91a78bc, 0x47c9889cc8509667, 0x9df54a66405070b8, 0x7369e6a92493a1bf}}, + {{0xe1014434dcc5caed, 0x47ed5d963c84fb33, 0x70019576ed86a0e7, 0x25b2697bd267f9e4}}, + {{0x9d673ffb13986864, 0x3ca5fbd9415dc7b8, 0xe04ecc3bdf273b5e, 0x1420683db54e4cd2}}}, +{{{0xb478bd1e249dd197, 0x620c35005e58c102, 0xfb02d32fccbaac5c, 0x60b63bebf508a72d}}, + {{0x34eebb6fc1cc5ad0, 0x6a1b0ce99646ac8b, 0xd3b0da49a66bde53, 0x31e83b4161d081c1}}, + {{0x97e8c7129e062b4f, 0x49e48f4f29320ad8, 0x5bece14b6f18683f, 0x55cf1eb62d550317}}}, +{{{0x5879101065c23d58, 0x8b9d086d5094819c, 0xe2402fa912c55fa7, 0x669a6564570891d4}}, + {{0x3076b5e37df58c52, 0xd73ab9dde799cc36, 0xbd831ce34913ee20, 0x1a56fbaa62ba0133}}, + {{0x943e6b505c9dc9ec, 0x302557bba77c371a, 0x9873ae5641347651, 0x13c4836799c58a5c}}}, +{{{0x423a5d465ab3e1b9, 0xfc13c187c7f13f61, 0x19f83664ecb5b9b6, 0x66f80c93a637b607}}, + {{0xc4dcfb6a5d8bd080, 0xdeebc4ec571a4842, 0xd4b2e883b8e55365, 0x50bdc87dc8e5b827}}, + {{0x606d37836edfe111, 0x32353e15f011abd9, 0x64b03ac325b73b96, 0x1dd56444725fd5ae}}}, +{{{0x8fa47ff83362127d, 0xbc9f6ac471cd7c15, 0x6e71454349220c8b, 0x0e645912219f732e}}, + {{0xc297e60008bac89a, 0x7d4cea11eae1c3e0, 0xf3e38be19fe7977c, 0x3a3a450f63a305cd}}, + {{0x078f2f31d8394627, 0x389d3183de94a510, 0xd1e36c6d17996f80, 0x318c8d9393a9a87b}}}, +{{{0xf2745d032afffe19, 0x0c9f3c497f24db66, 0xbc98d3e3ba8598ef, 0x224c7c679a1d5314}}, + {{0x5d669e29ab1dd398, 0xfc921658342d9e3b, 0x55851dfdf35973cd, 0x509a41c325950af6}}, + {{0xbdc06edca6f925e9, 0x793ef3f4641b1f33, 0x82ec12809d833e89, 0x05bff02328a11389}}}, +{{{0x3632137023cae00b, 0x544acf0ad1accf59, 0x96741049d21a1c88, 0x780b8cc3fa2a44a7}}, + {{0x6881a0dd0dc512e4, 0x4fe70dc844a5fafe, 0x1f748e6b8f4a5240, 0x576277cdee01a3ea}}, + {{0x1ef38abc234f305f, 0x9a577fbd1405de08, 0x5e82a51434e62a0d, 0x5ff418726271b7a1}}}, +{{{0x398e080c1789db9d, 0xa7602025f3e778f5, 0xfa98894c06bd035d, 0x106a03dc25a966be}}, + {{0xe5db47e813b69540, 0xf35d2a3b432610e1, 0xac1f26e938781276, 0x29d4db8ca0a0cb69}}, + {{0xd9ad0aaf333353d0, 0x38669da5acd309e5, 0x3c57658ac888f7f0, 0x4ab38a51052cbefa}}}, +{{{0xdfdacbee4324c0e9, 0x054442883f955bb7, 0xdef7aaa8ea31609f, 0x68aee70642287cff}}, + {{0xf68fe2e8809de054, 0xe3bc096a9c82bad1, 0x076353d40aadbf45, 0x7b9b1fb5dea1959e}}, + {{0xf01cc8f17471cc0c, 0x95242e37579082bb, 0x27776093d3e46b5f, 0x2d13d55a28bd85fb}}}, +{{{0xfac5d2065b35b8da, 0xa8da8a9a85624bb7, 0xccd2ca913d21cd0f, 0x6b8341ee8bf90d58}}, + {{0xbf019cce7aee7a52, 0xa8ded2b6e454ead3, 0x3c619f0b87a8bb19, 0x3619b5d7560916d8}}, + {{0x3579f26b0282c4b2, 0x64d592f24fafefae, 0xb7cded7b28c8c7c0, 0x6a927b6b7173a8d7}}}, +{{{0x1f6db24f986e4656, 0x1021c02ed1e9105b, 0xf8ff3fff2cc0a375, 0x1d2a6bf8c6c82592}}, + {{0x8d7040863ece88eb, 0xf0e307a980eec08c, 0xac2250610d788fda, 0x056d92a43a0d478d}}, + {{0x1b05a196fc3da5a1, 0x77d7a8c243b59ed0, 0x06da3d6297d17918, 0x66fbb494f12353f7}}}, +{{{0x751a50b9d85c0fb8, 0xd1afdc258bcf097b, 0x2f16a6a38309a969, 0x14ddff9ee5b00659}}, + {{0xd6d70996f12309d6, 0xdbfb2385e9c3d539, 0x46d602b0f7552411, 0x270a0b0557843e0c}}, + {{0x61ff0640a7862bcc, 0x81cac09a5f11abfe, 0x9047830455d12abb, 0x19a4bde1945ae873}}}, +{{{0x9b9f26f520a6200a, 0x64804443cf13eaf8, 0x8a63673f8631edd3, 0x72bbbce11ed39dc1}}, + {{0x40c709dec076c49f, 0x657bfaf27f3e53f6, 0x40662331eca042c4, 0x14b375487eb4df04}}, + {{0xae853c94ab66dc47, 0xeb62343edf762d6e, 0xf08e0e186fb2f7d1, 0x4f0b1c02700ab37a}}}, +{{{0xe1706787d81951fa, 0xa10a2c8eb290c77b, 0xe7382fa03ed66773, 0x0a4d84710bcc4b54}}, + {{0x79fd21ccc1b2e23f, 0x4ae7c281453df52a, 0xc8172ec9d151486b, 0x68abe9443e0a7534}}, + {{0xda12c6c407831dcb, 0x0da230d74d5c510d, 0x4ab1531e6bd404e1, 0x4106b166bcf440ef}}}, +{{{0x02e57a421cd23668, 0x4ad9fb5d0eaef6fd, 0x954e6727b1244480, 0x7f792f9d2699f331}}, + {{0xa485ccd539e4ecf2, 0x5aa3f3ad0555bab5, 0x145e3439937df82d, 0x1238b51e1214283f}}, + {{0x0b886b925fd4d924, 0x60906f7a3626a80d, 0xecd367b4b98abd12, 0x2876beb1def344cf}}}, +{{{0xdc84e93563144691, 0x632fe8a0d61f23f4, 0x4caa800612a9a8d5, 0x48f9dbfa0e9918d3}}, + {{0xd594b3333a8a85f8, 0x4ea37689e78d7d58, 0x73bf9f455e8e351f, 0x5507d7d2bc41ebb4}}, + {{0x1ceb2903299572fc, 0x7c8ccaa29502d0ee, 0x91bfa43411cce67b, 0x5784481964a831e7}}}, +{{{0xda7c2b256768d593, 0x98c1c0574422ca13, 0xf1a80bd5ca0ace1d, 0x29cdd1adc088a690}}, + {{0xd6cfd1ef5fddc09c, 0xe82b3efdf7575dce, 0x25d56b5d201634c2, 0x3041c6bb04ed2b9b}}, + {{0x0ff2f2f9d956e148, 0xade797759f356b2e, 0x1a4698bb5f6c025c, 0x104bbd6814049a7b}}}, +{{{0x51f0fd3168f1ed67, 0x2c811dcdd86f3bc2, 0x44dc5c4304d2f2de, 0x5be8cc57092a7149}}, + {{0xa95d9a5fd67ff163, 0xe92be69d4cc75681, 0xb7f8024cde20f257, 0x204f2a20fb072df5}}, + {{0xc8143b3d30ebb079, 0x7589155abd652e30, 0x653c3c318f6d5c31, 0x2570fb17c279161f}}}, +{{{0x3efa367f2cb61575, 0xf5f96f761cd6026c, 0xe8c7142a65b52562, 0x3dcb65ea53030acd}}, + {{0x192ea9550bb8245a, 0xc8e6fba88f9050d1, 0x7986ea2d88a4c935, 0x241c5f91de018668}}, + {{0x28d8172940de6caa, 0x8fbf2cf022d9733a, 0x16d7fcdd235b01d1, 0x08420edd5fcdf0e5}}}, +{{{0xcdff20ab8362fa4a, 0x57e118d4e21a3e6e, 0xe3179617fc39e62b, 0x0d9a53efbc1769fd}}, + {{0x0358c34e04f410ce, 0xb6135b5a276e0685, 0x5d9670c7ebb91521, 0x04d654f321db889c}}, + {{0x5e7dc116ddbdb5d5, 0x2954deb68da5dd2d, 0x1cb608173334a292, 0x4a7a4f2618991ad7}}}, +{{{0xf4a718025fb15f95, 0x3df65f346b5c1b8f, 0xcdfcf08500e01112, 0x11b50c4cddd31848}}, + {{0x24c3b291af372a4b, 0x93da8270718147f2, 0xdd84856486899ef2, 0x4a96314223e0ee33}}, + {{0xa6e8274408a4ffd6, 0x738e177e9c1576d9, 0x773348b63d02b3f2, 0x4f4bce4dce6bcc51}}}, +{{{0xa71fce5ae2242584, 0x26ea725692f58a9e, 0xd21a09d71cea3cf4, 0x73fcdd14b71c01e6}}, + {{0x30e2616ec49d0b6f, 0xe456718fcaec2317, 0x48eb409bf26b4fa6, 0x3042cee561595f37}}, + {{0x427e7079449bac41, 0x855ae36dbce2310a, 0x4cae76215f841a7c, 0x389e740c9a9ce1d6}}}, +{{{0x64fcb3ae34dcb9ce, 0x97500323e348d0ad, 0x45b3f07d62c6381b, 0x61545379465a6788}}, + {{0xc9bd78f6570eac28, 0xe55b0b3227919ce1, 0x65fc3eaba19b91ed, 0x25c425e5d6263690}}, + {{0x3f3e06a6f1d7de6e, 0x3ef976278e062308, 0x8c14f6264e8a6c77, 0x6539a08915484759}}}, +{{{0xe9d21f74c3d2f773, 0xc150544125c46845, 0x624e5ce8f9b99e33, 0x11c5e4aac5cd186c}}, + {{0xddc4dbd414bb4a19, 0x19b2bc3c98424f8e, 0x48a89fd736ca7169, 0x0f65320ef019bd90}}, + {{0xd486d1b1cafde0c6, 0x4f3fe6e3163b5181, 0x59a8af0dfaf2939a, 0x4cabc7bdec33072a}}}, +{{{0x16faa8fb532f7428, 0xdbd42ea046a4e272, 0x5337653b8b9ea480, 0x4065947223973f03}}, + {{0xf7c0a19c1a54a044, 0x4a1c5e2477bd9fbb, 0xa6e3ca115af22972, 0x1819bb953f2e9e0d}}, + {{0x498fbb795e042e84, 0x7d0dd89a7698b714, 0x8bfb0ba427fe6295, 0x36ba82e721200524}}}, +{{{0xd60ecbb74245ec41, 0xfd9be89e34348716, 0xc9240afee42284de, 0x4472f648d0531db4}}, + {{0xc8d69d0a57274ed5, 0x45ba803260804b17, 0xdf3cda102255dfac, 0x77d221232709b339}}, + {{0x498a6d7064ad94d8, 0xa5b5c8fd9af62263, 0x8ca8ed0545c141f4, 0x2c63bec3662d358c}}}, +{{{0x7fe60d8bea787955, 0xb9dc117eb5f401b7, 0x91c7c09a19355cce, 0x22692ef59442bedf}}, + {{0x9a518b3a8586f8bf, 0x9ee71af6cbb196f0, 0xaa0625e6a2385cf2, 0x1deb2176ddd7c8d1}}, + {{0x8563d19a2066cf6c, 0x401bfd8c4dcc7cd7, 0xd976a6becd0d8f62, 0x67cfd773a278b05e}}}, +{{{0x8dec31faef3ee475, 0x99dbff8a9e22fd92, 0x512d11594e26cab1, 0x0cde561eec4310b9}}, + {{0x2d5fa9855a4e586a, 0x65f8f7a449beab7e, 0xaa074dddf21d33d3, 0x185cba721bcb9dee}}, + {{0x93869da3f4e3cb41, 0xbf0392f540f7977e, 0x026204fcd0463b83, 0x3ec91a769eec6eed}}}, +{{{0x1e9df75bf78166ad, 0x4dfda838eb0cd7af, 0xba002ed8c1eaf988, 0x13fedb3e11f33cfc}}, + {{0x0fad2fb7b0a3402f, 0x46615ecbfb69f4a8, 0xf745bcc8c5f8eaa6, 0x7a5fa8794a94e896}}, + {{0x52958faa13cd67a1, 0x965ee0818bdbb517, 0x16e58daa2e8845b3, 0x357d397d5499da8f}}}, +{{{0x1ebfa05fb0bace6c, 0xc934620c1caf9a1e, 0xcc771cc41d82b61a, 0x2d94a16aa5f74fec}}, + {{0x481dacb4194bfbf8, 0x4d77e3f1bae58299, 0x1ef4612e7d1372a0, 0x3a8d867e70ff69e1}}, + {{0x6f58cd5d55aff958, 0xba3eaa5c75567721, 0x75c123999165227d, 0x69be1343c2f2b35e}}}, +{{{0x0e091d5ee197c92a, 0x4f51019f2945119f, 0x143679b9f034e99c, 0x7d88112e4d24c696}}, + {{0x82bbbdac684b8de3, 0xa2f4c7d03fca0718, 0x337f92fbe096aaa8, 0x200d4d8c63587376}}, + {{0x208aed4b4893b32b, 0x3efbf23ebe59b964, 0xd762deb0dba5e507, 0x69607bd681bd9d94}}}, +{{{0xf6be021068de1ce1, 0xe8d518e70edcbc1f, 0xe3effdd01b5505a5, 0x35f63353d3ec3fd0}}, + {{0x3b7f3bd49323a902, 0x7c21b5566b2c6e53, 0xe5ba8ff53a7852a7, 0x28bc77a5838ece00}}, + {{0x63ba78a8e25d8036, 0x63651e0094333490, 0x48d82f20288ce532, 0x3a31abfa36b57524}}}, +{{{0x239e9624089c0a2e, 0xc748c4c03afe4738, 0x17dbed2a764fa12a, 0x639b93f0321c8582}}, + {{0xc08f788f3f78d289, 0xfe30a72ca1404d9f, 0xf2778bfccf65cc9d, 0x7ee498165acb2021}}, + {{0x7bd508e39111a1c3, 0x2b2b90d480907489, 0xe7d2aec2ae72fd19, 0x0edf493c85b602a6}}}, +{{{0xaecc8158599b5a68, 0xea574f0febade20e, 0x4fe41d7422b67f07, 0x403b92e3019d4fb4}}, + {{0x6767c4d284764113, 0xa090403ff7f5f835, 0x1c8fcffacae6bede, 0x04c00c54d1dfa369}}, + {{0x4dc22f818b465cf8, 0x71a0f35a1480eff8, 0xaee8bfad04c7d657, 0x355bb12ab26176f4}}}, +{{{0xa71e64cc7493bbf4, 0xe5bd84d9eca3b0c3, 0x0a6bc50cfa05e785, 0x0f9b8132182ec312}}, + {{0xa301dac75a8c7318, 0xed90039db3ceaa11, 0x6f077cbf3bae3f2d, 0x7518eaf8e052ad8e}}, + {{0xa48859c41b7f6c32, 0x0f2d60bcf4383298, 0x1815a929c9b1d1d9, 0x47c3871bbb1755c4}}}, +{{{0x5144539771ec4f48, 0xf805b17dc98c5d6e, 0xf762c11a47c3c66b, 0x00b89b85764699dc}}, + {{0xfbe65d50c85066b0, 0x62ecc4b0b3a299b0, 0xe53754ea441ae8e0, 0x08fea02ce8d48d5f}}, + {{0x824ddd7668deead0, 0xc86445204b685d23, 0xb514cfcd5d89d665, 0x473829a74f75d537}}}, +{{{0x82d2da754679c418, 0xe63bd7d8b2618df0, 0x355eef24ac47eb0a, 0x2078684c4833c6b4}}, + {{0x23d9533aad3902c9, 0x64c2ddceef03588f, 0x15257390cfe12fb4, 0x6c668b4d44e4d390}}, + {{0x3b48cf217a78820c, 0xf76a0ab281273e97, 0xa96c65a78c8eed7b, 0x7411a6054f8a433f}}}, +{{{0x4d659d32b99dc86d, 0x044cdc75603af115, 0xb34c712cdcc2e488, 0x7c136574fb8134ff}}, + {{0x579ae53d18b175b4, 0x68713159f392a102, 0x8455ecba1eef35f5, 0x1ec9a872458c398f}}, + {{0xb8e6a4d400a2509b, 0x9b81d7020bc882b4, 0x57e7cc9bf1957561, 0x3add88a5c7cd6460}}}, +{{{0xab895770b635dcf2, 0x02dfef6cf66c1fbc, 0x85530268beb6d187, 0x249929fccc879e74}}, + {{0x85c298d459393046, 0x8f7e35985ff659ec, 0x1d2ca22af2f66e3a, 0x61ba1131a406a720}}, + {{0xa3d0a0f116959029, 0x023b6b6cba7ebd89, 0x7bf15a3e26783307, 0x5620310cbbd8ece7}}}, +{{{0x528993434934d643, 0xb9dbf806a51222f5, 0x8f6d878fc3f41c22, 0x37676a2a4d9d9730}}, + {{0x6646b5f477e285d6, 0x40e8ff676c8f6193, 0xa6ec7311abb594dd, 0x7ec846f3658cec4d}}, + {{0x9b5e8f3f1da22ec7, 0x130f1d776c01cd13, 0x214c8fcfa2989fb8, 0x6daaf723399b9dd5}}}, +{{{0x591e4a5610628564, 0x2a4bb87ca8b4df34, 0xde2a2572e7a38e43, 0x3cbdabd9fee5046e}}, + {{0x81aebbdd2cd13070, 0x962e4325f85a0e9e, 0xde9391aacadffecb, 0x53177fda52c230e6}}, + {{0xa7bc970650b9de79, 0x3d12a7fbc301b59b, 0x02652e68d36ae38c, 0x79d739835a6199dc}}}, +{{{0xd9354df64131c1bd, 0x758094a186ec5822, 0x4464ee12e459f3c2, 0x6c11fce4cb133282}}, + {{0x21c9d9920d591737, 0x9bea41d2e9b46cd6, 0xe20e84200d89bfca, 0x79d99f946eae5ff8}}, + {{0xf17b483568673205, 0x387deae83caad96c, 0x61b471fd56ffe386, 0x31741195b745a599}}}, +{{{0xe8d10190b77a360b, 0x99b983209995e702, 0xbd4fdff8fa0247aa, 0x2772e344e0d36a87}}, + {{0x17f8ba683b02a047, 0x50212096feefb6c8, 0x70139be21556cbe2, 0x203e44a11d98915b}}, + {{0xd6863eba37b9e39f, 0x105bc169723b5a23, 0x104f6459a65c0762, 0x567951295b4d38d4}}}, +{{{0x535fd60613037524, 0xe210adf6b0fbc26a, 0xac8d0a9b23e990ae, 0x47204d08d72fdbf9}}, + {{0x07242eb30d4b497f, 0x1ef96306b9bccc87, 0x37950934d8116f45, 0x05468d6201405b04}}, + {{0x00f565a9f93267de, 0xcecfd78dc0d58e8a, 0xa215e2dcf318e28e, 0x4599ee919b633352}}}, +{{{0xd3c220ca70e0e76b, 0xb12bea58ea9f3094, 0x294ddec8c3271282, 0x0c3539e1a1d1d028}}, + {{0xac746d6b861ae579, 0x31ab0650f6aea9dc, 0x241d661140256d4c, 0x2f485e853d21a5de}}, + {{0x329744839c0833f3, 0x6fe6257fd2abc484, 0x5327d1814b358817, 0x65712585893fe9bc}}}, +{{{0x9c102fb732a61161, 0xe48e10dd34d520a8, 0x365c63546f9a9176, 0x32f6fe4c046f6006}}, + {{0x81c29f1bd708ee3f, 0xddcb5a05ae6407d0, 0x97aec1d7d2a3eba7, 0x1590521a91d50831}}, + {{0x40a3a11ec7910acc, 0x9013dff8f16d27ae, 0x1a9720d8abb195d4, 0x1bb9fe452ea98463}}}, +{{{0xe9d1d950b3d54f9e, 0x2d5f9cbee00d33c1, 0x51c2c656a04fc6ac, 0x65c091ee3c1cbcc9}}, + {{0xcf5e6c95cc36747c, 0x294201536b0bc30d, 0x453ac67cee797af0, 0x5eae6ab32a8bb3c9}}, + {{0x7083661114f118ea, 0x2b37b87b94349cad, 0x7273f51cb4e99f40, 0x78a2a95823d75698}}}, +{{{0xa2b072e95c8c2ace, 0x69cffc96651e9c4b, 0x44328ef842e7b42b, 0x5dd996c122aadeb3}}, + {{0xb4f23c425ef83207, 0xabf894d3c9a934b5, 0xd0708c1339fd87f7, 0x1876789117166130}}, + {{0x925b5ef0670c507c, 0x819bc842b93c33bf, 0x10792e9a70dd003f, 0x59ad4b7a6e28dc74}}}, +{{{0x5f3a7562eb3dbe47, 0xf7ea38548ebda0b8, 0x00c3e53145747299, 0x1304e9e71627d551}}, + {{0x583b04bfacad8ea2, 0x29b743e8148be884, 0x2b1e583b0810c5db, 0x2b5449e58eb3bbaa}}, + {{0x789814d26adc9cfe, 0x3c1bab3f8b48dd0b, 0xda0fe1fff979c60a, 0x4468de2d7c2dd693}}}, +{{{0x51bb355e9419469e, 0x33e6dc4c23ddc754, 0x93a5b6d6447f9962, 0x6cce7c6ffb44bd63}}, + {{0x4b9ad8c6f86307ce, 0x21113531435d0c28, 0xd4a866c5657a772c, 0x5da6427e63247352}}, + {{0x1a94c688deac22ca, 0xb9066ef7bbae1ff8, 0x88ad8c388d59580f, 0x58f29abfe79f2ca8}}}, +{{{0xe90ecfab8de73e68, 0x54036f9f377e76a5, 0xf0495b0bbe015982, 0x577629c4a7f41e36}}, + {{0x4b5a64bf710ecdf6, 0xb14ce538462c293c, 0x3643d056d50b3ab9, 0x6af93724185b4870}}, + {{0x3220024509c6a888, 0xd2e036134b558973, 0x83e236233c33289f, 0x701f25bb0caec18f}}}, +{{{0xc3a8b0f8e4616ced, 0xf700660e9e25a87d, 0x61e3061ff4bca59c, 0x2e0c92bfbdc40be9}}, + {{0x9d18f6d97cbec113, 0x844a06e674bfdbe4, 0x20f5b522ac4e60d6, 0x720a5bc050955e51}}, + {{0x0c3f09439b805a35, 0xe84e8b376242abfc, 0x691417f35c229346, 0x0e9b9cbb144ef0ec}}}, +{{{0xfbbad48ffb5720ad, 0xee81916bdbf90d0e, 0xd4813152635543bf, 0x221104eb3f337bd8}}, + {{0x8dee9bd55db1beee, 0xc9c3ab370a723fb9, 0x44a8f1bf1c68d791, 0x366d44191cfd3cde}}, + {{0x9e3c1743f2bc8c14, 0x2eda26fcb5856c3b, 0xccb82f0e68a7fb97, 0x4167a4e6bc593244}}}, +{{{0x643b9d2876f62700, 0x5d1d9d400e7668eb, 0x1b4b430321fc0684, 0x7938bb7e2255246a}}, + {{0xc2be2665f8ce8fee, 0xe967ff14e880d62c, 0xf12e6e7e2f364eee, 0x34b33370cb7ed2f6}}, + {{0xcdc591ee8681d6cc, 0xce02109ced85a753, 0xed7485c158808883, 0x1176fc6e2dfe65e4}}}, +{{{0xb4af6cd05b9c619b, 0x2ddfc9f4b2a58480, 0x3d4fa502ebe94dc4, 0x08fc3a4c677d5f34}}, + {{0xdb90e28949770eb8, 0x98fbcc2aacf440a3, 0x21354ffeded7879b, 0x1f6a3e54f26906b6}}, + {{0x60a4c199d30734ea, 0x40c085b631165cd6, 0xe2333e23f7598295, 0x4f2fad0116b900d1}}}, +{{{0x44beb24194ae4e54, 0x5f541c511857ef6c, 0xa61e6b2d368d0498, 0x445484a4972ef7ab}}, + {{0x962cd91db73bb638, 0xe60577aafc129c08, 0x6f619b39f3b61689, 0x3451995f2944ee81}}, + {{0x9152fcd09fea7d7c, 0x4a816c94b0935cf6, 0x258e9aaa47285c40, 0x10b89ca6042893b7}}}, +{{{0x9b2a426e3b646025, 0x32127190385ce4cf, 0xa25cffc2dd6dea45, 0x06409010bea8de75}}, + {{0xd67cded679d34aa0, 0xcc0b9ec0cc4db39f, 0xa535a456e35d190f, 0x2e05d9eaf61f6fef}}, + {{0xc447901ad61beb59, 0x661f19bce5dc880a, 0x24685482b7ca6827, 0x293c778cefe07f26}}}, +{{{0x86809e7007069096, 0xaad75b15e4e50189, 0x07f35715a21a0147, 0x0487f3f112815d5e}}, + {{0x16c795d6a11ff200, 0xcb70d0e2b15815c9, 0x89f293209b5395b5, 0x50b8c2d031e47b4f}}, + {{0x48350c08068a4962, 0x6ffdd05351092c9a, 0x17af4f4aaf6fc8dd, 0x4b0553b53cdba58b}}}, +{{{0x9c65fcbe1b32ff79, 0xeb75ea9f03b50f9b, 0xfced2a6c6c07e606, 0x35106cd551717908}}, + {{0xbf05211b27c152d4, 0x5ec26849bd1af639, 0x5e0b2caa8e6fab98, 0x054c8bdd50bd0840}}, + {{0x38a0b12f1dcf073d, 0x4b60a8a3b7f6a276, 0xfed5ac25d3404f9a, 0x72e82d5e5505c229}}}, +{{{0x6b0b697ff0d844c8, 0xbb12f85cd979cb49, 0xd2a541c6c1da0f1f, 0x7b7c242958ce7211}}, + {{0x00d9cdfd69771d02, 0x410276cd6cfbf17e, 0x4c45306c1cb12ec7, 0x2857bf1627500861}}, + {{0x9f21903f0101689e, 0xd779dfd3bf861005, 0xa122ee5f3deb0f1b, 0x510df84b485a00d4}}}, +{{{0xa54133bb9277a1fa, 0x74ec3b6263991237, 0x1a3c54dc35d2f15a, 0x2d347144e482ba3a}}, + {{0x24b3c887c70ac15e, 0xb0f3a557fb81b732, 0x9b2cde2fe578cc1b, 0x4cf7ed0703b54f8e}}, + {{0x6bd47c6598fbee0f, 0x9e4733e2ab55be2d, 0x1093f624127610c5, 0x4e05e26ad0a1eaa4}}}, +{{{0xda9b6b624b531f20, 0x429a760e77509abb, 0xdbe9f522e823cb80, 0x618f1856880c8f82}}, + {{0x1833c773e18fe6c0, 0xe3c4711ad3c87265, 0x3bfd3c4f0116b283, 0x1955875eb4cd4db8}}, + {{0x6da6de8f0e399799, 0x7ad61aa440fda178, 0xb32cd8105e3563dd, 0x15f6beae2ae340ae}}}, +{{{0x862bcb0c31ec3a62, 0x810e2b451138f3c2, 0x788ec4b839dac2a4, 0x28f76867ae2a9281}}, + {{0xba9a0f7b9245e215, 0xf368612dd98c0dbb, 0x2e84e4cbf220b020, 0x6ba92fe962d90eda}}, + {{0x3e4df9655884e2aa, 0xbd62fbdbdbd465a5, 0xd7596caa0de9e524, 0x6e8042ccb2b1b3d7}}}, +{{{0xf10d3c29ce28ca6e, 0xbad34540fcb6093d, 0xe7426ed7a2ea2d3f, 0x08af9d4e4ff298b9}}, + {{0x1530653616521f7e, 0x660d06b896203dba, 0x2d3989bc545f0879, 0x4b5303af78ebd7b0}}, + {{0x72f8a6c3bebcbde8, 0x4f0fca4adc3a8e89, 0x6fa9d4e8c7bfdf7a, 0x0dcf2d679b624eb7}}}, +{{{0x3d5947499718289c, 0x12ebf8c524533f26, 0x0262bfcb14c3ef15, 0x20b878d577b7518e}}, + {{0x753941be5a45f06e, 0xd07caeed6d9c5f65, 0x11776b9c72ff51b6, 0x17d2d1d9ef0d4da9}}, + {{0x27f2af18073f3e6a, 0xfd3fe519d7521069, 0x22e3b72c3ca60022, 0x72214f63cc65c6a7}}}, +{{{0xb4e37f405307a693, 0xaba714d72f336795, 0xd6fbd0a773761099, 0x5fdf48c58171cbc9}}, + {{0x1d9db7b9f43b29c9, 0xd605824a4f518f75, 0xf2c072bd312f9dc4, 0x1f24ac855a1545b0}}, + {{0x24d608328e9505aa, 0x4748c1d10c1420ee, 0xc7ffe45c06fb25a2, 0x00ba739e2ae395e6}}}, +{{{0x592e98de5c8790d6, 0xe5bfb7d345c2a2df, 0x115a3b60f9b49922, 0x03283a3e67ad78f3}}, + {{0xae4426f5ea88bb26, 0x360679d984973bfb, 0x5c9f030c26694e50, 0x72297de7d518d226}}, + {{0x48241dc7be0cb939, 0x32f19b4d8b633080, 0xd3dfc90d02289308, 0x05e1296846271945}}}, +{{{0xba82eeb32d9c495a, 0xceefc8fcf12bb97c, 0xb02dabae93b5d1e0, 0x39c00c9c13698d9b}}, + {{0xadbfbbc8242c4550, 0xbcc80cecd03081d9, 0x843566a6f5c8df92, 0x78cf25d38258ce4c}}, + {{0x15ae6b8e31489d68, 0xaa851cab9c2bf087, 0xc9a75a97f04efa05, 0x006b52076b3ff832}}}, +{{{0x29e0cfe19d95781c, 0xb681df18966310e2, 0x57df39d370516b39, 0x4d57e3443bc76122}}, + {{0xf5cb7e16b9ce082d, 0x3407f14c417abc29, 0xd4b36bce2bf4a7ab, 0x7de2e9561a9f75ce}}, + {{0xde70d4f4b6a55ecb, 0x4801527f5d85db99, 0xdbc9c440d3ee9a81, 0x6b2a90af1a6029ed}}}, +{{{0x6923f4fc9ae61e97, 0x5735281de03f5fd1, 0xa764ae43e6edd12d, 0x5fd8f4e9d12d3e4a}}, + {{0x77ebf3245bb2d80a, 0xd8301b472fb9079b, 0xc647e6f24cee7333, 0x465812c8276c2109}}, + {{0x4d43beb22a1062d9, 0x7065fb753831dc16, 0x180d4a7bde2968d7, 0x05b32c2b1cb16790}}}, +{{{0xc8c05eccd24da8fd, 0xa1cf1aac05dfef83, 0xdbbeeff27df9cd61, 0x3b5556a37b471e99}}, + {{0xf7fca42c7ad58195, 0x3214286e4333f3cc, 0xb6c29d0d340b979d, 0x31771a48567307e1}}, + {{0x32b0c524e14dd482, 0xedb351541a2ba4b6, 0xa3d16048282b5af3, 0x4fc079d27a7336eb}}}, +{{{0x51c938b089bf2f7f, 0x2497bd6502dfe9a7, 0xffffc09c7880e453, 0x124567cecaf98e92}}, + {{0xdc348b440c86c50d, 0x1337cbc9cc94e651, 0x6422f74d643e3cb9, 0x241170c2bae3cd08}}, + {{0x3ff9ab860ac473b4, 0xf0911dee0113e435, 0x4ae75060ebc6c4af, 0x3f8612966c87000d}}}, +{{{0x0c9c5303f7957be4, 0xa3c31a20e085c145, 0xb0721d71d0850050, 0x0aba390eab0bf2da}}, + {{0x529fdffe638c7bf3, 0xdf2b9e60388b4995, 0xe027b34f1bad0249, 0x7bc92fc9b9fa74ed}}, + {{0x9f97ef2e801ad9f9, 0x83697d5479afda3a, 0xe906b3ffbd596b50, 0x02672b37dd3fb8e0}}}, +{{{0x48b2ca8b260885e4, 0xa4286bec82b34c1c, 0x937e1a2617f58f74, 0x741d1fcbab2ca2a5}}, + {{0xee9ba729398ca7f5, 0xeb9ca6257a4849db, 0x29eb29ce7ec544e1, 0x232ca21ef736e2c8}}, + {{0xbf61423d253fcb17, 0x08803ceafa39eb14, 0xf18602df9851c7af, 0x0400f3a049e3414b}}}, +{{{0xabce0476ba61c55b, 0x36a3d6d7c4d39716, 0x6eb259d5e8d82d09, 0x0c9176e984d756fb}}, + {{0x2efba412a06e7b06, 0x146785452c8d2560, 0xdf9713ebd67a91c7, 0x32830ac7157eadf3}}, + {{0x0e782a7ab73769e8, 0x04a05d7875b18e2c, 0x29525226ebcceae1, 0x0d794f8383eba820}}}, +{{{0xff35f5cb9e1516f4, 0xee805bcf648aae45, 0xf0d73c2bb93a9ef3, 0x097b0bf22092a6c2}}, + {{0x7be44ce7a7a2e1ac, 0x411fd93efad1b8b7, 0x1734a1d70d5f7c9b, 0x0d6592233127db16}}, + {{0xc48bab1521a9d733, 0xa6c2eaead61abb25, 0x625c6c1cc6cb4305, 0x7fc90fea93eb3a67}}}, +{{{0x0408f1fe1f5c5926, 0x1a8f2f5e3b258bf4, 0x40a951a2fdc71669, 0x6598ee93c98b577e}}, + {{0xc527deb59c7cb23d, 0x955391695328404e, 0xd64392817ccf2c7a, 0x6ce97dabf7d8fa11}}, + {{0x25b5a8e50ef7c48f, 0xeb6034116f2ce532, 0xc5e75173e53de537, 0x73119fa08c12bb03}}}, +{{{0xed30129453f1a4cb, 0xbce621c9c8f53787, 0xfacb2b1338bee7b9, 0x3025798a9ea8428c}}, + {{0x7845b94d21f4774d, 0xbf62f16c7897b727, 0x671857c03c56522b, 0x3cd6a85295621212}}, + {{0x3fecde923aeca999, 0xbdaa5b0062e8c12f, 0x67b99dfc96988ade, 0x3f52c02852661036}}}, +{{{0xffeaa48e2a1351c6, 0x28624754fa7f53d7, 0x0b5ba9e57582ddf1, 0x60c0104ba696ac59}}, + {{0x9258bf99eec416c6, 0xac8a5017a9d2f671, 0x629549ab16dea4ab, 0x05d0e85c99091569}}, + {{0x051de020de9cbe97, 0xfa07fc56b50bcf74, 0x378cec9f0f11df65, 0x36853c69ab96de4d}}}, +{{{0x36d9b8de78f39b2d, 0x7f42ed71a847b9ec, 0x241cd1d679bd3fde, 0x6a704fec92fbce6b}}, + {{0x4433c0b0fac5e7be, 0x724bae854c08dcbe, 0xf1f24cc446978f9b, 0x4a0aff6d62825fc8}}, + {{0xe917fb9e61095301, 0xc102df9402a092f8, 0xbf09e2f5fa66190b, 0x681109bee0dcfe37}}}, +{{{0x559a0cc9782a0dde, 0x551dcdb2ea718385, 0x7f62865b31ef238c, 0x504aa7767973613d}}, + {{0x9c18fcfa36048d13, 0x29159db373899ddd, 0xdc9f350b9f92d0aa, 0x26f57eee878a19d4}}, + {{0x0cab2cd55687efb1, 0x5180d162247af17b, 0x85c15a344f5a2467, 0x4041943d9dba3069}}}, +{{{0xc3c0eeba43ebcc96, 0x8d749c9c26ea9caf, 0xd9fa95ee1c77ccc6, 0x1420a1d97684340f}}, + {{0x4b217743a26caadd, 0x47a6b424648ab7ce, 0xcb1d4f7a03fbc9e3, 0x12d931429800d019}}, + {{0x00c67799d337594f, 0x5e3c5140b23aa47b, 0x44182854e35ff395, 0x1b4f92314359a012}}}, +{{{0x3e5c109d89150951, 0x39cefa912de9696a, 0x20eae43f975f3020, 0x239b572a7f132dae}}, + {{0x33cf3030a49866b1, 0x251f73d2215f4859, 0xab82aa4051def4f6, 0x5ff191d56f9a23f6}}, + {{0x819ed433ac2d9068, 0x2883ab795fc98523, 0xef4572805593eb3d, 0x020c526a758f36cb}}}, +{{{0x779834f89ed8dbbc, 0xc8f2aaf9dc7ca46c, 0xa9524cdca3e1b074, 0x02aacc4615313877}}, + {{0xe931ef59f042cc89, 0x2c589c9d8e124bb6, 0xadc8e18aaec75997, 0x452cfe0a5602c50c}}, + {{0x86a0f7a0647877df, 0xbbc464270e607c9f, 0xab17ea25f1fb11c9, 0x4cfb7d7b304b877b}}}, +{{{0x72b43d6cb89b75fe, 0x54c694d99c6adc80, 0xb8c3aa373ee34c9f, 0x14b4622b39075364}}, + {{0xe28699c29789ef12, 0x2b6ecd71df57190d, 0xc343c857ecc970d0, 0x5b1d4cbc434d3ac5}}, + {{0xb6fb2615cc0a9f26, 0x3a4f0e2bb88dcce5, 0x1301498b3369a705, 0x2f98f71258592dd1}}}, +{{{0x0c94a74cb50f9e56, 0x5b1ff4a98e8e1320, 0x9a2acc2182300f67, 0x3a6ae249d806aaf9}}, + {{0x2e12ae444f54a701, 0xfcfe3ef0a9cbd7de, 0xcebf890d75835de0, 0x1d8062e9e7614554}}, + {{0x657ada85a9907c5a, 0x1a0ea8b591b90f62, 0x8d0e1dfbdf34b4e9, 0x298b8ce8aef25ff3}}}, +{{{0x2a927953eff70cb2, 0x4b89c92a79157076, 0x9418457a30a7cf6a, 0x34b8a8404d5ce485}}, + {{0x837a72ea0a2165de, 0x3fab07b40bcf79f6, 0x521636c77738ae70, 0x6ba6271803a7d7dc}}, + {{0xc26eecb583693335, 0xd5a813df63b5fefd, 0xa293aa9aa4b22573, 0x71d62bdd465e1c6a}}}, +{{{0x6533cc28d378df80, 0xf6db43790a0fa4b4, 0xe3645ff9f701da5a, 0x74d5f317f3172ba4}}, + {{0xcd2db5dab1f75ef5, 0xd77f95cf16b065f5, 0x14571fea3f49f085, 0x1c333621262b2b3d}}, + {{0xa86fe55467d9ca81, 0x398b7c752b298c37, 0xda6d0892e3ac623b, 0x4aebcc4547e9d98c}}}, +{{{0x53175a7205d21a77, 0xb0c04422d3b934d4, 0xadd9f24bdd5deadc, 0x074f46e69f10ff8c}}, + {{0x0de9b204a059a445, 0xe15cb4aa4b17ad0f, 0xe1bbec521f79c557, 0x2633f1b9d071081b}}, + {{0xc1fb4177018b9910, 0xa6ea20dc6c0fe140, 0xd661f3e74354c6ff, 0x5ecb72e6f1a3407a}}}, +{{{0xa515a31b2259fb4e, 0x0960f3972bcac52f, 0xedb52fec8d3454cb, 0x382e2720c476c019}}, + {{0xfeeae106e8e86997, 0x9863337f98d09383, 0x9470480eaa06ebef, 0x038b6898d4c5c2d0}}, + {{0xf391c51d8ace50a6, 0x3142d0b9ae2d2948, 0xdb4d5a1a7f24ca80, 0x21aeba8b59250ea8}}}, +{{{0x24f13b34cf405530, 0x3c44ea4a43088af7, 0x5dd5c5170006a482, 0x118eb8f8890b086d}}, + {{0x53853600f0087f23, 0x4c461879da7d5784, 0x6af303deb41f6860, 0x0a3c16c5c27c18ed}}, + {{0x17e49c17cc947f3d, 0xccc6eda6aac1d27b, 0xdf6092ceb0f08e56, 0x4909b3e22c67c36b}}}, +{{{0x9c9c85ea63fe2e89, 0xbe1baf910e9412ec, 0x8f7baa8a86fbfe7b, 0x0fb17f9fef968b6c}}, + {{0x59a16676706ff64e, 0x10b953dd0d86a53d, 0x5848e1e6ce5c0b96, 0x2d8b78e712780c68}}, + {{0x79d5c62eafc3902b, 0x773a215289e80728, 0xc38ae640e10120b9, 0x09ae23717b2b1a6d}}}, +{{{0xbb6a192a4e4d083c, 0x34ace0630029e192, 0x98245a59aafabaeb, 0x6d9c8a9ada97faac}}, + {{0x10ab8fa1ad32b1d0, 0xe9aced1be2778b24, 0xa8856bc0373de90f, 0x66f35ddddda53996}}, + {{0xd27d9afb24997323, 0x1bb7e07ef6f01d2e, 0x2ba7472df52ecc7f, 0x03019b4f646f9dc8}}}, +{{{0x04a186b5565345cd, 0xeee76610bcc4116a, 0x689c73b478fb2a45, 0x387dcbff65697512}}, + {{0xaf09b214e6b3dc6b, 0x3f7573b5ad7d2f65, 0xd019d988100a23b0, 0x392b63a58b5c35f7}}, + {{0x4093addc9c07c205, 0xc565be15f532c37e, 0x63dbecfd1583402a, 0x61722b4aef2e032e}}}, +{{{0x0012aafeecbd47af, 0x55a266fb1cd46309, 0xf203eb680967c72c, 0x39633944ca3c1429}}, + {{0xd6b07a5581cb0e3c, 0x290ff006d9444969, 0x08680b6a16dcda1f, 0x5568d2b75a06de59}}, + {{0x8d0cb88c1b37cfe1, 0x05b6a5a3053818f3, 0xf2e9bc04b787d959, 0x6beba1249add7f64}}}, +{{{0x1d06005ca5b1b143, 0x6d4c6bb87fd1cda2, 0x6ef5967653fcffe7, 0x097c29e8c1ce1ea5}}, + {{0x5c3cecb943f5a53b, 0x9cc9a61d06c08df2, 0xcfba639a85895447, 0x5a845ae80df09fd5}}, + {{0x4ce97dbe5deb94ca, 0x38d0a4388c709c48, 0xc43eced4a169d097, 0x0a1249fff7e587c3}}}, +{{{0x12f0071b276d01c9, 0xe7b8bac586c48c70, 0x5308129b71d6fba9, 0x5d88fbf95a3db792}}, + {{0x0b408d9e7354b610, 0x806b32535ba85b6e, 0xdbe63a034a58a207, 0x173bd9ddc9a1df2c}}, + {{0x2b500f1efe5872df, 0x58d6582ed43918c1, 0xe6ed278ec9673ae0, 0x06e1cd13b19ea319}}}, +{{{0x40d0ad516f166f23, 0x118e32931fab6abe, 0x3fe35e14a04d088e, 0x3080603526e16266}}, + {{0x472baf629e5b0353, 0x3baa0b90278d0447, 0x0c785f469643bf27, 0x7f3a6a1a8d837b13}}, + {{0xf7e644395d3d800b, 0x95a8d555c901edf6, 0x68cd7830592c6339, 0x30d0fded2e51307e}}}, +{{{0xe0594d1af21233b3, 0x1bdbe78ef0cc4d9c, 0x6965187f8f499a77, 0x0a9214202c099868}}, + {{0x9cb4971e68b84750, 0xa09572296664bbcf, 0x5c8de72672fa412b, 0x4615084351c589d9}}, + {{0xbc9019c0aeb9a02e, 0x55c7110d16034cae, 0x0e6df501659932ec, 0x3bca0d2895ca5dfe}}}, +{{{0x40f031bc3c5d62a4, 0x19fc8b3ecff07a60, 0x98183da2130fb545, 0x5631deddae8f13cd}}, + {{0x9c688eb69ecc01bf, 0xf0bc83ada644896f, 0xca2d955f5f7a9fe2, 0x4ea8b4038df28241}}, + {{0x2aed460af1cad202, 0x46305305a48cee83, 0x9121774549f11a5f, 0x24ce0930542ca463}}}, +{{{0x1fe890f5fd06c106, 0xb5c468355d8810f2, 0x827808fe6e8caf3e, 0x41d4e3c28a06d74b}}, + {{0x3fcfa155fdf30b85, 0xd2f7168e36372ea4, 0xb2e064de6492f844, 0x549928a7324f4280}}, + {{0xf26e32a763ee1a2e, 0xae91e4b7d25ffdea, 0xbc3bd33bd17f4d69, 0x491b66dec0dcff6a}}}, +{{{0x98f5b13dc7ea32a7, 0xe3d5f8cc7e16db98, 0xac0abf52cbf8d947, 0x08f338d0c85ee4ac}}, + {{0x75f04a8ed0da64a1, 0xed222caf67e2284b, 0x8234a3791f7b7ba4, 0x4cf6b8b0b7018b67}}, + {{0xc383a821991a73bd, 0xab27bc01df320c7a, 0xc13d331b84777063, 0x530d4a82eb078a99}}}, +{{{0x004c3630e1f94825, 0x7e2d78268cab535a, 0xc7482323cc84ff8b, 0x65ea753f101770b9}}, + {{0x6d6973456c9abf9e, 0x257fb2fc4900a880, 0x2bacf412c8cfb850, 0x0db3e7e00cbfbd5b}}, + {{0x3d66fc3ee2096363, 0x81d62c7f61b5cb6b, 0x0fbe044213443b1a, 0x02a4ec1921e1a1db}}}, +{{{0x5ce6259a3b24b8a2, 0xb8577acc45afa0b8, 0xcccbe6e88ba07037, 0x3d143c51127809bf}}, + {{0xf5c86162f1cf795f, 0x118c861926ee57f2, 0x172124851c063578, 0x36d12b5dec067fcf}}, + {{0x126d279179154557, 0xd5e48f5cfc783a0a, 0x36bdb6e8df179bac, 0x2ef517885ba82859}}}, +{{{0x88bd438cd11e0d4a, 0x30cb610d43ccf308, 0xe09a0e3791937bcc, 0x4559135b25b1720c}}, + {{0x1ea436837c6da1e9, 0xf9c189af1fb9bdbe, 0x303001fcce5dd155, 0x28a7c99ebc57be52}}, + {{0xb8fd9399e8d19e9d, 0x908191cb962423ff, 0xb2b948d747c742a3, 0x37f33226d7fb44c4}}}, +{{{0x0dae8767b55f6e08, 0x4a43b3b35b203a02, 0xe3725a6e80af8c79, 0x0f7a7fd1705fa7a3}}, + {{0x33912553c821b11d, 0x66ed42c241e301df, 0x066fcc11104222fd, 0x307a3b41c192168f}}, + {{0x8eeb5d076eb55ce0, 0x2fc536bfaa0d925a, 0xbe81830fdcb6c6e8, 0x556c7045827baf52}}}, +{{{0x8e2b517302e9d8b7, 0xe3e52269248714e8, 0xbd4fbd774ca960b5, 0x6f4b4199c5ecada9}}, + {{0xb94b90022bf44406, 0xabd4237eff90b534, 0x7600a960faf86d3a, 0x2f45abdac2322ee3}}, + {{0x61af4912c8ef8a6a, 0xe58fa4fe43fb6e5e, 0xb5afcc5d6fd427cf, 0x6a5393281e1e11eb}}}, +{{{0xf3da5139a5d1ee89, 0x8145457cff936988, 0x3f622fed00e188c4, 0x0f513815db8b5a3d}}, + {{0x0fff04fe149443cf, 0x53cac6d9865cddd7, 0x31385b03531ed1b7, 0x5846a27cacd1039d}}, + {{0x4ff5cdac1eb08717, 0x67e8b29590f2e9bc, 0x44093b5e237afa99, 0x0d414bed8708b8b2}}}, +{{{0xcfb68265fd0e75f6, 0xe45b3e28bb90e707, 0x7242a8de9ff92c7a, 0x685b3201933202dd}}, + {{0x81886a92294ac9e8, 0x23162b45d55547be, 0x94cfbc4403715983, 0x50eb8fdb134bc401}}, + {{0xc0b73ec6d6b330cd, 0x84e44807132faff1, 0x732b7352c4a5dee1, 0x5d7c7cf1aa7cd2d2}}}, +{{{0xaf3b46bf7a4aafa2, 0xb78705ec4d40d411, 0x114f0c6aca7c15e3, 0x3f364faaa9489d4d}}, + {{0x33d1013e9b73a562, 0x925cef5748ec26e1, 0xa7fce614dd468058, 0x78b0fad41e9aa438}}, + {{0xbf56a431ed05b488, 0xa533e66c9c495c7e, 0xe8652baf87f3651a, 0x0241800059d66c33}}}, +{{{0xceb077fea37a5be4, 0xdb642f02e5a5eeb7, 0xc2e6d0c5471270b8, 0x4771b65538e4529c}}, + {{0x28350c7dcf38ea01, 0x7c6cdbc0b2917ab6, 0xace7cfbe857082f7, 0x4d2845aba2d9a1e0}}, + {{0xbb537fe0447070de, 0xcba744436dd557df, 0xd3b5a3473600dbcb, 0x4aeabbe6f9ffd7f8}}}, +{{{0x4630119e40d8f78c, 0xa01a9bc53c710e11, 0x486d2b258910dd79, 0x1e6c47b3db0324e5}}, + {{0x6a2134bcc4a9c8f2, 0xfbf8fd1c8ace2e37, 0x000ae3049911a0ba, 0x046e3a616bc89b9e}}, + {{0x14e65442f03906be, 0x4a019d54e362be2a, 0x68ccdfec8dc230c7, 0x7cfb7e3faf6b861c}}}, +{{{0x4637974e8c58aedc, 0xb9ef22fbabf041a4, 0xe185d956e980718a, 0x2f1b78fab143a8a6}}, + {{0x96eebffb305b2f51, 0xd3f938ad889596b8, 0xf0f52dc746d5dd25, 0x57968290bb3a0095}}, + {{0xf71ab8430a20e101, 0xf393658d24f0ec47, 0xcf7509a86ee2eed1, 0x7dc43e35dc2aa3e1}}}, +{{{0x85966665887dd9c3, 0xc90f9b314bb05355, 0xc6e08df8ef2079b1, 0x7ef72016758cc12f}}, + {{0x5a782a5c273e9718, 0x3576c6995e4efd94, 0x0f2ed8051f237d3e, 0x044fb81d82d50a99}}, + {{0xc1df18c5a907e3d9, 0x57b3371dce4c6359, 0xca704534b201bb49, 0x7f79823f9c30dd2e}}}, +{{{0x8334d239a3b513e8, 0xc13670d4b91fa8d8, 0x12b54136f590bd33, 0x0a4e0373d784d9b4}}, + {{0x6a9c1ff068f587ba, 0x0827894e0050c8de, 0x3cbf99557ded5be7, 0x64a9b0431c06d6f0}}, + {{0x2eb3d6a15b7d2919, 0xb0b4f6a0d53a8235, 0x7156ce4389a45d47, 0x071a7d0ace18346c}}}, +{{{0xd3072daac887ba0b, 0x01262905bfa562ee, 0xcf543002c0ef768b, 0x2c3bcc7146ea7e9c}}, + {{0xcc0c355220e14431, 0x0d65950709b15141, 0x9af5621b209d5f36, 0x7c69bcf7617755d3}}, + {{0x07f0d7eb04e8295f, 0x10db18252f50f37d, 0xe951a9a3171798d7, 0x6f5a9a7322aca51d}}}, +{{{0x8ba1000c2f41c6c5, 0xc49f79c10cfefb9b, 0x4efa47703cc51c9f, 0x494e21a2e147afca}}, + {{0xe729d4eba3d944be, 0x8d9e09408078af9e, 0x4525567a47869c03, 0x02ab9680ee8d3b24}}, + {{0xefa48a85dde50d9a, 0x219a224e0fb9a249, 0xfa091f1dd91ef6d9, 0x6b5d76cbea46bb34}}}, +{{{0x8857556cec0cd994, 0x6472dc6f5cd01dba, 0xaf0169148f42b477, 0x0ae333f685277354}}, + {{0xe0f941171e782522, 0xf1e6ae74036936d3, 0x408b3ea2d0fcc746, 0x16fb869c03dd313e}}, + {{0x288e199733b60962, 0x24fc72b4d8abe133, 0x4811f7ed0991d03e, 0x3f81e38b8f70d075}}}, +{{{0x7f910fcc7ed9affe, 0x545cb8a12465874b, 0xa8397ed24b0c4704, 0x50510fc104f50993}}, + {{0x0adb7f355f17c824, 0x74b923c3d74299a4, 0xd57c3e8bcbf8eaf7, 0x0ad3e2d34cdedc3d}}, + {{0x6f0c0fc5336e249d, 0x745ede19c331cfd9, 0xf2d6fd0009eefe1c, 0x127c158bf0fa1ebe}}}, +{{{0xf6197c422e9879a2, 0xa44addd452ca3647, 0x9b413fc14b4eaccb, 0x354ef87d07ef4f68}}, + {{0xdea28fc4ae51b974, 0x1d9973d3744dfe96, 0x6240680b873848a8, 0x4ed82479d167df95}}, + {{0xfee3b52260c5d975, 0x50352efceb41b0b8, 0x8808ac30a9f6653c, 0x302d92d20539236d}}}, +{{{0x4c59023fcb3efb7c, 0x6c2fcb99c63c2a94, 0xba4190e2c3c7e084, 0x0e545daea51874d9}}, + {{0x957b8b8b0df53c30, 0x2a1c770a8e60f098, 0xbbc7a670345796de, 0x22a48f9a90c99bc9}}, + {{0x6b7dc0dc8d3fac58, 0x5497cd6ce6e42bfd, 0x542f7d1bf400d305, 0x4159f47f048d9136}}}, +{{{0x20ad660839e31e32, 0xf81e1bd58405be50, 0xf8064056f4dabc69, 0x14d23dd4ce71b975}}, + {{0x748515a8bbd24839, 0x77128347afb02b55, 0x50ba2ac649a2a17f, 0x060525513ad730f1}}, + {{0xf2398e098aa27f82, 0x6d7982bb89a1b024, 0xfa694084214dd24c, 0x71ab966fa32301c3}}}, +{{{0x2dcbd8e34ded02fc, 0x1151f3ec596f22aa, 0xbca255434e0328da, 0x35768fbe92411b22}}, + {{0xb1088a0702809955, 0x43b273ea0b43c391, 0xca9b67aefe0686ed, 0x605eecbf8335f4ed}}, + {{0x83200a656c340431, 0x9fcd71678ee59c2f, 0x75d4613f71300f8a, 0x7a912faf60f542f9}}}, +{{{0xb204585e5edc1a43, 0x9f0e16ee5897c73c, 0x5b82c0ae4e70483c, 0x624a170e2bddf9be}}, + {{0x253f4f8dfa2d5597, 0x25e49c405477130c, 0x00c052e5996b1102, 0x33cb966e33bb6c4a}}, + {{0x597028047f116909, 0x828ac41c1e564467, 0x70417dbde6217387, 0x721627aefbac4384}}}, +{{{0x97d03bc38736add5, 0x2f1422afc532b130, 0x3aa68a057101bbc4, 0x4c946cf7e74f9fa7}}, + {{0xfd3097bc410b2f22, 0xf1a05da7b5cfa844, 0x61289a1def57ca74, 0x245ea199bb821902}}, + {{0xaedca66978d477f8, 0x1898ba3c29117fe1, 0xcf73f983720cbd58, 0x67da12e6b8b56351}}}, +{{{0x7067e187b4bd6e07, 0x6e8f0203c7d1fe74, 0x93c6aa2f38c85a30, 0x76297d1f3d75a78a}}, + {{0x2b7ef3d38ec8308c, 0x828fd7ec71eb94ab, 0x807c3b36c5062abd, 0x0cb64cb831a94141}}, + {{0x3030fc33534c6378, 0xb9635c5ce541e861, 0x15d9a9bed9b2c728, 0x49233ea3f3775dcb}}}, +{{{0x629398fa8dbffc3a, 0xe12fe52dd54db455, 0xf3be11dfdaf25295, 0x628b140dce5e7b51}}, + {{0x7b3985fe1c9f249b, 0x4fd6b2d5a1233293, 0xceb345941adf4d62, 0x6987ff6f542de50c}}, + {{0x47e241428f83753c, 0x6317bebc866af997, 0xdabb5b433d1a9829, 0x074d8d245287fb2d}}}, +{{{0x8337d9cd440bfc31, 0x729d2ca1af318fd7, 0xa040a4a4772c2070, 0x46002ef03a7349be}}, + {{0x481875c6c0e31488, 0x219429b2e22034b4, 0x7223c98a31283b65, 0x3420d60b342277f9}}, + {{0xfaa23adeaffe65f7, 0x78261ed45be0764c, 0x441c0a1e2f164403, 0x5aea8e567a87d395}}}, +{{{0x7813c1a2bca4283d, 0xed62f091a1863dd9, 0xaec7bcb8c268fa86, 0x10e5d3b76f1cae4c}}, + {{0x2dbc6fb6e4e0f177, 0x04e1bf29a4bd6a93, 0x5e1966d4787af6e8, 0x0edc5f5eb426d060}}, + {{0x5453bfd653da8e67, 0xe9dc1eec24a9f641, 0xbf87263b03578a23, 0x45b46c51361cba72}}}, +{{{0xa9402abf314f7fa1, 0xe257f1dc8e8cf450, 0x1dbbd54b23a8be84, 0x2177bfa36dcb713b}}, + {{0xce9d4ddd8a7fe3e4, 0xab13645676620e30, 0x4b594f7bb30e9958, 0x5c1c0aef321229df}}, + {{0x37081bbcfa79db8f, 0x6048811ec25f59b3, 0x087a76659c832487, 0x4ae619387d8ab5bb}}}, +{{{0x8ddbf6aa5344a32e, 0x7d88eab4b41b4078, 0x5eb0eb974a130d60, 0x1a00d91b17bf3e03}}, + {{0x61117e44985bfb83, 0xfce0462a71963136, 0x83ac3448d425904b, 0x75685abe5ba43d64}}, + {{0x6e960933eb61f2b2, 0x543d0fa8c9ff4952, 0xdf7275107af66569, 0x135529b623b0e6aa}}}, +{{{0x18f0dbd7add1d518, 0x979f7888cfc11f11, 0x8732e1f07114759b, 0x79b5b81a65ca3a01}}, + {{0xf5c716bce22e83fe, 0xb42beb19e80985c1, 0xec9da63714254aae, 0x5972ea051590a613}}, + {{0x0fd4ac20dc8f7811, 0x9a9ad294ac4d4fa8, 0xc01b2d64b3360434, 0x4f7e9c95905f3bdb}}}, +{{{0x62674bbc5781302e, 0xd8520f3989addc0f, 0x8c2999ae53fbd9c6, 0x31993ad92e638e4c}}, + {{0x71c8443d355299fe, 0x8bcd3b1cdbebead7, 0x8092499ef1a49466, 0x1942eec4a144adc8}}, + {{0x7dac5319ae234992, 0x2c1b3d910cea3e92, 0x553ce494253c1122, 0x2a0a65314ef9ca75}}}, +{{{0x2db7937ff7f927c2, 0xdb741f0617d0a635, 0x5982f3a21155af76, 0x4cf6e218647c2ded}}, + {{0xcf361acd3c1c793a, 0x2f9ebcac5a35bc3b, 0x60e860e9a8cda6ab, 0x055dc39b6dea1a13}}, + {{0xb119227cc28d5bb6, 0x07e24ebc774dffab, 0xa83c78cee4a32c89, 0x121a307710aa24b6}}}, +{{{0xe4db5d5e9f034a97, 0xe153fc093034bc2d, 0x460546919551d3b1, 0x333fc76c7a40e52d}}, + {{0xd659713ec77483c9, 0x88bfe077b82b96af, 0x289e28231097bcd3, 0x527bb94a6ced3a9b}}, + {{0x563d992a995b482e, 0x3405d07c6e383801, 0x485035de2f64d8e5, 0x6b89069b20a7a9f7}}}, +{{{0x812aa0416270220d, 0x995a89faf9245b4e, 0xffadc4ce5072ef05, 0x23bc2103aa73eb73}}, + {{0x4082fa8cb5c7db77, 0x068686f8c734c155, 0x29e6c8d9f6e7a57e, 0x0473d308a7639bcf}}, + {{0xcaee792603589e05, 0x2b4b421246dcc492, 0x02a1ef74e601a94f, 0x102f73bfde04341a}}}, +{{{0xb5a2d50c7ec20d3e, 0xc64bdd6ea0c97263, 0x56e89052c1ff734d, 0x4929c6f72b2ffaba}}, + {{0x358ecba293a36247, 0xaf8f9862b268fd65, 0x412f7e9968a01c89, 0x5786f312cd754524}}, + {{0x337788ffca14032c, 0xf3921028447f1ee3, 0x8b14071f231bccad, 0x4c817b4bf2344783}}}, +{{{0x0ff853852871b96e, 0xe13e9fab60c3f1bb, 0xeefd595325344402, 0x0a37c37075b7744b}}, + {{0x413ba057a40b4484, 0xba4c2e1a4f5f6a43, 0x614ba0a5aee1d61c, 0x78a1531a8b05dc53}}, + {{0x6cbdf1703ad0562b, 0x8ecf4830c92521a3, 0xdaebd303fd8424e7, 0x72ad82a42e5ec56f}}}, +{{{0x3f9e8e35bafb65f6, 0x39d69ec8f27293a1, 0x6cb8cd958cf6a3d0, 0x1734778173adae6d}}, + {{0xc368939167024bc3, 0x8e69d16d49502fda, 0xfcf2ec3ce45f4b29, 0x065f669ea3b4cbc4}}, + {{0x8a00aec75532db4d, 0xb869a4e443e31bb1, 0x4a0f8552d3a7f515, 0x19adeb7c303d7c08}}}, +{{{0xc720cb6153ead9a3, 0x55b2c97f512b636e, 0xb1e35b5fd40290b1, 0x2fd9ccf13b530ee2}}, + {{0x9d05ba7d43c31794, 0x2470c8ff93322526, 0x8323dec816197438, 0x2852709881569b53}}, + {{0x07bd475b47f796b8, 0xd2c7b013542c8f54, 0x2dbd23f43b24f87e, 0x6551afd77b0901d6}}}, +{{{0x4546baaf54aac27f, 0xf6f66fecb2a45a28, 0x582d1b5b562bcfe8, 0x44b123f3920f785f}}, + {{0x68a24ce3a1d5c9ac, 0xbb77a33d10ff6461, 0x0f86ce4425d3166e, 0x56507c0950b9623b}}, + {{0x1206f0b7d1713e63, 0x353fe3d915bafc74, 0x194ceb970ad9d94d, 0x62fadd7cf9d03ad3}}}, +{{{0xc6b5967b5598a074, 0x5efe91ce8e493e25, 0xd4b72c4549280888, 0x20ef1149a26740c2}}, + {{0x3cd7bc61e7ce4594, 0xcd6b35a9b7dd267e, 0xa080abc84366ef27, 0x6ec7c46f59c79711}}, + {{0x2f07ad636f09a8a2, 0x8697e6ce24205e7d, 0xc0aefc05ee35a139, 0x15e80958b5f9d897}}}, +{{{0x25a5ef7d0c3e235b, 0x6c39c17fbe134ee7, 0xc774e1342dc5c327, 0x021354b892021f39}}, + {{0x4dd1ed355bb061c4, 0x42dc0cef941c0700, 0x61305dc1fd86340e, 0x56b2cc930e55a443}}, + {{0x1df79da6a6bfc5a2, 0x02f3a2749fde4369, 0xb323d9f2cda390a7, 0x7be0847b8774d363}}}, +{{{0x8c99cc5a8b3f55c3, 0x0611d7253fded2a0, 0xed2995ff36b70a36, 0x1f699a54d78a2619}}, + {{0x1466f5af5307fa11, 0x817fcc7ded6c0af2, 0x0a6de44ec3a4a3fb, 0x74071475bc927d0b}}, + {{0xe77292f373e7ea8a, 0x296537d2cb045a31, 0x1bd0653ed3274fde, 0x2f9a2c4476bd2966}}}, +{{{0xeb18b9ab7f5745c6, 0x023a8aee5787c690, 0xb72712da2df7afa9, 0x36597d25ea5c013d}}, + {{0xa2b4dae0b5511c9a, 0x7ac860292bffff06, 0x981f375df5504234, 0x3f6bd725da4ea12d}}, + {{0x734d8d7b106058ac, 0xd940579e6fc6905f, 0x6466f8f99202932d, 0x7b7ecc19da60d6d0}}}, +{{{0x78c2373c695c690d, 0xdd252e660642906e, 0x951d44444ae12bd2, 0x4235ad7601743956}}, + {{0x6dae4a51a77cfa9b, 0x82263654e7a38650, 0x09bbffcd8f2d82db, 0x03bedc661bf5caba}}, + {{0x6258cb0d078975f5, 0x492942549189f298, 0xa0cab423e2e36ee4, 0x0e7ce2b0cdf066a1}}}, +{{{0xc494643ac48c85a3, 0xfd361df43c6139ad, 0x09db17dd3ae94d48, 0x666e0a5d8fb4674a}}, + {{0xfea6fedfd94b70f9, 0xf130c051c1fcba2d, 0x4882d47e7f2fab89, 0x615256138aeceeb5}}, + {{0x2abbf64e4870cb0d, 0xcd65bcf0aa458b6b, 0x9abe4eba75e8985d, 0x7f0bc810d514dee4}}}, +{{{0xb9006ba426f4136f, 0x8d67369e57e03035, 0xcbc8dfd94f463c28, 0x0d1f8dbcf8eedbf5}}, + {{0x83ac9dad737213a0, 0x9ff6f8ba2ef72e98, 0x311e2edd43ec6957, 0x1d3a907ddec5ab75}}, + {{0xba1693313ed081dc, 0x29329fad851b3480, 0x0128013c030321cb, 0x00011b44a31bfde3}}}, +{{{0x3fdfa06c3fc66c0c, 0x5d40e38e4dd60dd2, 0x7ae38b38268e4d71, 0x3ac48d916e8357e1}}, + {{0x16561f696a0aa75c, 0xc1bf725c5852bd6a, 0x11a8dd7f9a7966ad, 0x63d988a2d2851026}}, + {{0x00120753afbd232e, 0xe92bceb8fdd8f683, 0xf81669b384e72b91, 0x33fad52b2368a066}}}, +{{{0x540649c6c5e41e16, 0x0af86430333f7735, 0xb2acfcd2f305e746, 0x16c0f429a256dca7}}, + {{0x8d2cc8d0c422cfe8, 0x072b4f7b05a13acb, 0xa3feb6e6ecf6a56f, 0x3cc355ccb90a71e2}}, + {{0xe9b69443903e9131, 0xb8a494cb7a5637ce, 0xc87cd1a4baba9244, 0x631eaf426bae7568}}}, +{{{0xb3e90410da66fe9f, 0x85dd4b526c16e5a6, 0xbc3d97611ef9bf83, 0x5599648b1ea919b5}}, + {{0x47d975b9a3700de8, 0x7280c5fbe2f80552, 0x53658f2732e45de1, 0x431f2c7f665f80b5}}, + {{0xd6026344858f7b19, 0x14ab352fa1ea514a, 0x8900441a2090a9d7, 0x7b04715f91253b26}}}, +{{{0x83edbd28acf6ae43, 0x86357c8b7d5c7ab4, 0xc0404769b7eb2c44, 0x59b37bf5c2f6583f}}, + {{0xb376c280c4e6bac6, 0x970ed3dd6d1d9b0b, 0xb09a9558450bf944, 0x48d0acfa57cde223}}, + {{0xb60f26e47dabe671, 0xf1d1a197622f3a37, 0x4208ce7ee9960394, 0x16234191336d3bdb}}}, +{{{0xf19aeac733a63aef, 0x2c7fba5d4442454e, 0x5da87aa04795e441, 0x413051e1a4e0b0f5}}, + {{0x852dd1fd3d578bbe, 0x2b65ce72c3286108, 0x658c07f4eace2273, 0x0933f804ec38ab40}}, + {{0xa7ab69798d496476, 0x8121aadefcb5abc8, 0xa5dc12ef7b539472, 0x07fd47065e45351a}}}, +{{{0xc8583c3d258d2bcd, 0x17029a4daf60b73f, 0xfa0fc9d6416a3781, 0x1c1e5fba38b3fb23}}, + {{0x304211559ae8e7c3, 0xf281b229944882a5, 0x8a13ac2e378250e4, 0x014afa0954ba48f4}}, + {{0xcb3197001bb3666c, 0x330060524bffecb9, 0x293711991a88233c, 0x291884363d4ed364}}}, +{{{0x033c6805dc4babfa, 0x2c15bf5e5596ecc1, 0x1bc70624b59b1d3b, 0x3ede9850a19f0ec5}}, + {{0xfb9d37c3bc1ab6eb, 0x02be14534d57a240, 0xf4d73415f8a5e1f6, 0x5964f4300ccc8188}}, + {{0xe44a23152d096800, 0x5c08c55970866996, 0xdf2db60a46affb6e, 0x579155c1f856fd89}}}, +{{{0x96324edd12e0c9ef, 0x468b878df2420297, 0x199a3776a4f573be, 0x1e7fbcf18e91e92a}}, + {{0xb5f16b630817e7a6, 0x808c69233c351026, 0x324a983b54cef201, 0x53c092084a485345}}, + {{0xd2d41481f1cbafbf, 0x231d2db6716174e5, 0x0b7d7656e2a55c98, 0x3e955cd82aa495f6}}}, +{{{0xe48f535e3ed15433, 0xd075692a0d7270a3, 0x40fbd21daade6387, 0x14264887cf4495f5}}, + {{0xab39f3ef61bb3a3f, 0x8eb400652eb9193e, 0xb5de6ecc38c11f74, 0x654d7e9626f3c49f}}, + {{0xe564cfdd5c7d2ceb, 0x82eeafded737ccb9, 0x6107db62d1f9b0ab, 0x0b6baac3b4358dbb}}}, +{{{0x7ae62bcb8622fe98, 0x47762256ceb891af, 0x1a5a92bcf2e406b4, 0x7d29401784e41501}}, + {{0x204abad63700a93b, 0xbe0023d3da779373, 0xd85f0346633ab709, 0x00496dc490820412}}, + {{0x1c74b88dc27e6360, 0x074854268d14850c, 0xa145fb7b3e0dcb30, 0x10843f1b43803b23}}}, +{{{0xc5f90455376276dd, 0xce59158dd7645cd9, 0x92f65d511d366b39, 0x11574b6e526996c4}}, + {{0xd56f672de324689b, 0xd1da8aedb394a981, 0xdd7b58fe9168cfed, 0x7ce246cd4d56c1e8}}, + {{0xb8f4308e7f80be53, 0x5f3cb8cb34a9d397, 0x18a961bd33cc2b2c, 0x710045fb3a9af671}}}, +{{{0x73f93d36101b95eb, 0xfaef33794f6f4486, 0x5651735f8f15e562, 0x7fa3f19058b40da1}}, + {{0xa03fc862059d699e, 0x2370cfa19a619e69, 0xc4fe3b122f823deb, 0x1d1b056fa7f0844e}}, + {{0x1bc64631e56bf61f, 0xd379ab106e5382a3, 0x4d58c57e0540168d, 0x566256628442d8e4}}}, +{{{0xb9e499def6267ff6, 0x7772ca7b742c0843, 0x23a0153fe9a4f2b1, 0x2cdfdfecd5d05006}}, + {{0xdd499cd61ff38640, 0x29cd9bc3063625a0, 0x51e2d8023dd73dc3, 0x4a25707a203b9231}}, + {{0x2ab7668a53f6ed6a, 0x304242581dd170a1, 0x4000144c3ae20161, 0x5721896d248e49fc}}}, +{{{0x0b6e5517fd181bae, 0x9022629f2bb963b4, 0x5509bce932064625, 0x578edd74f63c13da}}, + {{0x285d5091a1d0da4e, 0x4baa6fa7b5fe3e08, 0x63e5177ce19393b3, 0x03c935afc4b030fd}}, + {{0x997276c6492b0c3d, 0x47ccc2c4dfe205fc, 0xdcd29b84dd623a3c, 0x3ec2ab590288c7a2}}}, +{{{0xa1a0d27be4d87bb9, 0xa98b4deb61391aed, 0x99a0ddd073cb9b83, 0x2dd5c25a200fcace}}, + {{0xa7213a09ae32d1cb, 0x0f2b87df40f5c2d5, 0x0baea4c6e81eab29, 0x0e1bf66c6adbac5e}}, + {{0xe2abd5e9792c887e, 0x1a020018cb926d5d, 0xbfba69cdbaae5f1e, 0x730548b35ae88f5f}}}, +{{{0xc43551a3cba8b8ee, 0x65a26f1db2115f16, 0x760f4f52ab8c3850, 0x3043443b411db8ca}}, + {{0x805b094ba1d6e334, 0xbf3ef17709353f19, 0x423f06cb0622702b, 0x585a2277d87845dd}}, + {{0xa18a5f8233d48962, 0x6698c4b5ec78257f, 0xa78e6fa5373e41ff, 0x7656278950ef981f}}}, +{{{0x38c3cf59d51fc8c0, 0x9bedd2fd0506b6f2, 0x26bf109fab570e8f, 0x3f4160a8c1b846a6}}, + {{0xe17073a3ea86cf9d, 0x3a8cfbb707155fdc, 0x4853e7fc31838a8e, 0x28bbf484b613f616}}, + {{0xf2612f5c6f136c7c, 0xafead107f6dd11be, 0x527e9ad213de6f33, 0x1e79cb358188f75d}}}, +{{{0x013436c3eef7e3f1, 0x828b6a7ffe9e10f8, 0x7ff908e5bcf9defc, 0x65d7951b3a3b3831}}, + {{0x77e953d8f5e08181, 0x84a50c44299dded9, 0xdc6c2d0c864525e5, 0x478ab52d39d1f2f4}}, + {{0x66a6a4d39252d159, 0xe5dde1bc871ac807, 0xb82c6b40a6c1c96f, 0x16d87a411a212214}}}, +{{{0xb3bd7e5a42066215, 0x879be3cd0c5a24c1, 0x57c05db1d6f994b7, 0x28f87c8165f38ca6}}, + {{0xfba4d5e2d54e0583, 0xe21fafd72ebd99fa, 0x497ac2736ee9778f, 0x1f990b577a5a6dde}}, + {{0xa3344ead1be8f7d6, 0x7d1e50ebacea798f, 0x77c6569e520de052, 0x45882fe1534d6d3e}}}, +{{{0x6669345d757983d6, 0x62b6ed1117aa11a6, 0x7ddd1857985e128f, 0x688fe5b8f626f6dd}}, + {{0xd8ac9929943c6fe4, 0xb5f9f161a38392a2, 0x2699db13bec89af3, 0x7dcf843ce405f074}}, + {{0x6c90d6484a4732c0, 0xd52143fdca563299, 0xb3be28c3915dc6e1, 0x6739687e7327191b}}}, +{{{0x9f65c5ea200814cf, 0x840536e169a31740, 0x8b0ed13925c8b4ad, 0x0080dbafe936361d}}, + {{0x8ce5aad0c9cb971f, 0x1156aaa99fd54a29, 0x41f7247015af9b78, 0x1fe8cca8420f49aa}}, + {{0x72a1848f3c0cc82a, 0x38c560c2877c9e54, 0x5004e228ce554140, 0x042418a103429d71}}}, +{{{0x899dea51abf3ff5f, 0x9b93a8672fc2d8ba, 0x2c38cb97be6ebd5c, 0x114d578497263b5d}}, + {{0x58e84c6f20816247, 0x8db2b2b6e36fd793, 0x977182561d484d85, 0x0822024f8632abd7}}, + {{0xb301bb7c6b1beca3, 0x55393f6dc6eb1375, 0x910d281097b6e4eb, 0x1ad4548d9d479ea3}}}, +{{{0xcd5a7da0389a48fd, 0xb38fa4aa9a78371e, 0xc6d9761b2cdb8e6c, 0x35cf51dbc97e1443}}, + {{0xa06fe66d0fe9fed3, 0xa8733a401c587909, 0x30d14d800df98953, 0x41ce5876c7b30258}}, + {{0x59ac3bc5d670c022, 0xeae67c109b119406, 0x9798bdf0b3782fda, 0x651e3201fd074092}}}, +{{{0xd63d8483ef30c5cf, 0x4cd4b4962361cc0c, 0xee90e500a48426ac, 0x0af51d7d18c14eeb}}, + {{0xa57ba4a01efcae9e, 0x769f4beedc308a94, 0xd1f10eeb3603cb2e, 0x4099ce5e7e441278}}, + {{0x1ac98e4f8a5121e9, 0x7dae9544dbfa2fe0, 0x8320aa0dd6430df9, 0x667282652c4a2fb5}}}, +{{{0x874621f4d86bc9ab, 0xb54c7bbe56fe6fea, 0x077a24257fadc22c, 0x1ab53be419b90d39}}, + {{0xada8b6e02946db23, 0x1c0ce51a7b253ab7, 0x8448c85a66dd485b, 0x7f1fc025d0675adf}}, + {{0xd8ee1b18319ea6aa, 0x004d88083a21f0da, 0x3bd6aa1d883a4f4b, 0x4db9a3a6dfd9fd14}}}, +{{{0x8ce7b23bb99c0755, 0x35c5d6edc4f50f7a, 0x7e1e2ed2ed9b50c3, 0x36305f16e8934da1}}, + {{0xd95b00bbcbb77c68, 0xddbc846a91f17849, 0x7cf700aebe28d9b3, 0x5ce1285c85d31f3e}}, + {{0x31b6972d98b0bde8, 0x7d920706aca6de5b, 0xe67310f8908a659f, 0x50fac2a6efdf0235}}}, +{{{0xf3d3a9f35b880f5a, 0xedec050cdb03e7c2, 0xa896981ff9f0b1a2, 0x49a4ae2bac5e34a4}}, + {{0x295b1c86f6f449bc, 0x51b2e84a1f0ab4dd, 0xc001cb30aa8e551d, 0x6a28d35944f43662}}, + {{0x28bb12ee04a740e0, 0x14313bbd9bce8174, 0x72f5b5e4e8c10c40, 0x7cbfb19936adcd5b}}}, +{{{0xa311ddc26b89792d, 0x1b30b4c6da512664, 0x0ca77b4ccf150859, 0x1de443df1b009408}}, + {{0x8e793a7acc36e6e0, 0xf9fab7a37d586eed, 0x3a4f9692bae1f4e4, 0x1c14b03eff5f447e}}, + {{0x19647bd114a85291, 0x57b76cb21034d3af, 0x6329db440f9d6dfa, 0x5ef43e586a571493}}}, +{{{0xef782014385675a6, 0xa2649f30aafda9e8, 0x4cd1eb505cdfa8cb, 0x46115aba1d4dc0b3}}, + {{0xa66dcc9dc80c1ac0, 0x97a05cf41b38a436, 0xa7ebf3be95dbd7c6, 0x7da0b8f68d7e7dab}}, + {{0xd40f1953c3b5da76, 0x1dac6f7321119e9b, 0x03cc6021feb25960, 0x5a5f887e83674b4b}}}, +{{{0x8f6301cf70a13d11, 0xcfceb815350dd0c4, 0xf70297d4a4bca47e, 0x3669b656e44d1434}}, + {{0x9e9628d3a0a643b9, 0xb5c3cb00e6c32064, 0x9b5302897c2dec32, 0x43e37ae2d5d1c70c}}, + {{0x387e3f06eda6e133, 0x67301d5199a13ac0, 0xbd5ad8f836263811, 0x6a21e6cd4fd5e9be}}}, +{{{0xf1c6170a3046e65f, 0x58712a2a00d23524, 0x69dbbd3c8c82b755, 0x586bf9f1a195ff57}}, + {{0xef4129126699b2e3, 0x71d30847708d1301, 0x325432d01182b0bd, 0x45371b07001e8b36}}, + {{0xa6db088d5ef8790b, 0x5278f0dc610937e5, 0xac0349d261a16eb8, 0x0eafb03790e52179}}}, +{{{0x960555c13748042f, 0x219a41e6820baa11, 0x1c81f73873486d0c, 0x309acc675a02c661}}, + {{0x5140805e0f75ae1d, 0xec02fbe32662cc30, 0x2cebdf1eea92396d, 0x44ae3344c5435bb3}}, + {{0x9cf289b9bba543ee, 0xf3760e9d5ac97142, 0x1d82e5c64f9360aa, 0x62d5221b7f94678f}}}, +{{{0x524c299c18d0936d, 0xc86bb56c8a0c1a0c, 0xa375052edb4a8631, 0x5c0efde4bc754562}}, + {{0x7585d4263af77a3c, 0xdfae7b11fee9144d, 0xa506708059f7193d, 0x14f29a5383922037}}, + {{0xdf717edc25b2d7f5, 0x21f970db99b53040, 0xda9234b7c3ed4c62, 0x5e72365c7bee093e}}}, +{{{0x575bfc074571217f, 0x3779675d0694d95b, 0x9a0a37bbf4191e33, 0x77f1104c47b4eabc}}, + {{0x7d9339062f08b33e, 0x5b9659e5df9f32be, 0xacff3dad1f9ebdfd, 0x70b20555cb7349b7}}, + {{0xbe5113c555112c4c, 0x6688423a9a881fcd, 0x446677855e503b47, 0x0e34398f4a06404a}}}, +{{{0xb67d22d93ecebde8, 0x09b3e84127822f07, 0x743fa61fb05b6d8d, 0x5e5405368a362372}}, + {{0x18930b093e4b1928, 0x7de3e10e73f3f640, 0xf43217da73395d6f, 0x6f8aded6ca379c3e}}, + {{0xe340123dfdb7b29a, 0x487b97e1a21ab291, 0xf9967d02fde6949e, 0x780de72ec8d3de97}}}, +{{{0x0ae28545089ae7bc, 0x388ddecf1c7f4d06, 0x38ac15510a4811b8, 0x0eb28bf671928ce4}}, + {{0x671feaf300f42772, 0x8f72eb2a2a8c41aa, 0x29a17fd797373292, 0x1defc6ad32b587a6}}, + {{0xaf5bbe1aef5195a7, 0x148c1277917b15ed, 0x2991f7fb7ae5da2e, 0x467d201bf8dd2867}}}, +{{{0x7906ee72f7bd2e6b, 0x05d270d6109abf4e, 0x8d5cfe45b941a8a4, 0x44c218671c974287}}, + {{0x745f9d56296bc318, 0x993580d4d8152e65, 0xb0e5b13f5839e9ce, 0x51fc2b28d43921c0}}, + {{0x1b8fd11795e2a98c, 0x1c4e5ee12b6b6291, 0x5b30e7107424b572, 0x6e6b9de84c4f4ac6}}}, +{{{0xdff25fce4b1de151, 0xd841c0c7e11c4025, 0x2554b3c854749c87, 0x2d292459908e0df9}}, + {{0x6b7c5f10f80cb088, 0x736b54dc56e42151, 0xc2b620a5c6ef99c4, 0x5f4c802cc3a06f42}}, + {{0x9b65c8f17d0752da, 0x881ce338c77ee800, 0xc3b514f05b62f9e3, 0x66ed5dd5bec10d48}}}, +{{{0x7d38a1c20bb2089d, 0x808334e196ccd412, 0xc4a70b8c6c97d313, 0x2eacf8bc03007f20}}, + {{0xf0adf3c9cbca047d, 0x81c3b2cbf4552f6b, 0xcfda112d44735f93, 0x1f23a0c77e20048c}}, + {{0xf235467be5bc1570, 0x03d2d9020dbab38c, 0x27529aa2fcf9e09e, 0x0840bef29d34bc50}}}, +{{{0x796dfb35dc10b287, 0x27176bcd5c7ff29d, 0x7f3d43e8c7b24905, 0x0304f5a191c54276}}, + {{0xcd54e06b7f37e4eb, 0x8cc15f87f5e96cca, 0xb8248bb0d3597dce, 0x246affa06074400c}}, + {{0x37d88e68fbe45321, 0x86097548c0d75032, 0x4e9b13ef894a0d35, 0x25a83cac5753d325}}}, +{{{0x10222f48eed8165e, 0x623fc1234b8bcf3a, 0x1e145c09c221e8f0, 0x7ccfa59fca782630}}, + {{0x9f0f66293952b6e2, 0x33db5e0e0934267b, 0xff45252bd609fedc, 0x06be10f5c506e0c9}}, + {{0x1a9615a9b62a345f, 0x22050c564a52fecc, 0xa7a2788528bc0dfe, 0x5e82770a1a1ee71d}}}, +{{{0x35425183ad896a5c, 0xe8673afbe78d52f6, 0x2c66f25f92a35f64, 0x09d04f3b3b86b102}}, + {{0xe802e80a42339c74, 0x34175166a7fffae5, 0x34865d1f1c408cae, 0x2cca982c605bc5ee}}, + {{0xfd2d5d35197dbe6e, 0x207c2eea8be4ffa3, 0x2613d8db325ae918, 0x7a325d1727741d3e}}}, +{{{0xd036b9bbd16dfde2, 0xa2055757c497a829, 0x8e6cc966a7f12667, 0x4d3b1a791239c180}}, + {{0xecd27d017e2a076a, 0xd788689f1636495e, 0x52a61af0919233e5, 0x2a479df17bb1ae64}}, + {{0x9e5eee8e33db2710, 0x189854ded6c43ca5, 0xa41c22c592718138, 0x27ad5538a43a5e9b}}}, +{{{0x2746dd4b15350d61, 0xd03fcbc8ee9521b7, 0xe86e365a138672ca, 0x510e987f7e7d89e2}}, + {{0xcb5a7d638e47077c, 0x8db7536120a1c059, 0x549e1e4d8bedfdcc, 0x080153b7503b179d}}, + {{0xdda69d930a3ed3e3, 0x3d386ef1cd60a722, 0xc817ad58bdaa4ee6, 0x23be8d554fe7372a}}}, +{{{0x95fe919a74ef4fad, 0x3a827becf6a308a2, 0x964e01d309a47b01, 0x71c43c4f5ba3c797}}, + {{0xbc1ef4bd567ae7a9, 0x3f624cb2d64498bd, 0xe41064d22c1f4ec8, 0x2ef9c5a5ba384001}}, + {{0xb6fd6df6fa9e74cd, 0xf18278bce4af267a, 0x8255b3d0f1ef990e, 0x5a758ca390c5f293}}}, +{{{0xa2b72710d9462495, 0x3aa8c6d2d57d5003, 0xe3d400bfa0b487ca, 0x2dbae244b3eb72ec}}, + {{0x8ce0918b1d61dc94, 0x8ded36469a813066, 0xd4e6a829afe8aad3, 0x0a738027f639d43f}}, + {{0x980f4a2f57ffe1cc, 0x00670d0de1839843, 0x105c3f4a49fb15fd, 0x2698ca635126a69c}}}, +{{{0xe765318832b0ba78, 0x381831f7925cff8b, 0x08a81b91a0291fcc, 0x1fb43dcc49caeb07}}, + {{0x2e3d702f5e3dd90e, 0x9e3f0918e4d25386, 0x5e773ef6024da96a, 0x3c004b0c4afa3332}}, + {{0x9aa946ac06f4b82b, 0x1ca284a5a806c4f3, 0x3ed3265fc6cd4787, 0x6b43fd01cd1fd217}}}, +{{{0xc7a75d4b4697c544, 0x15fdf848df0fffbf, 0x2868b9ebaa46785a, 0x5a68d7105b52f714}}, + {{0xb5c742583e760ef3, 0x75dc52b9ee0ab990, 0xbf1427c2072b923f, 0x73420b2d6ff0d9f0}}, + {{0xaf2cf6cb9e851e06, 0x8f593913c62238c4, 0xda8ab89699fbf373, 0x3db5632fea34bc9e}}}, +{{{0xf46eee2bf75dd9d8, 0x0d17b1f6396759a5, 0x1bf2d131499e7273, 0x04321adf49d75f13}}, + {{0x2e4990b1829825d5, 0xedeaeb873e9a8991, 0xeef03d394c704af8, 0x59197ea495df2b0e}}, + {{0x04e16019e4e55aae, 0xe77b437a7e2f92e9, 0xc7ce2dc16f159aa4, 0x45eafdc1f4d70cc0}}}, +{{{0x698401858045d72b, 0x4c22faa2cf2f0651, 0x941a36656b222dc6, 0x5a5eebc80362dade}}, + {{0xb60e4624cfccb1ed, 0x59dbc292bd5c0395, 0x31a09d1ddc0481c9, 0x3f73ceea5d56d940}}, + {{0xb7a7bfd10a4e8dc6, 0xbe57007e44c9b339, 0x60c1207f1557aefa, 0x26058891266218db}}}, +{{{0x59f704a68360ff04, 0xc3d93fde7661e6f4, 0x831b2a7312873551, 0x54ad0c2e4e615d57}}, + {{0x4c818e3cc676e542, 0x5e422c9303ceccad, 0xec07cccab4129f08, 0x0dedfa10b24443b8}}, + {{0xee3b67d5b82b522a, 0x36f163469fa5c1eb, 0xa5b4d2f26ec19fd3, 0x62ecb2baa77a9408}}}, +{{{0xe5ed795261152b3d, 0x4962357d0eddd7d1, 0x7482c8d0b96b4c71, 0x2e59f919a966d8be}}, + {{0x92072836afb62874, 0x5fcd5e8579e104a5, 0x5aad01adc630a14a, 0x61913d5075663f98}}, + {{0x0dc62d361a3231da, 0xfa47583294200270, 0x02d801513f9594ce, 0x3ddbc2a131c05d5c}}}, +{{{0x3f50a50a4ffb81ef, 0xb1e035093bf420bf, 0x9baa8e1cc6aa2cd0, 0x32239861fa237a40}}, + {{0xfb735ac2004a35d1, 0x31de0f433a6607c3, 0x7b8591bfc528d599, 0x55be9a25f5bb050c}}, + {{0x0d005acd33db3dbf, 0x0111b37c80ac35e2, 0x4892d66c6f88ebeb, 0x770eadb16508fbcd}}}, +{{{0x8451f9e05e4e89dd, 0xc06302ffbc793937, 0x5d22749556a6495c, 0x09a6755ca05603fb}}, + {{0xf1d3b681a05071b9, 0x2207659a3592ff3a, 0x5f0169297881e40e, 0x16bedd0e86ba374e}}, + {{0x5ecccc4f2c2737b5, 0x43b79e0c2dccb703, 0x33e008bc4ec43df3, 0x06c1b840f07566c0}}}, +{{{0x7688a5c6a388f877, 0x02a96c14deb2b6ac, 0x64c9f3431b8c2af8, 0x3628435554a1eed6}}, + {{0x69ee9e7f9b02805c, 0xcbff828a547d1640, 0x3d93a869b2430968, 0x46b7b8cd3fe26972}}, + {{0xe9812086fe7eebe0, 0x4cba6be72f515437, 0x1d04168b516efae9, 0x5ea1391043982cb9}}}, +{{{0x49125c9cf4702ee1, 0x4520b71f8b25b32d, 0x33193026501fef7e, 0x656d8997c8d2eb2b}}, + {{0x6f2b3be4d5d3b002, 0xafec33d96a09c880, 0x035f73a4a8bcc4cc, 0x22c5b9284662198b}}, + {{0xcb58c8fe433d8939, 0x89a0cb2e6a8d7e50, 0x79ca955309fbbe5a, 0x0c626616cd7fc106}}}, +{{{0x1ffeb80a4879b61f, 0x6396726e4ada21ed, 0x33c7b093368025ba, 0x471aa0c6f3c31788}}, + {{0x8fdfc379fbf454b1, 0x45a5a970f1a4b771, 0xac921ef7bad35915, 0x42d088dca81c2192}}, + {{0x8fda0f37a0165199, 0x0adadb77c8a0e343, 0x20fbfdfcc875e820, 0x1cf2bea80c2206e7}}}, +{{{0xc2ddf1deb36202ac, 0x92a5fe09d2e27aa5, 0x7d1648f6fc09f1d3, 0x74c2cc0513bc4959}}, + {{0x982d6e1a02c0412f, 0x90fa4c83db58e8fe, 0x01c2f5bcdcb18bc0, 0x686e0c90216abc66}}, + {{0x1fadbadba54395a7, 0xb41a02a0ae0da66a, 0xbf19f598bba37c07, 0x6a12b8acde48430d}}}, +{{{0xf8daea1f39d495d9, 0x592c190e525f1dfc, 0xdb8cbd04c9991d1b, 0x11f7fda3d88f0cb7}}, + {{0x793bdd801aaeeb5f, 0x00a2a0aac1518871, 0xe8a373a31f2136b4, 0x48aab888fc91ef19}}, + {{0x041f7e925830f40e, 0x002d6ca979661c06, 0x86dc9ff92b046a2e, 0x760360928b0493d1}}}, +{{{0x21bb41c6120cf9c6, 0xeab2aa12decda59b, 0xc1a72d020aa48b34, 0x215d4d27e87d3b68}}, + {{0xb43108e5695a0b05, 0x6cb00ee8ad37a38b, 0x5edad6eea3537381, 0x3f2602d4b6dc3224}}, + {{0xc8b247b65bcaf19c, 0x49779dc3b1b2c652, 0x89a180bbd5ece2e2, 0x13f098a3cec8e039}}}, +{{{0x9adc0ff9ce5ec54b, 0x039c2a6b8c2f130d, 0x028007c7f0f89515, 0x78968314ac04b36b}}, + {{0xf3aa57a22796bb14, 0x883abab79b07da21, 0xe54be21831a0391c, 0x5ee7fb38d83205f9}}, + {{0x538dfdcb41446a8e, 0xa5acfda9434937f9, 0x46af908d263c8c78, 0x61d0633c9bca0d09}}}, +{{{0x63744935ffdb2566, 0xc5bd6b89780b68bb, 0x6f1b3280553eec03, 0x6e965fd847aed7f5}}, + {{0xada328bcf8fc73df, 0xee84695da6f037fc, 0x637fb4db38c2a909, 0x5b23ac2df8067bdc}}, + {{0x9ad2b953ee80527b, 0xe88f19aafade6d8d, 0x0e711704150e82cf, 0x79b9bbb9dd95dedc}}}, +{{{0xebb355406a3126c2, 0xd26383a868c8c393, 0x6c0c6429e5b97a82, 0x5065f158c9fd2147}}, + {{0xd1997dae8e9f7374, 0xa032a2f8cfbb0816, 0xcd6cba126d445f0a, 0x1ba811460accb834}}, + {{0x708169fb0c429954, 0xe14600acd76ecf67, 0x2eaab98a70e645ba, 0x3981f39e58a4faf2}}}, +{{{0x18fb8a7559230a93, 0x1d168f6960e6f45d, 0x3a85a94514a93cb5, 0x38dc083705acd0fd}}, + {{0xc845dfa56de66fde, 0xe152a5002c40483a, 0xe9d2e163c7b4f632, 0x30f4452edcbc1b65}}, + {{0x856d2782c5759740, 0xfa134569f99cbecc, 0x8844fc73c0ea4e71, 0x632d9a1a593f2469}}}, +{{{0xf6bb6b15b807cba6, 0x1823c7dfbc54f0d7, 0xbb1d97036e29670b, 0x0b24f48847ed4a57}}, + {{0xbf09fd11ed0c84a7, 0x63f071810d9f693a, 0x21908c2d57cf8779, 0x3a5a7df28af64ba2}}, + {{0xdcdad4be511beac7, 0xa4538075ed26ccf2, 0xe19cff9f005f9a65, 0x34fcf74475481f63}}}, +{{{0xc197e04c789767ca, 0xb8714dcb38d9467d, 0x55de888283f95fa8, 0x3d3bdc164dfa63f7}}, + {{0xa5bb1dab78cfaa98, 0x5ceda267190b72f2, 0x9309c9110a92608e, 0x0119a3042fb374b0}}, + {{0x67a2d89ce8c2177d, 0x669da5f66895d0c1, 0xf56598e5b282a2b0, 0x56c088f1ede20a73}}}, +{{{0x336d3d1110a86e17, 0xd7f388320b75b2fa, 0xf915337625072988, 0x09674c6b99108b87}}, + {{0x581b5fac24f38f02, 0xa90be9febae30cbd, 0x9a2169028acf92f0, 0x038b7ea48359038f}}, + {{0x9f4ef82199316ff8, 0x2f49d282eaa78d4f, 0x0971a5ab5aef3174, 0x6e5e31025969eb65}}}, +{{{0xb16c62f587e593fb, 0x4999eddeca5d3e71, 0xb491c1e014cc3e6d, 0x08f5114789a8dba8}}, + {{0x3304fb0e63066222, 0xfb35068987acba3f, 0xbd1924778c1061a3, 0x3058ad43d1838620}}, + {{0x323c0ffde57663d0, 0x05c3df38a22ea610, 0xbdc78abdac994f9a, 0x26549fa4efe3dc99}}}, +{{{0x738b38d787ce8f89, 0xb62658e24179a88d, 0x30738c9cf151316d, 0x49128c7f727275c9}}, + {{0x04dbbc17f75396b9, 0x69e6a2d7d2f86746, 0xc6409d99f53eabc6, 0x606175f6332e25d2}}, + {{0x4021370ef540e7dd, 0x0910d6f5a1f1d0a5, 0x4634aacd5b06b807, 0x6a39e6356944f235}}}, +{{{0x96cd5640df90f3e7, 0x6c3a760edbfa25ea, 0x24f3ef0959e33cc4, 0x42889e7e530d2e58}}, + {{0x1da1965774049e9d, 0xfbcd6ea198fe352b, 0xb1cbcd50cc5236a6, 0x1f5ec83d3f9846e2}}, + {{0x8efb23c3328ccb75, 0xaf42a207dd876ee9, 0x20fbdadc5dfae796, 0x241e246b06bf9f51}}}, +{{{0x29e68e57ad6e98f6, 0x4c9260c80b462065, 0x3f00862ea51ebb4b, 0x5bc2c77fb38d9097}}, + {{0x7eaafc9a6280bbb8, 0x22a70f12f403d809, 0x31ce40bb1bfc8d20, 0x2bc65635e8bd53ee}}, + {{0xe8d5dc9fa96bad93, 0xe58fb17dde1947dc, 0x681532ea65185fa3, 0x1fdd6c3b034a7830}}}, +{{{0x0a64e28c55dc18fe, 0xe3df9e993399ebdd, 0x79ac432370e2e652, 0x35ff7fc33ae4cc0e}}, + {{0x9c13a6a52dd8f7a9, 0x2dbb1f8c3efdcabf, 0x961e32405e08f7b5, 0x48c8a121bbe6c9e5}}, + {{0xfc415a7c59646445, 0xd224b2d7c128b615, 0x6035c9c905fbb912, 0x42d7a91274429fab}}}, +{{{0x4e6213e3eaf72ed3, 0x6794981a43acd4e7, 0xff547cde6eb508cb, 0x6fed19dd10fcb532}}, + {{0xa9a48947933da5bc, 0x4a58920ec2e979ec, 0x96d8800013e5ac4c, 0x453692d74b48b147}}, + {{0xdd775d99a8559c6f, 0xf42a2140df003e24, 0x5223e229da928a66, 0x063f46ba6d38f22c}}}, +{{{0xd2d242895f536694, 0xca33a2c542939b2c, 0x986fada6c7ddb95c, 0x5a152c042f712d5d}}, + {{0x39843cb737346921, 0xa747fb0738c89447, 0xcb8d8031a245307e, 0x67810f8e6d82f068}}, + {{0x3eeb8fbcd2287db4, 0x72c7d3a301a03e93, 0x5473e88cbd98265a, 0x7324aa515921b403}}}, +{{{0x857942f46c3cbe8e, 0xa1d364b14730c046, 0x1c8ed914d23c41bf, 0x0838e161eef6d5d2}}, + {{0xad23f6dae82354cb, 0x6962502ab6571a6d, 0x9b651636e38e37d1, 0x5cac5005d1a3312f}}, + {{0x8cc154cce9e39904, 0x5b3a040b84de6846, 0xc4d8a61cb1be5d6e, 0x40fb897bd8861f02}}}, +{{{0x84c5aa9062de37a1, 0x421da5000d1d96e1, 0x788286306a9242d9, 0x3c5e464a690d10da}}, + {{0xe57ed8475ab10761, 0x71435e206fd13746, 0x342f824ecd025632, 0x4b16281ea8791e7b}}, + {{0xd1c101d50b813381, 0xdee60f1176ee6828, 0x0cb68893383f6409, 0x6183c565f6ff484a}}}, +{{{0x741d5a461e6bf9d6, 0x2305b3fc7777a581, 0xd45574a26474d3d9, 0x1926e1dc6401e0ff}}, + {{0xdb468549af3f666e, 0xd77fcf04f14a0ea5, 0x3df23ff7a4ba0c47, 0x3a10dfe132ce3c85}}, + {{0xe07f4e8aea17cea0, 0x2fd515463a1fc1fd, 0x175322fd31f2c0f1, 0x1fa1d01d861e5d15}}}, +{{{0xcc8055947d599832, 0x1e4656da37f15520, 0x99f6f7744e059320, 0x773563bc6a75cf33}}, + {{0x38dcac00d1df94ab, 0x2e712bddd1080de9, 0x7f13e93efdd5e262, 0x73fced18ee9a01e5}}, + {{0x06b1e90863139cb3, 0xa493da67c5a03ecd, 0x8d77cec8ad638932, 0x1f426b701b864f44}}}, +{{{0xefc9264c41911c01, 0xf1a3b7b817a22c25, 0x5875da6bf30f1447, 0x4e1af5271d31b090}}, + {{0xf17e35c891a12552, 0xb76b8153575e9c76, 0xfa83406f0d9b723e, 0x0b76bb1b3fa7e438}}, + {{0x08b8c1f97f92939b, 0xbe6771cbd444ab6e, 0x22e5646399bb8017, 0x7b6dd61eb772a955}}}, +{{{0xb7adc1e850f33d92, 0x7998fa4f608cd5cf, 0xad962dbd8dfc5bdb, 0x703e9bceaf1d2f4f}}, + {{0x5730abf9ab01d2c7, 0x16fb76dc40143b18, 0x866cbe65a0cbb281, 0x53fa9b659bff6afe}}, + {{0x6c14c8e994885455, 0x843a5d6665aed4e5, 0x181bb73ebcd65af1, 0x398d93e5c4c61f50}}}, +{{{0x1c4bd16733e248f3, 0xbd9e128715bf0a5f, 0xd43f8cf0a10b0376, 0x53b09b5ddf191b13}}, + {{0xc3877c60d2e7e3f2, 0x3b34aaa030828bb1, 0x283e26e7739ef138, 0x699c9c9002c30577}}, + {{0xf306a7235946f1cc, 0x921718b5cce5d97d, 0x28cdd24781b4e975, 0x51caf30c6fcdd907}}}, +{{{0xa60ba7427674e00a, 0x630e8570a17a7bf3, 0x3758563dcf3324cc, 0x5504aa292383fdaa}}, + {{0x737af99a18ac54c7, 0x903378dcc51cb30f, 0x2b89bc334ce10cc7, 0x12ae29c189f8e99a}}, + {{0xa99ec0cb1f0d01cf, 0x0dd1efcc3a34f7ae, 0x55ca7521d09c4e22, 0x5fd14fe958eba5ea}}}, +{{{0xb5dc2ddf2845ab2c, 0x069491b10a7fe993, 0x4daaf3d64002e346, 0x093ff26e586474d1}}, + {{0x3c42fe5ebf93cb8e, 0xbedfa85136d4565f, 0xe0f0859e884220e8, 0x7dd73f960725d128}}, + {{0xb10d24fe68059829, 0x75730672dbaf23e5, 0x1367253ab457ac29, 0x2f59bcbc86b470a4}}}, +{{{0x83847d429917135f, 0xad1b911f567d03d7, 0x7e7748d9be77aad1, 0x5458b42e2e51af4a}}, + {{0x7041d560b691c301, 0x85201b3fadd7e71e, 0x16c2e16311335585, 0x2aa55e3d010828b1}}, + {{0xed5192e60c07444f, 0x42c54e2d74421d10, 0x352b4c82fdb5c864, 0x13e9004a8a768664}}}, +{{{0xcbb5b5556c032bff, 0xdf7191b729297a3a, 0xc1ff7326aded81bb, 0x71ade8bb68be03f5}}, + {{0x1e6284c5806b467c, 0xc5f6997be75d607b, 0x8b67d958b378d262, 0x3d88d66a81cd8b70}}, + {{0x8b767a93204ed789, 0x762fcacb9fa0ae2a, 0x771febcc6dce4887, 0x343062158ff05fb3}}}, +{{{0xe05da1a7e1f5bf49, 0x26457d6dd4736092, 0x77dcb07773cc32f6, 0x0a5d94969cdd5fcd}}, + {{0xfce219072a7b31b4, 0x4d7adc75aa578016, 0x0ec276a687479324, 0x6d6d9d5d1fda4beb}}, + {{0x22b1a58ae9b08183, 0xfd95d071c15c388b, 0xa9812376850a0517, 0x33384cbabb7f335e}}}, +{{{0x3c6fa2680ca2c7b5, 0x1b5082046fb64fda, 0xeb53349c5431d6de, 0x5278b38f6b879c89}}, + {{0x33bc627a26218b8d, 0xea80b21fc7a80c61, 0x9458b12b173e9ee6, 0x076247be0e2f3059}}, + {{0x52e105f61416375a, 0xec97af3685abeba4, 0x26e6b50623a67c36, 0x5cf0e856f3d4fb01}}}, +{{{0xf6c968731ae8cab4, 0x5e20741ecb4f92c5, 0x2da53be58ccdbc3e, 0x2dddfea269970df7}}, + {{0xbeaece313db342a8, 0xcba3635b842db7ee, 0xe88c6620817f13ef, 0x1b9438aa4e76d5c6}}, + {{0x8a50777e166f031a, 0x067b39f10fb7a328, 0x1925c9a6010fbd76, 0x6df9b575cc740905}}}, +{{{0x42c1192927f6bdcf, 0x8f91917a403d61ca, 0xdc1c5a668b9e1f61, 0x1596047804ec0f8d}}, + {{0xecdfc35b48cade41, 0x6a88471fb2328270, 0x740a4a2440a01b6a, 0x471e5796003b5f29}}, + {{0xda96bbb3aced37ac, 0x7a2423b5e9208cea, 0x24cc5c3038aebae2, 0x50c356afdc5dae2f}}}, +{{{0x09dcbf4341c30318, 0xeeba061183181dce, 0xc179c0cedc1e29a1, 0x1dbf7b89073f35b0}}, + {{0xcfed9cdf1b31b964, 0xf486a9858ca51af3, 0x14897265ea8c1f84, 0x784a53dd932acc00}}, + {{0x2d99f9df14fc4920, 0x76ccb60cc4499fe5, 0xa4132cbbe5cf0003, 0x3f93d82354f000ea}}}, +{{{0x8183e7689e04ce85, 0x678fb71e04465341, 0xad92058f6688edac, 0x5da350d3532b099a}}, + {{0xeaac12d179e14978, 0xff923ff3bbebff5e, 0x4af663e40663ce27, 0x0fd381a811a5f5ff}}, + {{0xf256aceca436df54, 0x108b6168ae69d6e8, 0x20d986cb6b5d036c, 0x655957b9fee2af50}}}, +{{{0xaea8b07fa902030f, 0xf88c766af463d143, 0x15b083663c787a60, 0x08eab1148267a4a8}}, + {{0xbdc1409bd002d0ac, 0x66660245b5ccd9a6, 0x82317dc4fade85ec, 0x02fe934b6ad7df0d}}, + {{0xef5cf100cfb7ea74, 0x22897633a1cb42ac, 0xd4ce0c54cef285e2, 0x30408c048a146a55}}}, +{{{0x739d8845832fcedb, 0xfa38d6c9ae6bf863, 0x32bc0dcab74ffef7, 0x73937e8814bce45e}}, + {{0xbb2e00c9193b877f, 0xece3a890e0dc506b, 0xecf3b7c036de649f, 0x5f46040898de9e1a}}, + {{0xb9037116297bf48d, 0xa9d13b22d4f06834, 0xe19715574696bdc6, 0x2cf8a4e891d5e835}}}, +{{{0x6d93fd8707110f67, 0xdd4c09d37c38b549, 0x7cb16a4cc2736a86, 0x2049bd6e58252a09}}, + {{0x2cb5487e17d06ba2, 0x24d2381c3950196b, 0xd7659c8185978a30, 0x7a6f7f2891d6a4f6}}, + {{0x7d09fd8d6a9aef49, 0xf0ee60be5b3db90b, 0x4c21b52c519ebfd4, 0x6011aadfc545941d}}}, +{{{0x5f67926dcf95f83c, 0x7c7e856171289071, 0xd6a1e7f3998f7a5b, 0x6fc5cc1b0b62f9e0}}, + {{0x63ded0c802cbf890, 0xfbd098ca0dff6aaa, 0x624d0afdb9b6ed99, 0x69ce18b779340b1e}}, + {{0xd1ef5528b29879cb, 0xdd1aae3cd47e9092, 0x127e0442189f2352, 0x15596b3ae57101f1}}}, +{{{0x462739d23f9179a2, 0xff83123197d6ddcf, 0x1307deb553f2148a, 0x0d2237687b5f4dda}}, + {{0x09ff31167e5124ca, 0x0be4158bd9c745df, 0x292b7d227ef556e5, 0x3aa4e241afb6d138}}, + {{0x2cc138bf2a3305f5, 0x48583f8fa2e926c3, 0x083ab1a25549d2eb, 0x32fcaa6e4687a36c}}}, +{{{0x7bc56e8dc57d9af5, 0x3e0bd2ed9df0bdf2, 0xaac014de22efe4a3, 0x4627e9cefebd6a5c}}, + {{0x3207a4732787ccdf, 0x17e31908f213e3f8, 0xd5b2ecd7f60d964e, 0x746f6336c2600be9}}, + {{0x3f4af345ab6c971c, 0xe288eb729943731f, 0x33596a8a0344186d, 0x7b4917007ed66293}}}, +{{{0x2d85fb5cab84b064, 0x497810d289f3bc14, 0x476adc447b15ce0c, 0x122ba376f844fd7b}}, + {{0x54341b28dd53a2dd, 0xaa17905bdf42fc3f, 0x0ff592d94dd2f8f4, 0x1d03620fe08cd37d}}, + {{0xc20232cda2b4e554, 0x9ed0fd42115d187f, 0x2eabb4be7dd479d9, 0x02c70bf52b68ec4c}}}, +{{{0xa287ec4b5d0b2fbb, 0x415c5790074882ca, 0xe044a61ec1d0815c, 0x26334f0a409ef5e0}}, + {{0xace532bf458d72e1, 0x5be768e07cb73cb5, 0x56cf7d94ee8bbde7, 0x6b0697e3feb43a03}}, + {{0xb6c8f04adf62a3c0, 0x3ef000ef076da45d, 0x9c9cb95849f0d2a9, 0x1cc37f43441b2fae}}}, +{{{0x508f565a5cc7324f, 0xd061c4c0e506a922, 0xfb18abdb5c45ac19, 0x6c6809c10380314a}}, + {{0xd76656f1c9ceaeb9, 0x1c5b15f818e5656a, 0x26e72832844c2334, 0x3a346f772f196838}}, + {{0xd2d55112e2da6ac8, 0xe9bd0331b1e851ed, 0x960746dd8ec67262, 0x05911b9f6ef7c5d0}}}, +{{{0xe9dcd756b637ff2d, 0xec4c348fc987f0c4, 0xced59285f3fbc7b7, 0x3305354793e1ea87}}, + {{0x01c18980c5fe9f94, 0xcd656769716fd5c8, 0x816045c3d195a086, 0x6e2b7f3266cc7982}}, + {{0xcc802468f7c3568f, 0x9de9ba8219974cb3, 0xabb7229cb5b81360, 0x44e2017a6fbeba62}}}, +{{{0xc4c2a74354dab774, 0x8e5d4c3c4eaf031a, 0xb76c23d242838f17, 0x749a098f68dce4ea}}, + {{0x87f82cf3b6ca6ecd, 0x580f893e18f4a0c2, 0x058930072604e557, 0x6cab6ac256d19c1d}}, + {{0xdcdfe0a02cc1de60, 0x032665ff51c5575b, 0x2c0c32f1073abeeb, 0x6a882014cd7b8606}}}, +{{{0xa52a92fea4747fb5, 0xdc12a4491fa5ab89, 0xd82da94bb847a4ce, 0x4d77edce9512cc4e}}, + {{0xd111d17caf4feb6e, 0x050bba42b33aa4a3, 0x17514c3ceeb46c30, 0x54bedb8b1bc27d75}}, + {{0x77c8e14577e2189c, 0xa3e46f6aff99c445, 0x3144dfc86d335343, 0x3a96559e7c4216a9}}}, +{{{0x12550d37f42ad2ee, 0x8b78e00498a1fbf5, 0x5d53078233894cb2, 0x02c84e4e3e498d0c}}, + {{0x4493896880baaa52, 0x4c98afc4f285940e, 0xef4aa79ba45448b6, 0x5278c510a57aae7f}}, + {{0xa54dd074294c0b94, 0xf55d46b8df18ffb6, 0xf06fecc58dae8366, 0x588657668190d165}}}, +{{{0xd47712311aef7117, 0x50343101229e92c7, 0x7a95e1849d159b97, 0x2449959b8b5d29c9}}, + {{0xbf5834f03de25cc3, 0xb887c8aed6815496, 0x5105221a9481e892, 0x6760ed19f7723f93}}, + {{0x669ba3b7ac35e160, 0x2eccf73fba842056, 0x1aec1f17c0804f07, 0x0d96bc031856f4e7}}}, +{{{0x3318be7775c52d82, 0x4cb764b554d0aab9, 0xabcf3d27cc773d91, 0x3bf4d1848123288a}}, + {{0xb1d534b0cc7505e1, 0x32cd003416c35288, 0xcb36a5800762c29d, 0x5bfe69b9237a0bf8}}, + {{0x183eab7e78a151ab, 0xbbe990c999093763, 0xff717d6e4ac7e335, 0x4c5cddb325f39f88}}}, +{{{0xc0f6b74d6190a6eb, 0x20ea81a42db8f4e4, 0xa8bd6f7d97315760, 0x33b1d60262ac7c21}}, + {{0x57750967e7a9f902, 0x2c37fdfc4f5b467e, 0xb261663a3177ba46, 0x3a375e78dc2d532b}}, + {{0x8141e72f2d4dddea, 0xe6eafe9862c607c8, 0x23c28458573cafd0, 0x46b9476f4ff97346}}}, +{{{0x0c1ffea44f901e5c, 0x2b0b6fb72184b782, 0xe587ff910114db88, 0x37130f364785a142}}, + {{0x1215505c0d58359f, 0x2a2013c7fc28c46b, 0x24a0a1af89ea664e, 0x4400b638a1130e1f}}, + {{0x3a01b76496ed19c3, 0x31e00ab0ed327230, 0x520a885783ca15b1, 0x06aab9875accbec7}}}, +{{{0xc1339983f5df0ebb, 0xc0f3758f512c4cac, 0x2cf1130a0bb398e1, 0x6b3cecf9aa270c62}}, + {{0x5349acf3512eeaef, 0x20c141d31cc1cb49, 0x24180c07a99a688d, 0x555ef9d1c64b2d17}}, + {{0x36a770ba3b73bd08, 0x624aef08a3afbf0c, 0x5737ff98b40946f2, 0x675f4de13381749d}}}, +{{{0x0e2c52036b1782fc, 0x64816c816cad83b4, 0xd0dcbdd96964073e, 0x13d99df70164c520}}, + {{0xa12ff6d93bdab31d, 0x0725d80f9d652dfe, 0x019c4ff39abe9487, 0x60f450b882cd3c43}}, + {{0x014b5ec321e5c0ca, 0x4fcb69c9d719bfa2, 0x4e5f1c18750023a0, 0x1c06de9e55edac80}}}, +{{{0x990f7ad6a33ec4e2, 0x6608f938be2ee08e, 0x9ca143c563284515, 0x4cf38a1fec2db60d}}, + {{0xffd52b40ff6d69aa, 0x34530b18dc4049bb, 0x5e4a5c2fa34d9897, 0x78096f8e7d32ba2d}}, + {{0xa0aaaa650dfa5ce7, 0xf9c49e2a48b5478c, 0x4f09cc7d7003725b, 0x373cad3a26091abe}}}, +{{{0xb294634d82c9f57c, 0x1fcbfde124934536, 0x9e9c4db3418cdb5a, 0x0040f3d9454419fc}}, + {{0xf1bea8fb89ddbbad, 0x3bcb2cbc61aeaecb, 0x8f58a7bb1f9b8d9d, 0x21547eda5112a686}}, + {{0xdefde939fd5986d3, 0xf4272c89510a380c, 0xb72ba407bb3119b9, 0x63550a334a254df4}}}, +{{{0x6507d6edb569cf37, 0x178429b00ca52ee1, 0xea7c0090eb6bd65d, 0x3eea62c7daf78f51}}, + {{0x9bba584572547b49, 0xf305c6fae2c408e0, 0x60e8fa69c734f18d, 0x39a92bafaa7d767a}}, + {{0x9d24c713e693274e, 0x5f63857768dbd375, 0x70525560eb8ab39a, 0x68436a0665c9c4cd}}}, +{{{0xbc0235e8202f3f27, 0xc75c00e264f975b0, 0x91a4e9d5a38c2416, 0x17b6e7f68ab789f9}}, + {{0x1e56d317e820107c, 0xc5266844840ae965, 0xc1e0a1c6320ffc7a, 0x5373669c91611472}}, + {{0x5d2814ab9a0e5257, 0x908f2084c9cab3fc, 0xafcaf5885b2d1eca, 0x1cb4b5a678f87d11}}}, +{{{0xb664c06b394afc6c, 0x0c88de2498da5fb1, 0x4f8d03164bcad834, 0x330bca78de7434a2}}, + {{0x6b74aa62a2a007e7, 0xf311e0b0f071c7b1, 0x5707e438000be223, 0x2dc0fd2d82ef6eac}}, + {{0x982eff841119744e, 0xf9695e962b074724, 0xc58ac14fbfc953fb, 0x3c31be1b369f1cf5}}}, +{{{0xb0f4864d08948aee, 0x07dc19ee91ba1c6f, 0x7975cdaea6aca158, 0x330b61134262d4bb}}, + {{0xc168bc93f9cb4272, 0xaeb8711fc7cedb98, 0x7f0e52aa34ac8d7a, 0x41cec1097e7d55bb}}, + {{0xf79619d7a26d808a, 0xbb1fd49e1d9e156d, 0x73d7c36cdba1df27, 0x26b44cd91f28777d}}}, +{{{0x300a9035393aa6d8, 0x2b501131a12bb1cd, 0x7b1ff677f093c222, 0x4309c1f8cab82bad}}, + {{0xaf44842db0285f37, 0x8753189047efc8df, 0x9574e091f820979a, 0x0e378d6069615579}}, + {{0xd9fa917183075a55, 0x4bdb5ad26b009fdc, 0x7829ad2cd63def0e, 0x078fc54975fd3877}}}, +{{{0x87dfbd1428878f2d, 0x134636dd1e9421a1, 0x4f17c951257341a3, 0x5df98d4bad296cb8}}, + {{0xe2004b5bb833a98a, 0x44775dec2d4c3330, 0x3aa244067eace913, 0x272630e3d58e00a9}}, + {{0xf3678fd0ecc90b54, 0xf001459b12043599, 0x26725fbc3758b89b, 0x4325e4aa73a719ae}}}, +{{{0x657dc6ef433c3493, 0x65375e9f80dbf8c3, 0x47fd2d465b372dae, 0x4966ab79796e7947}}, + {{0xed24629acf69f59d, 0x2a4a1ccedd5abbf4, 0x3535ca1f56b2d67b, 0x5d8c68d043b1b42d}}, + {{0xee332d4de3b42b0a, 0xd84e5a2b16a4601c, 0x78243877078ba3e4, 0x77ed1eb4184ee437}}}, +{{{0xbfd4e13f201839a0, 0xaeefffe23e3df161, 0xb65b04f06b5d1fe3, 0x52e085fb2b62fbc0}}, + {{0x185d43f89e92ed1a, 0xb04a1eeafe4719c6, 0x499fbe88a6f03f4f, 0x5d8b0d2f3c859bdd}}, + {{0x124079eaa54cf2ba, 0xd72465eb001b26e7, 0x6843bcfdc97af7fd, 0x0524b42b55eacd02}}}, +{{{0xfd0d5dbee45447b0, 0x6cec351a092005ee, 0x99a47844567579cb, 0x59d242a216e7fa45}}, + {{0xbc18dcad9b829eac, 0x23ae7d28b5f579d0, 0xc346122a69384233, 0x1a6110b2e7d4ac89}}, + {{0x4f833f6ae66997ac, 0x6849762a361839a4, 0x6985dec1970ab525, 0x53045e89dcb1f546}}}, +{{{0xcb8bb346d75353db, 0xfcfcb24bae511e22, 0xcba48d40d50ae6ef, 0x26e3bae5f4f7cb5d}}, + {{0x84da3cde8d45fe12, 0xbd42c218e444e2d2, 0xa85196781f7e3598, 0x7642c93f5616e2b2}}, + {{0x2323daa74595f8e4, 0xde688c8b857abeb4, 0x3fc48e961c59326e, 0x0b2e73ca15c9b8ba}}}, +{{{0xd6bb4428c17f5026, 0x9eb27223fb5a9ca7, 0xe37ba5031919c644, 0x21ce380db59a6602}}, + {{0x0e3fbfaf79c03a55, 0x3077af054cbb5acf, 0xd5c55245db3de39f, 0x015e68c1476a4af7}}, + {{0xc1d5285220066a38, 0x95603e523570aef3, 0x832659a7226b8a4d, 0x5dd689091f8eedc9}}}, +{{{0xcbac84debfd3c856, 0x1624c348b35ff244, 0xb7f88dca5d9cad07, 0x3b0e574da2c2ebe8}}, + {{0x1d022591a5313084, 0xca2d4aaed6270872, 0x86a12b852f0bfd20, 0x56e6c439ad7da748}}, + {{0xc704ff4942bdbae6, 0x5e21ade2b2de1f79, 0xe95db3f35652fad8, 0x0822b5378f08ebc1}}}, +{{{0x51f048478f387475, 0xb25dbcf49cbecb3c, 0x9aab1244d99f2055, 0x2c709e6c1c10a5d6}}, + {{0xe1b7f29362730383, 0x4b5279ffebca8a2c, 0xdafc778abfd41314, 0x7deb10149c72610f}}, + {{0xcb62af6a8766ee7a, 0x66cbec045553cd0e, 0x588001380f0be4b5, 0x08e68e9ff62ce2ea}}}, +{{{0x34ad500a4bc130ad, 0x8d38db493d0bd49c, 0xa25c3d98500a89be, 0x2f1f3f87eeba3b09}}, + {{0x2f2d09d50ab8f2f9, 0xacb9218dc55923df, 0x4a8f342673766cb9, 0x4cb13bd738f719f5}}, + {{0xf7848c75e515b64a, 0xa59501badb4a9038, 0xc20d313f3f751b50, 0x19a1e353c0ae2ee8}}}, +{{{0x7d1c7560bafa05c3, 0xb3e1a0a0c6e55e61, 0xe3529718c0d66473, 0x41546b11c20c3486}}, + {{0xb42172cdd596bdbd, 0x93e0454398eefc40, 0x9fb15347b44109b5, 0x736bd3990266ae34}}, + {{0x85532d509334b3b4, 0x46fd114b60816573, 0xcc5f5f30425c8375, 0x412295a2b87fab5c}}}, +{{{0x19c99b88f57ed6e9, 0x5393cb266df8c825, 0x5cee3213b30ad273, 0x14e153ebb52d2e34}}, + {{0x2e655261e293eac6, 0x845a92032133acdb, 0x460975cb7900996b, 0x0760bb8d195add80}}, + {{0x413e1a17cde6818a, 0x57156da9ed69a084, 0x2cbf268f46caccb1, 0x6b34be9bc33ac5f2}}}, +{{{0xf3df2f643a78c0b2, 0x4c3e971ef22e027c, 0xec7d1c5e49c1b5a3, 0x2012c18f0922dd2d}}, + {{0x11fc69656571f2d3, 0xc6c9e845530e737a, 0xe33ae7a2d4fe5035, 0x01b9c7b62e6dd30b}}, + {{0x880b55e55ac89d29, 0x1483241f45a0a763, 0x3d36efdfc2e76c1f, 0x08af5b784e4bade8}}}, +{{{0x283499dc881f2533, 0x9d0525da779323b6, 0x897addfb673441f4, 0x32b79d71163a168d}}, + {{0xe27314d289cc2c4b, 0x4be4bd11a287178d, 0x18d528d6fa3364ce, 0x6423c1d5afd9826e}}, + {{0xcc85f8d9edfcb36a, 0x22bcc28f3746e5f9, 0xe49de338f9e5d3cd, 0x480a5efbc13e2dcc}}}, +{{{0x0b51e70b01622071, 0x06b505cf8b1dafc5, 0x2c6bb061ef5aabcd, 0x47aa27600cb7bf31}}, + {{0xb6614ce442ce221f, 0x6e199dcc4c053928, 0x663fb4a4dc1cbe03, 0x24b31d47691c8e06}}, + {{0x2a541eedc015f8c3, 0x11a4fe7e7c693f7c, 0xf0af66134ea278d6, 0x545b585d14dda094}}}, +{{{0x67bf275ea0d43a0f, 0xade68e34089beebe, 0x4289134cd479e72e, 0x0f62f9c332ba5454}}, + {{0x6204e4d0e3b321e1, 0x3baa637a28ff1e95, 0x0b0ccffd5b99bd9e, 0x4d22dc3e64c8d071}}, + {{0xfcb46589d63b5f39, 0x5cae6a3f57cbcf61, 0xfebac2d2953afa05, 0x1c0fa01a36371436}}}, +{{{0xe7547449bc7cd692, 0x0f9abeaae6f73ddf, 0x4af01ca700837e29, 0x63ab1b5d3f1bc183}}, + {{0xc11ee5e854c53fae, 0x6a0b06c12b4f3ff4, 0x33540f80e0b67a72, 0x15f18fc3cd07e3ef}}, + {{0x32750763b028f48c, 0x06020740556a065f, 0xd53bd812c3495b58, 0x08706c9b865f508d}}}, +{{{0xf37ca2ab3d343dff, 0x1a8c6a2d80abc617, 0x8e49e035d4ccffca, 0x48b46beebaa1d1b9}}, + {{0xcc991b4138b41246, 0x243b9c526f9ac26b, 0xb9ef494db7cbabbd, 0x5fba433dd082ed00}}, + {{0x9c49e355c9941ad0, 0xb9734ade74498f84, 0x41c3fed066663e5c, 0x0ecfedf8e8e710b3}}}, +{{{0x76430f9f9cd470d9, 0xb62acc9ba42f6008, 0x1898297c59adad5e, 0x7789dd2db78c5080}}, + {{0x744f7463e9403762, 0xf79a8dee8dfcc9c9, 0x163a649655e4cde3, 0x3b61788db284f435}}, + {{0xb22228190d6ef6b2, 0xa94a66b246ce4bfa, 0x46c1a77a4f0b6cc7, 0x4236ccffeb7338cf}}}, +{{{0x8497404d0d55e274, 0x6c6663d9c4ad2b53, 0xec2fb0d9ada95734, 0x2617e120cdb8f73c}}, + {{0x3bd82dbfda777df6, 0x71b177cc0b98369e, 0x1d0e8463850c3699, 0x5a71945b48e2d1f1}}, + {{0x6f203dd5405b4b42, 0x327ec60410b24509, 0x9c347230ac2a8846, 0x77de29fc11ffeb6a}}}, +{{{0xb0ac57c983b778a8, 0x53cdcca9d7fe912c, 0x61c2b854ff1f59dc, 0x3a1a2cf0f0de7dac}}, + {{0x835e138fecced2ca, 0x8c9eaf13ea963b9a, 0xc95fbfc0b2160ea6, 0x575e66f3ad877892}}, + {{0x99803a27c88fcb3a, 0x345a6789275ec0b0, 0x459789d0ff6c2be5, 0x62f882651e70a8b2}}}, +{{{0x085ae2c759ff1be4, 0x149145c93b0e40b7, 0xc467e7fa7ff27379, 0x4eeecf0ad5c73a95}}, + {{0x6d822986698a19e0, 0xdc9821e174d78a71, 0x41a85f31f6cb1f47, 0x352721c2bcda9c51}}, + {{0x48329952213fc985, 0x1087cf0d368a1746, 0x8e5261b166c15aa5, 0x2d5b2d842ed24c21}}}, +{{{0x02cfebd9ebd3ded1, 0xd45b217739021974, 0x7576f813fe30a1b7, 0x5691b6f9a34ef6c2}}, + {{0x5eb7d13d196ac533, 0x377234ecdb80be2b, 0xe144cffc7cf5ae24, 0x5226bcf9c441acec}}, + {{0x79ee6c7223e5b547, 0x6f5f50768330d679, 0xed73e1e96d8adce9, 0x27c3da1e1d8ccc03}}}, +{{{0x7eb9efb23fe24c74, 0x3e50f49f1651be01, 0x3ea732dc21858dea, 0x17377bd75bb810f9}}, + {{0x28302e71630ef9f6, 0xc2d4a2032b64cee0, 0x090820304b6292be, 0x5fca747aa82adf18}}, + {{0x232a03c35c258ea5, 0x86f23a2c6bcb0cf1, 0x3dad8d0d2e442166, 0x04a8933cab76862b}}}, +{{{0xd2c604b622943dff, 0xbc8cbece44cfb3a0, 0x5d254ff397808678, 0x0fa3614f3b1ca6bf}}, + {{0x69082b0e8c936a50, 0xf9c9a035c1dac5b6, 0x6fb73e54c4dfb634, 0x4005419b1d2bc140}}, + {{0xa003febdb9be82f0, 0x2089c1af3a44ac90, 0xf8499f911954fa8e, 0x1fba218aef40ab42}}}, +{{{0xab549448fac8f53e, 0x81f6e89a7ba63741, 0x74fd6c7d6c2b5e01, 0x392e3acaa8c86e42}}, + {{0x4f3e57043e7b0194, 0xa81d3eee08daaf7f, 0xc839c6ab99dcdef1, 0x6c535d13ff7761d5}}, + {{0x4cbd34e93e8a35af, 0x2e0781445887e816, 0x19319c76f29ab0ab, 0x25e17fe4d50ac13b}}}, +{{{0x0a289bd71e04f676, 0x208e1c52d6420f95, 0x5186d8b034691fab, 0x255751442a9fb351}}, + {{0x915f7ff576f121a7, 0xc34a32272fcd87e3, 0xccba2fde4d1be526, 0x6bba828f8969899b}}, + {{0xe2d1bc6690fe3901, 0x4cb54a18a0997ad5, 0x971d6914af8460d4, 0x559d504f7f6b7be4}}}, +{{{0xa7738378b3eb54d5, 0x1d69d366a5553c7c, 0x0a26cf62f92800ba, 0x01ab12d5807e3217}}, + {{0x9c4891e7f6d266fd, 0x0744a19b0307781b, 0x88388f1d6061e23b, 0x123ea6a3354bd50e}}, + {{0x118d189041e32d96, 0xb9ede3c2d8315848, 0x1eab4271d83245d9, 0x4a3961e2c918a154}}}, +{{{0x71dc3be0f8e6bba0, 0xd6cef8347effe30a, 0xa992425fe13a476a, 0x2cd6bce3fb1db763}}, + {{0x0327d644f3233f1e, 0x499a260e34fcf016, 0x83b5a716f2dab979, 0x68aceead9bd4111f}}, + {{0x38b4c90ef3d7c210, 0x308e6e24b7ad040c, 0x3860d9f1b7e73e23, 0x595760d5b508f597}}}, +{{{0x6129bfe104aa6397, 0x8f960008a4a7fccb, 0x3f8bc0897d909458, 0x709fa43edcb291a9}}, + {{0x882acbebfd022790, 0x89af3305c4115760, 0x65f492e37d3473f4, 0x2cb2c5df54515a2b}}, + {{0xeb0a5d8c63fd2aca, 0xd22bc1662e694eff, 0x2723f36ef8cbb03a, 0x70f029ecf0c8131f}}}, +{{{0x461307b32eed3e33, 0xae042f33a45581e7, 0xc94449d3195f0366, 0x0b7d5d8a6c314858}}, + {{0x2a6aafaa5e10b0b9, 0x78f0a370ef041aa9, 0x773efb77aa3ad61f, 0x44eca5a2a74bd9e1}}, + {{0x25d448327b95d543, 0x70d38300a3340f1d, 0xde1c531c60e1c52b, 0x272224512c7de9e4}}}, +{{{0x1abc92af49c5342e, 0xffeed811b2e6fad0, 0xefa28c8dfcc84e29, 0x11b5df18a44cc543}}, + {{0xbf7bbb8a42a975fc, 0x8c5c397796ada358, 0xe27fc76fcdedaa48, 0x19735fd7f6bc20a6}}, + {{0xe3ab90d042c84266, 0xeb848e0f7f19547e, 0x2503a1d065a497b9, 0x0fef911191df895f}}}, +{{{0xb1507ca1ab1c6eb9, 0xbd448f3e16b687b3, 0x3455fb7f2c7a91ab, 0x7579229e2f2adec1}}, + {{0x6ab5dcb85b1c16b7, 0x94c0fce83c7b27a5, 0xa4b11c1a735517be, 0x499238d0ba0eafaa}}, + {{0xecf46e527aba8b57, 0x15a08c478bd1647b, 0x7af1c6a65f706fef, 0x6345fa78f03a30d5}}}, +{{{0xdf02f95f1015e7a1, 0x790ec41da9b40263, 0x4d3a0ea133ea1107, 0x54f70be7e33af8c9}}, + {{0x93d3cbe9bdd8f0a4, 0xdb152c1bfd177302, 0x7dbddc6d7f17a875, 0x3e1a71cc8f426efe}}, + {{0xc83ca3e390babd62, 0x80ede3670291c833, 0xc88038ccd37900c4, 0x2c5fc0231ec31fa1}}}, +{{{0xfeba911717038b4f, 0xe5123721c9deef81, 0x1c97e4e75d0d8834, 0x68afae7a23dc3bc6}}, + {{0xc422e4d102456e65, 0x87414ac1cad47b91, 0x1592e2bba2b6ffdd, 0x75d9d2bff5c2100f}}, + {{0x5bd9b4763626e81c, 0x89966936bca02edd, 0x0a41193d61f077b3, 0x3097a24200ce5471}}}, +{{{0x57427734c7f8b84c, 0xf141a13e01b270e9, 0x02d1adfeb4e564a6, 0x4bb23d92ce83bd48}}, + {{0xa162e7246695c486, 0x131d633435a89607, 0x30521561a0d12a37, 0x56704bada6afb363}}, + {{0xaf6c4aa752f912b9, 0x5e665f6cd86770c8, 0x4c35ac83a3c8cd58, 0x2b7a29c010a58a7e}}}, +{{{0xc4007f77d0c1cec3, 0x8d1020b6bac492f8, 0x32ec29d57e69daaf, 0x599408759d95fce0}}, + {{0x33810a23bf00086e, 0xafce925ee736ff7c, 0x3d60e670e24922d4, 0x11ce9e714f96061b}}, + {{0x219ef713d815bac1, 0xf141465d485be25c, 0x6d5447cc4e513c51, 0x174926be5ef44393}}}, +{{{0xb5deb2f9fc5bd5bb, 0x92daa72ae1d810e1, 0xafc4cfdcb72a1c59, 0x497d78813fc22a24}}, + {{0x3ef5d41593ea022e, 0x5cbcc1a20ed0eed6, 0x8fd24ecf07382c8c, 0x6fa42ead06d8e1ad}}, + {{0xe276824a1f73371f, 0x7f7cf01c4f5b6736, 0x7e201fe304fa46e7, 0x785a36a357808c96}}}, +{{{0x825fbdfd63014d2b, 0xc852369c6ca7578b, 0x5b2fcd285c0b5df0, 0x12ab214c58048c8f}}, + {{0x070442985d517bc3, 0x6acd56c7ae653678, 0x00a27983985a7763, 0x5167effae512662b}}, + {{0xbd4ea9e10f53c4b6, 0x1673dc5f8ac91a14, 0xa8f81a4e2acc1aba, 0x33a92a7924332a25}}}, +{{{0x9dd1f49927996c02, 0x0cb3b058e04d1752, 0x1f7e88967fd02c3e, 0x2f964268cb8b3eb1}}, + {{0x7ba95ba0218f2ada, 0xcff42287330fb9ca, 0xdada496d56c6d907, 0x5380c296f4beee54}}, + {{0x9d4f270466898d0a, 0x3d0987990aff3f7a, 0xd09ef36267daba45, 0x7761455e7b1c669c}}} \ No newline at end of file diff --git a/ext/ed25519-amd64-asm/ge25519_base_niels_smalltables.data b/ext/ed25519-amd64-asm/ge25519_base_niels_smalltables.data new file mode 100644 index 0000000..a31f6f2 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_base_niels_smalltables.data @@ -0,0 +1,768 @@ +{{{0x9d103905d740913e, 0xfd399f05d140beb3, 0xa5c18434688f8a09, 0x44fd2f9298f81267}}, + {{0x2fbc93c6f58c3b85, 0xcf932dc6fb8c0e19, 0x270b4898643d42c2, 0x07cf9d3a33d4ba65}}, + {{0xdbbd15674b6fbb59, 0x41e13f00eea2a5ea, 0xcdd49d1cc957c6fa, 0x4f0ebe1faf16ecca}}}, +{{{0x8a99a56042b4d5a8, 0x8f2b810c4e60acf6, 0xe09e236bb16e37aa, 0x6bb595a669c92555}}, + {{0x9224e7fc933c71d7, 0x9f469d967a0ff5b5, 0x5aa69a65e1d60702, 0x590c063fa87d2e2e}}, + {{0x6e347eaadad36802, 0xbaf3599383ee4805, 0x3bcabe10e6076826, 0x49314f0a165ed1b8}}}, +{{{0x56611fe8a4fcd265, 0x3bd353fde5c1ba7d, 0x8131f31a214bd6bd, 0x2ab91587555bda62}}, + {{0xaf25b0a84cee9730, 0x025a8430e8864b8a, 0xc11b50029f016732, 0x7a164e1b9a80f8f4}}, + {{0x9bf211f4f1674834, 0xb84e6b17f62df895, 0xd7de6f075b722a4e, 0x549a04b963bb2a21}}}, +{{{0x95fe050a056818bf, 0x327e89715660faa9, 0xc3e8e3cd06a05073, 0x27933f4c7445a49a}}, + {{0x287351b98efc099f, 0x6765c6f47dfd2538, 0xca348d3dfb0a9265, 0x680e910321e58727}}, + {{0xbf1e45ece51426b0, 0xe32bc63d6dba0f94, 0xe42974d58cf852c0, 0x44f079b1b0e64c18}}}, +{{{0x7f9182c3a447d6ba, 0xd50014d14b2729b7, 0xe33cf11cb864a087, 0x154a7e73eb1b55f3}}, + {{0xa212bc4408a5bb33, 0x8d5048c3c75eed02, 0xdd1beb0c5abfec44, 0x2945ccf146e206eb}}, + {{0xc832a179e7d003b3, 0x5f729d0a00124d7e, 0x62c1d4a10e6d8ff3, 0x68b8ac5938b27a98}}}, +{{{0x499806b67b7d8ca4, 0x575be28427d22739, 0xbb085ce7204553b9, 0x38b64c41ae417884}}, + {{0x3a0ceeeb77157131, 0x9b27158900c8af88, 0x8065b668da59a736, 0x51e57bb6a2cc38bd}}, + {{0x8f9dad91689de3a4, 0x175f2428f8fb9137, 0x050ab5329fcfb988, 0x7865dfa21354c09f}}}, +{{{0xba6f2c9aaa3221b1, 0x6ca021533bba23a7, 0x9dea764f92192c3a, 0x1d6edd5d2e5317e0}}, + {{0x6b1a5cd0944ea3bf, 0x7470353ab39dc0d2, 0x71b2528228542e49, 0x461bea69283c927e}}, + {{0x217a8aacab0fda36, 0xa528c6543d3549c8, 0x37d05b8b13ab7568, 0x233cef623a2cbc37}}}, +{{{0xe2a75dedf39234d9, 0x963d7680e1b558f9, 0x2c2741ac6e3c23fb, 0x3a9024a1320e01c3}}, + {{0x59b7596604dd3e8f, 0x6cb30377e288702c, 0xb1339c665ed9c323, 0x0915e76061bce52f}}, + {{0xdf7de835a834a37e, 0x8be19cda689857ea, 0x2c1185367167b326, 0x589eb3d9dbefd5c2}}}, +{{{0xed5b635449aa515e, 0xa865c49f0bc6823a, 0x850c1fe95b42d1c4, 0x30d76d6f03d315b9}}, + {{0x2eccdd0e632f9c1d, 0x51d0b69676893115, 0x52dfb76ba8637a58, 0x6dd37d49a00eef39}}, + {{0x6c4444172106e4c7, 0xfb53d680928d7f69, 0xb4739ea4694d3f26, 0x10c697112e864bb0}}}, +{{{0x6493c4277dbe5fde, 0x265d4fad19ad7ea2, 0x0e00dfc846304590, 0x25e61cabed66fe09}}, + {{0x0ca62aa08358c805, 0x6a3d4ae37a204247, 0x7464d3a63b11eddc, 0x03bf9baf550806ef}}, + {{0x3f13e128cc586604, 0x6f5873ecb459747e, 0xa0b63dedcc1268f5, 0x566d78634586e22c}}}, +{{{0x1637a49f9cc10834, 0xbc8e56d5a89bc451, 0x1cb5ec0f7f7fd2db, 0x33975bca5ecc35d9}}, + {{0xa1054285c65a2fd0, 0x6c64112af31667c3, 0x680ae240731aee58, 0x14fba5f34793b22a}}, + {{0x3cd746166985f7d4, 0x593e5e84c9c80057, 0x2fc3f2b67b61131e, 0x14829cea83fc526c}}}, +{{{0xff437b8497dd95c2, 0x6c744e30aa4eb5a7, 0x9e0c5d613c85e88b, 0x2fd9c71e5f758173}}, + {{0x21e70b2f4e71ecb8, 0xe656ddb940a477e3, 0xbf6556cece1d4f80, 0x05fc3bc4535d7b7e}}, + {{0x24b8b3ae52afdedd, 0x3495638ced3b30cf, 0x33a4bc83a9be8195, 0x373767475c651f04}}}, +{{{0x2fba99fd40d1add9, 0xb307166f96f4d027, 0x4363f05215f03bae, 0x1fbea56c3b18f999}}, + {{0x634095cb14246590, 0xef12144016c15535, 0x9e38140c8910bc60, 0x6bf5905730907c8c}}, + {{0x0fa778f1e1415b8a, 0x06409ff7bac3a77e, 0x6f52d7b89aa29a50, 0x02521cf67a635a56}}}, +{{{0x513fee0b0a9d5294, 0x8f98e75c0fdf5a66, 0xd4618688bfe107ce, 0x3fa00a7e71382ced}}, + {{0xb1146720772f5ee4, 0xe8f894b196079ace, 0x4af8224d00ac824a, 0x001753d9f7cd6cc4}}, + {{0x3c69232d963ddb34, 0x1dde87dab4973858, 0xaad7d1f9a091f285, 0x12b5fe2fa048edb6}}}, +{{{0x71f0fbc496fce34d, 0x73b9826badf35bed, 0xd2047261ff28c561, 0x749b76f96fb1206f}}, + {{0xdf2b7c26ad6f1e92, 0x4b66d323504b8913, 0x8c409dc0751c8bc3, 0x6f7e93c20796c7b8}}, + {{0x1f5af604aea6ae05, 0xc12351f1bee49c99, 0x61a808b5eeff6b66, 0x0fcec10f01e02151}}}, +{{{0x644d58a649fe1e44, 0x21fcaea231ad777e, 0x02441c5a887fd0d2, 0x4901aa7183c511f3}}, + {{0x3df2d29dc4244e45, 0x2b020e7493d8de0a, 0x6cc8067e820c214d, 0x413779166feab90a}}, + {{0x08b1b7548c1af8f0, 0xce0f7a7c246299b4, 0xf760b0f91e06d939, 0x41bb887b726d1213}}}, +{{{0x40e87d44744346be, 0x1d48dad415b52b25, 0x7c3a8a18a13b603e, 0x4eb728c12fcdbdf7}}, + {{0x7e234c597c6691ae, 0x64889d3d0a85b4c8, 0xdae2c90c354afae7, 0x0a871e070c6a9e1d}}, + {{0x3301b5994bbc8989, 0x736bae3a5bdd4260, 0x0d61ade219d59e3c, 0x3ee7300f2685d464}}}, +{{{0xf5d255e49e7dd6b7, 0x8016115c610b1eac, 0x3c99975d92e187ca, 0x13815762979125c2}}, + {{0x43fa7947841e7518, 0xe5c6fa59639c46d7, 0xa1065e1de3052b74, 0x7d47c6a2cfb89030}}, + {{0x3fdad0148ef0d6e0, 0x9d3e749a91546f3c, 0x71ec621026bb8157, 0x148cf58d34c9ec80}}}, +{{{0x46a492f67934f027, 0x469984bef6840aa9, 0x5ca1bc2a89611854, 0x3ff2fa1ebd5dbbd4}}, + {{0xe2572f7d9ae4756d, 0x56c345bb88f3487f, 0x9fd10b6d6960a88d, 0x278febad4eaea1b9}}, + {{0xb1aa681f8c933966, 0x8c21949c20290c98, 0x39115291219d3c52, 0x4104dd02fe9c677b}}}, +{{{0x72b2bf5e1124422a, 0xa1fa0c3398a33ab5, 0x94cb6101fa52b666, 0x2c863b00afaf53d5}}, + {{0x81214e06db096ab8, 0x21a8b6c90ce44f35, 0x6524c12a409e2af5, 0x0165b5a48efca481}}, + {{0xf190a474a0846a76, 0x12eff984cd2f7cc0, 0x695e290658aa2b8f, 0x591b67d9bffec8b8}}}, +{{{0x312f0d1c80b49bfa, 0x5979515eabf3ec8a, 0x727033c09ef01c88, 0x3de02ec7ca8f7bcb}}, + {{0x99b9b3719f18b55d, 0xe465e5faa18c641e, 0x61081136c29f05ed, 0x489b4f867030128b}}, + {{0xd232102d3aeb92ef, 0xe16253b46116a861, 0x3d7eabe7190baa24, 0x49f5fbba496cbebf}}}, +{{{0x30949a108a5bcfd4, 0xdc40dd70bc6473eb, 0x92c294c1307c0d1c, 0x5604a86dcbfa6e74}}, + {{0x155d628c1e9c572e, 0x8a4d86acc5884741, 0x91a352f6515763eb, 0x06a1a6c28867515b}}, + {{0x7288d1d47c1764b6, 0x72541140e0418b51, 0x9f031a6018acf6d1, 0x20989e89fe2742c6}}}, +{{{0x499777fd3a2dcc7f, 0x32857c2ca54fd892, 0xa279d864d207e3a0, 0x0403ed1d0ca67e29}}, + {{0x1674278b85eaec2e, 0x5621dc077acb2bdf, 0x640a4c1661cbf45a, 0x730b9950f70595d3}}, + {{0xc94b2d35874ec552, 0xc5e6c8cf98246f8d, 0xf7cb46fa16c035ce, 0x5bd7454308303dcc}}}, +{{{0x7f9ad19528b24cc2, 0x7f6b54656335c181, 0x66b8b66e4fc07236, 0x133a78007380ad83}}, + {{0x85c4932115e7792a, 0xc64c89a2bdcdddc9, 0x9d1e3da8ada3d762, 0x5bb7db123067f82c}}, + {{0x0961f467c6ca62be, 0x04ec21d6211952ee, 0x182360779bd54770, 0x740dca6d58f0e0d2}}}, +{{{0xdf48ee0752cfce4e, 0xc3fffaf306ec08b7, 0x05710b2ab95459c4, 0x161d25fa963ea38d}}, + {{0x231a8c570478433c, 0xb7b5270ec281439d, 0xdbaa99eae3d9079f, 0x2c03f5256c2b03d9}}, + {{0x790f18757b53a47d, 0x307b0130cf0c5879, 0x31903d77257ef7f9, 0x699468bdbd96bbaf}}}, +{{{0xbd1f2f46f4dafecf, 0x7cef0114a47fd6f7, 0xd31ffdda4a47b37f, 0x525219a473905785}}, + {{0xd8dd3de66aa91948, 0x485064c22fc0d2cc, 0x9b48246634fdea2f, 0x293e1c4e6c4a2e3a}}, + {{0x376e134b925112e1, 0x703778b5dca15da0, 0xb04589af461c3111, 0x5b605c447f032823}}}, +{{{0xb965805920c47c89, 0xe7f0100c923b8fcc, 0x0001256502e2ef77, 0x24a76dcea8aeb3ee}}, + {{0x3be9fec6f0e7f04c, 0x866a579e75e34962, 0x5542ef161e1de61a, 0x2f12fef4cc5abdd5}}, + {{0x0a4522b2dfc0c740, 0x10d06e7f40c9a407, 0xc6cf144178cff668, 0x5e607b2518a43790}}}, +{{{0x58b31d8f6cdf1818, 0x35cfa74fc36258a2, 0xe1b3ff4f66e61d6e, 0x5067acab6ccdd5f7}}, + {{0xa02c431ca596cf14, 0xe3c42d40aed3e400, 0xd24526802e0f26db, 0x201f33139e457068}}, + {{0xfd527f6b08039d51, 0x18b14964017c0006, 0xd5220eb02e25a4a8, 0x397cba8862460375}}}, +{{{0x30c13093f05959b2, 0xe23aa18de9a97976, 0x222fd491721d5e26, 0x2339d320766e6c3a}}, + {{0x7815c3fbc81379e7, 0xa6619420dde12af1, 0xffa9c0f885a8fdd5, 0x771b4022c1e1c252}}, + {{0xd87dd986513a2fa7, 0xf5ac9b71f9d4cf08, 0xd06bc31b1ea283b3, 0x331a189219971a76}}}, +{{{0xf5166f45fb4f80c6, 0x9c36c7de61c775cf, 0xe3d4e81b9041d91c, 0x31167c6b83bdfe21}}, + {{0x26512f3a9d7572af, 0x5bcbe28868074a9e, 0x84edc1c11180f7c4, 0x1ac9619ff649a67b}}, + {{0xf22b3842524b1068, 0x5068343bee9ce987, 0xfc9d71844a6250c8, 0x612436341f08b111}}}, +{{{0xd99d41db874e898d, 0x09fea5f16c07dc20, 0x793d2c67d00f9bbc, 0x46ebe2309e5eff40}}, + {{0x8b6349e31a2d2638, 0x9ddfb7009bd3fd35, 0x7f8bf1b8a3a06ba4, 0x1522aa3178d90445}}, + {{0x2c382f5369614938, 0xdafe409ab72d6d10, 0xe8c83391b646f227, 0x45fe70f50524306c}}}, +{{{0xda4875a6960c0b8c, 0x5b68d076ef0e2f20, 0x07fb51cf3d0b8fd4, 0x428d1623a0e392d4}}, + {{0x62f24920c8951491, 0x05f007c83f630ca2, 0x6fbb45d2f5c9d4b8, 0x16619f6db57a2245}}, + {{0x084f4a4401a308fd, 0xa82219c376a5caac, 0xdeb8de4643d1bc7d, 0x1d81592d60bd38c6}}}, +{{{0x61368756a60dac5f, 0x17e02f6aebabdc57, 0x7f193f2d4cce0f7d, 0x20234a7789ecdcf0}}, + {{0x8765b69f7b85c5e8, 0x6ff0678bd168bab2, 0x3a70e77c1d330f9b, 0x3a5f6d51b0af8e7c}}, + {{0x76d20db67178b252, 0x071c34f9d51ed160, 0xf62a4a20b3e41170, 0x7cd682353cffe366}}}, +{{{0x0be1a45bd887fab6, 0x2a846a32ba403b6e, 0xd9921012e96e6000, 0x2838c8863bdc0943}}, + {{0xa665cd6068acf4f3, 0x42d92d183cd7e3d3, 0x5759389d336025d9, 0x3ef0253b2b2cd8ff}}, + {{0xd16bb0cf4a465030, 0xfa496b4115c577ab, 0x82cfae8af4ab419d, 0x21dcb8a606a82812}}}, +{{{0x5c6004468c9d9fc8, 0x2540096ed42aa3cb, 0x125b4d4c12ee2f9c, 0x0bc3d08194a31dab}}, + {{0x9a8d00fabe7731ba, 0x8203607e629e1889, 0xb2cc023743f3d97f, 0x5d840dbf6c6f678b}}, + {{0x706e380d309fe18b, 0x6eb02da6b9e165c7, 0x57bbba997dae20ab, 0x3a4276232ac196dd}}}, +{{{0x4b42432c8a7084fa, 0x898a19e3dfb9e545, 0xbe9f00219c58e45d, 0x1ff177cea16debd1}}, + {{0x3bf8c172db447ecb, 0x5fcfc41fc6282dbd, 0x80acffc075aa15fe, 0x0770c9e824e1a9f9}}, + {{0xcf61d99a45b5b5fd, 0x860984e91b3a7924, 0xe7300919303e3e89, 0x39f264fd41500b1e}}}, +{{{0xa7ad3417dbe7e29c, 0xbd94376a2b9c139c, 0xa0e91b8e93597ba9, 0x1712d73468889840}}, + {{0xd19b4aabfe097be1, 0xa46dfce1dfe01929, 0xc3c908942ca6f1ff, 0x65c621272c35f14e}}, + {{0xe72b89f8ce3193dd, 0x4d103356a125c0bb, 0x0419a93d2e1cfe83, 0x22f9800ab19ce272}}}, +{{{0x605a368a3e9ef8cb, 0xe3e9c022a5504715, 0x553d48b05f24248f, 0x13f416cd647626e5}}, + {{0x42029fdd9a6efdac, 0xb912cebe34a54941, 0x640f64b987bdf37b, 0x4171a4d38598cab4}}, + {{0xfa2758aa99c94c8c, 0x23006f6fb000b807, 0xfbd291ddadda5392, 0x508214fa574bd1ab}}}, +{{{0xc20269153ed6fe4b, 0xa65a6739511d77c4, 0xcbde26462c14af94, 0x22f960ec6faba74b}}, + {{0x461a15bb53d003d6, 0xb2102888bcf3c965, 0x27c576756c683a5a, 0x3a7758a4c86cb447}}, + {{0x548111f693ae5076, 0x1dae21df1dfd54a6, 0x12248c90f3115e65, 0x5d9fd15f8de7f494}}}, +{{{0x031408d36d63727f, 0x6a379aefd7c7b533, 0xa9e18fc5ccaee24b, 0x332f35914f8fbed3}}, + {{0x3f244d2aeed7521e, 0x8e3a9028432e9615, 0xe164ba772e9c16d4, 0x3bc187fa47eb98d8}}, + {{0x6d470115ea86c20c, 0x998ab7cb6c46d125, 0xd77832b53a660188, 0x450d81ce906fba03}}}, +{{{0x6e7bb6a1a6205275, 0xaa4f21d7413c8e83, 0x6f56d155e88f5cb2, 0x2de25d4ba6345be1}}, + {{0xd074d8961cae743f, 0xf86d18f5ee1c63ed, 0x97bdc55be7f4ed29, 0x4cbad279663ab108}}, + {{0x80d19024a0d71fcd, 0xc525c20afb288af8, 0xb1a3974b5f3a6419, 0x7d7fbcefe2007233}}}, +{{{0xfaef1e6a266b2801, 0x866c68c4d5739f16, 0xf68a2fbc1b03762c, 0x5975435e87b75a8d}}, + {{0xcd7c5dc5f3c29094, 0xc781a29a2a9105ab, 0x80c61d36421c3058, 0x4f9cd196dcd8d4d7}}, + {{0x199297d86a7b3768, 0xd0d058241ad17a63, 0xba029cad5c1c0c17, 0x7ccdd084387a0307}}}, +{{{0xdca6422c6d260417, 0xae153d50948240bd, 0xa9c0c1b4fb68c677, 0x428bd0ed61d0cf53}}, + {{0x9b0c84186760cc93, 0xcdae007a1ab32a99, 0xa88dec86620bda18, 0x3593ca848190ca44}}, + {{0x9213189a5e849aa7, 0xd4d8c33565d8facd, 0x8c52545b53fdbbd1, 0x27398308da2d63e6}}}, +{{{0x42c38d28435ed413, 0xbd50f3603278ccc9, 0xbb07ab1a79da03ef, 0x269597aebe8c3355}}, + {{0xb9a10e4c0a702453, 0x0fa25866d57d1bde, 0xffb9d9b5cd27daf7, 0x572c2945492c33fd}}, + {{0xc77fc745d6cd30be, 0xe4dfe8d3e3baaefb, 0xa22c8830aa5dda0c, 0x7f985498c05bca80}}}, +{{{0x3849ce889f0be117, 0x8005ad1b7b54a288, 0x3da3c39f23fc921c, 0x76c2ec470a31f304}}, + {{0xd35615520fbf6363, 0x08045a45cf4dfba6, 0xeec24fbc873fa0c2, 0x30f2653cd69b12e7}}, + {{0x8a08c938aac10c85, 0x46179b60db276bcb, 0xa920c01e0e6fac70, 0x2f1273f1596473da}}}, +{{{0x4739fc7c8ae01e11, 0xfd5274904a6aab9f, 0x41d98a8287728f2e, 0x5d9e572ad85b69f2}}, + {{0x30488bd755a70bc0, 0x06d6b5a4f1d442e7, 0xead1a69ebc596162, 0x38ac1997edc5f784}}, + {{0x0666b517a751b13b, 0x747d06867e9b858c, 0xacacc011454dde49, 0x22dfcd9cbfe9e69c}}}, +{{{0x8ddbd2e0c30d0cd9, 0xad8e665facbb4333, 0x8f6b258c322a961f, 0x6b2916c05448c1c7}}, + {{0x56ec59b4103be0a1, 0x2ee3baecd259f969, 0x797cb29413f5cd32, 0x0fe9877824cde472}}, + {{0x7edb34d10aba913b, 0x4ea3cd822e6dac0e, 0x66083dff6578f815, 0x4c303f307ff00a17}}}, +{{{0xd30a3bd617b28c85, 0xc5d377b739773bea, 0xc6c6e78c1e6a5cbf, 0x0d61b8f78b2ab7c4}}, + {{0x29fc03580dd94500, 0xecd27aa46fbbec93, 0x130a155fc2e2a7f8, 0x416b151ab706a1d5}}, + {{0x56a8d7efe9c136b0, 0xbd07e5cd58e44b20, 0xafe62fda1b57e0ab, 0x191a2af74277e8d2}}}, +{{{0xce16f74bc53c1431, 0x2b9725ce2072edde, 0xb8b9c36fb5b23ee7, 0x7e2e0e450b5cc908}}, + {{0x9fe62b434f460efb, 0xded303d4a63607d6, 0xf052210eb7a0da24, 0x237e7dbe00545b93}}, + {{0x013575ed6701b430, 0x231094e69f0bfd10, 0x75320f1583e47f22, 0x71afa699b11155e3}}}, +{{{0x65ce6f9b3953b61d, 0xc65839eaafa141e6, 0x0f435ffda9f759fe, 0x021142e9c2b1c28e}}, + {{0xea423c1c473b50d6, 0x51e87a1f3b38ef10, 0x9b84bf5fb2c9be95, 0x00731fbc78f89a1c}}, + {{0xe430c71848f81880, 0xbf960c225ecec119, 0xb6dae0836bba15e3, 0x4c4d6f3347e15808}}}, +{{{0x18f7eccfc17d1fc9, 0x6c75f5a651403c14, 0xdbde712bf7ee0cdf, 0x193fddaaa7e47a22}}, + {{0x2f0cddfc988f1970, 0x6b916227b0b9f51b, 0x6ec7b6c4779176be, 0x38bf9500a88f9fa8}}, + {{0x1fd2c93c37e8876f, 0xa2f61e5a18d1462c, 0x5080f58239241276, 0x6a6fb99ebf0d4969}}}, +{{{0x6a46c1bb560855eb, 0x2416bb38f893f09d, 0xd71d11378f71acc1, 0x75f76914a31896ea}}, + {{0xeeb122b5b6e423c6, 0x939d7010f286ff8e, 0x90a92a831dcf5d8c, 0x136fda9f42c5eb10}}, + {{0xf94cdfb1a305bdd1, 0x0f364b9d9ff82c08, 0x2a87d8a5c3bb588a, 0x022183510be8dcba}}}, +{{{0x4af766385ead2d14, 0xa08ed880ca7c5830, 0x0d13a6e610211e3d, 0x6a071ce17b806c03}}, + {{0x9d5a710143307a7f, 0xb063de9ec47da45f, 0x22bbfe52be927ad3, 0x1387c441fd40426c}}, + {{0xb5d3c3d187978af8, 0x722b5a3d7f0e4413, 0x0d7b4848bb477ca0, 0x3171b26aaf1edc92}}}, +{{{0xa92f319097564ca8, 0xff7bb84c2275e119, 0x4f55fe37a4875150, 0x221fd4873cf0835a}}, + {{0xa60db7d8b28a47d1, 0xa6bf14d61770a4f1, 0xd4a1f89353ddbd58, 0x6c514a63344243e9}}, + {{0x2322204f3a156341, 0xfb73e0e9ba0a032d, 0xfce0dd4c410f030e, 0x48daa596fb924aaa}}}, +{{{0x6eca8e665ca59cc7, 0xa847254b2e38aca0, 0x31afc708d21e17ce, 0x676dd6fccad84af7}}, + {{0x14f61d5dc84c9793, 0x9941f9e3ef418206, 0xcdf5b88f346277ac, 0x58c837fa0e8a79a9}}, + {{0x0cf9688596fc9058, 0x1ddcbbf37b56a01b, 0xdcc2e77d4935d66a, 0x1c4f73f2c6a57f0a}}}, +{{{0x0e7a4fbd305fa0bb, 0x829d4ce054c663ad, 0xf421c3832fe33848, 0x795ac80d1bf64c42}}, + {{0xb36e706efc7c3484, 0x73dfc9b4c3c1cf61, 0xeb1d79c9781cc7e5, 0x70459adb7daf675c}}, + {{0x1b91db4991b42bb3, 0x572696234b02dcca, 0x9fdf9ee51f8c78dc, 0x5fe162848ce21fd3}}}, +{{{0x4e59214fe194961a, 0x49be7dc70d71cd4f, 0x9300cfd23b50f22d, 0x4789d446fc917232}}, + {{0x2879852d5d7cb208, 0xb8dedd70687df2e7, 0xdc0bffab21687891, 0x2b44c043677daa35}}, + {{0x1a1c87ab074eb78e, 0xfac6d18e99daf467, 0x3eacbbcd484f9067, 0x60c52eef2bb9a4e4}}}, +{{{0x0b5d89bc3bfd8bf1, 0xb06b9237c9f3551a, 0x0e4c16b0d53028f5, 0x10bc9c312ccfcaab}}, + {{0x702bc5c27cae6d11, 0x44c7699b54a48cab, 0xefbc4056ba492eb2, 0x70d77248d9b6676d}}, + {{0xaa8ae84b3ec2a05b, 0x98699ef4ed1781e0, 0x794513e4708e85d1, 0x63755bd3a976f413}}}, +{{{0xb55fa03e2ad10853, 0x356f75909ee63569, 0x9ff9f1fdbe69b890, 0x0d8cc1c48bc16f84}}, + {{0x3dc7101897f1acb7, 0x5dda7d5ec165bbd8, 0x508e5b9c0fa1020f, 0x2763751737c52a56}}, + {{0x029402d36eb419a9, 0xf0b44e7e77b460a5, 0xcfa86230d43c4956, 0x70c2dd8a7ad166e7}}}, +{{{0x656194509f6fec0e, 0xee2e7ea946c6518d, 0x9733c1f367e09b5c, 0x2e0fac6363948495}}, + {{0x91d4967db8ed7e13, 0x74252f0ad776817a, 0xe40982e00d852564, 0x32b8613816a53ce5}}, + {{0x79e7f7bee448cd64, 0x6ac83a67087886d0, 0xf89fd4d9a0e4db2e, 0x4179215c735a4f41}}}, +{{{0x8c7094e7d7dced2a, 0x97fb8ac347d39c70, 0xe13be033a906d902, 0x700344a30cd99d76}}, + {{0xe4ae33b9286bcd34, 0xb7ef7eb6559dd6dc, 0x278b141fb3d38e1f, 0x31fa85662241c286}}, + {{0xaf826c422e3622f4, 0xc12029879833502d, 0x9bc1b7e12b389123, 0x24bb2312a9952489}}}, +{{{0xb1a8ed1732de67c3, 0x3cb49418461b4948, 0x8ebd434376cfbcd2, 0x0fee3e871e188008}}, + {{0x41f80c2af5f85c6b, 0x687284c304fa6794, 0x8945df99a3ba1bad, 0x0d1d2af9ffeb5d16}}, + {{0xa9da8aa132621edf, 0x30b822a159226579, 0x4004197ba79ac193, 0x16acd79718531d76}}}, +{{{0x72df72af2d9b1d3d, 0x63462a36a432245a, 0x3ecea07916b39637, 0x123e0ef6b9302309}}, + {{0xc959c6c57887b6ad, 0x94e19ead5f90feba, 0x16e24e62a342f504, 0x164ed34b18161700}}, + {{0x487ed94c192fe69a, 0x61ae2cea3a911513, 0x877bf6d3b9a4de27, 0x78da0fc61073f3eb}}}, +{{{0x5bf15d28e52bc66a, 0x2c47e31870f01a8e, 0x2419afbc06c28bdd, 0x2d25deeb256b173a}}, + {{0xa29f80f1680c3a94, 0x71f77e151ae9e7e6, 0x1100f15848017973, 0x054aa4b316b38ddd}}, + {{0xdfc8468d19267cb8, 0x0b28789c66e54daf, 0x2aeb1d2a666eec17, 0x134610a6ab7da760}}}, +{{{0x51138ec78df6b0fe, 0x5397da89e575f51b, 0x09207a1d717af1b9, 0x2102fdba2b20d650}}, + {{0xcd2a65e777d1f515, 0x548991878faa60f1, 0xb1b73bbcdabc06e5, 0x654878cba97cc9fb}}, + {{0x969ee405055ce6a1, 0x36bca7681251ad29, 0x3a1af517aa7da415, 0x0ad725db29ecb2ba}}}, +{{{0xdc4267b1834e2457, 0xb67544b570ce1bc5, 0x1af07a0bf7d15ed7, 0x4aefcffb71a03650}}, + {{0xfec7bc0c9b056f85, 0x537d5268e7f5ffd7, 0x77afc6624312aefa, 0x4f675f5302399fd9}}, + {{0xc32d36360415171e, 0xcd2bef118998483b, 0x870a6eadd0945110, 0x0bccbb72a2a86561}}}, +{{{0x185e962feab1a9c8, 0x86e7e63565147dcd, 0xb092e031bb5b6df2, 0x4024f0ab59d6b73e}}, + {{0x186d5e4c50fe1296, 0xe0397b82fee89f7e, 0x3bc7f6c5507031b0, 0x6678fd69108f37c2}}, + {{0x1586fa31636863c2, 0x07f68c48572d33f2, 0x4f73cc9f789eaefc, 0x2d42e2108ead4701}}}, +{{{0x97f5131594dfd29b, 0x6155985d313f4c6a, 0xeba13f0708455010, 0x676b2608b8d2d322}}, + {{0x21717b0d0f537593, 0x914e690b131e064c, 0x1bb687ae752ae09f, 0x420bf3a79b423c6e}}, + {{0x8138ba651c5b2b47, 0x8671b6ec311b1b80, 0x7bff0cb1bc3135b0, 0x745d2ffa9c0cf1e0}}}, +{{{0xbf525a1e2bc9c8bd, 0xea5b260826479d81, 0xd511c70edf0155db, 0x1ae23ceb960cf5d0}}, + {{0x6036df5721d34e6a, 0xb1db8827997bb3d0, 0xd3c209c3c8756afa, 0x06e15be54c1dc839}}, + {{0x5b725d871932994a, 0x32351cb5ceb1dab0, 0x7dc41549dab7ca05, 0x58ded861278ec1f7}}}, +{{{0xd8173793f266c55c, 0xc8c976c5cc454e49, 0x5ce382f8bc26c3a8, 0x2ff39de85485f6f9}}, + {{0x2dfb5ba8b6c2c9a8, 0x48eeef8ef52c598c, 0x33809107f12d1573, 0x08ba696b531d5bd8}}, + {{0x77ed3eeec3efc57a, 0x04e05517d4ff4811, 0xea3d7a3ff1a671cb, 0x120633b4947cfe54}}}, +{{{0x0b94987891610042, 0x4ee7b13cecebfae8, 0x70be739594f0a4c0, 0x35d30a99b4d59185}}, + {{0x82bd31474912100a, 0xde237b6d7e6fbe06, 0xe11e761911ea79c6, 0x07433be3cb393bde}}, + {{0xff7944c05ce997f4, 0x575d3de4b05c51a3, 0x583381fd5a76847c, 0x2d873ede7af6da9f}}}, +{{{0x157a316443373409, 0xfab8b7eef4aa81d9, 0xb093fee6f5a64806, 0x2e773654707fa7b6}}, + {{0xaa6202e14e5df981, 0xa20d59175015e1f5, 0x18a275d3bae21d6c, 0x0543618a01600253}}, + {{0x0deabdf4974c23c1, 0xaa6f0a259dce4693, 0x04202cb8a29aba2c, 0x4b1443362d07960d}}}, +{{{0xccc4b7c7b66e1f7a, 0x44157e25f50c2f7e, 0x3ef06dfc713eaf1c, 0x582f446752da63f7}}, + {{0x967c54e91c529ccb, 0x30f6269264c635fb, 0x2747aff478121965, 0x17038418eaf66f5c}}, + {{0xc6317bd320324ce4, 0xa81042e8a4488bc4, 0xb21ef18b4e5a1364, 0x0c2a1c4bcda28dc9}}}, +{{{0xd24dc7d06f1f0447, 0xb2269e3edb87c059, 0xd15b0272fbb2d28f, 0x7c558bd1c6f64877}}, + {{0xedc4814869bd6945, 0x0d6d907dbe1c8d22, 0xc63bd212d55cc5ab, 0x5a6a9b30a314dc83}}, + {{0xd0ec1524d396463d, 0x12bb628ac35a24f0, 0xa50c3a791cbc5fa4, 0x0404a5ca0afbafc3}}}, +{{{0x8c1f40070aa743d6, 0xccbad0cb5b265ee8, 0x574b046b668fd2de, 0x46395bfdcadd9633}}, + {{0x62bc9e1b2a416fd1, 0xb5c6f728e350598b, 0x04343fd83d5d6967, 0x39527516e7f8ee98}}, + {{0x117fdb2d1a5d9a9c, 0x9c7745bcd1005c2a, 0xefd4bef154d56fea, 0x76579a29e822d016}}}, +{{{0x45b68e7e49c02a17, 0x23cd51a2bca9a37f, 0x3ed65f11ec224c1b, 0x43a384dc9e05bdb1}}, + {{0x333cb51352b434f2, 0xd832284993de80e1, 0xb5512887750d35ce, 0x02c514bb2a2777c1}}, + {{0x684bd5da8bf1b645, 0xfb8bd37ef6b54b53, 0x313916d7a9b0d253, 0x1160920961548059}}}, +{{{0xb44d166929dacfaa, 0xda529f4c8413598f, 0xe9ef63ca453d5559, 0x351e125bc5698e0b}}, + {{0x7a385616369b4dcd, 0x75c02ca7655c3563, 0x7dc21bf9d4f18021, 0x2f637d7491e6e042}}, + {{0xd4b49b461af67bbe, 0xd603037ac8ab8961, 0x71dee19ff9a699fb, 0x7f182d06e7ce2a9a}}}, +{{{0x7a7c8e64ab0168ec, 0xcb5a4a5515edc543, 0x095519d347cd0eda, 0x67d4ac8c343e93b0}}, + {{0x09454b728e217522, 0xaa58e8f4d484b8d8, 0xd358254d7f46903c, 0x44acc043241c5217}}, + {{0x1c7d6bbb4f7a5777, 0x8b35fed4918313e1, 0x4adca1c6c96b4684, 0x556d1c8312ad71bd}}}, +{{{0x17ef40e30c8d3982, 0x31f7073e15a3fa34, 0x4f21f3cb0773646e, 0x746c6c6d1d824eff}}, + {{0x81f06756b11be821, 0x0faff82310a3f3dd, 0xf8b2d0556a99465d, 0x097abe38cc8c7f05}}, + {{0x0c49c9877ea52da4, 0x4c4369559bdc1d43, 0x022c3809f7ccebd2, 0x577e14a34bee84bd}}}, +{{{0xf0e268ac61a73b0a, 0xf2fafa103791a5f5, 0xc1e13e826b6d00e9, 0x60fa7ee96fd78f42}}, + {{0x94fecebebd4dd72b, 0xf46a4fda060f2211, 0x124a5977c0c8d1ff, 0x705304b8fb009295}}, + {{0xb63d1d354d296ec6, 0xf3c3053e5fad31d8, 0x670b958cb4bd42ec, 0x21398e0ca16353fd}}}, +{{{0x89f5058a382b33f3, 0x5ae2ba0bad48c0b4, 0x8f93b503a53db36e, 0x5aa3ed9d95a232e6}}, + {{0x2798aaf9b4b75601, 0x5eac72135c8dad72, 0xd2ceaa6161b7a023, 0x1bbfb284e98f7d4e}}, + {{0x656777e9c7d96561, 0xcb2b125472c78036, 0x65053299d9506eee, 0x4a07e14e5e8957cc}}}, +{{{0x4ee412cb980df999, 0xa315d76f3c6ec771, 0xbba5edde925c77fd, 0x3f0bac391d313402}}, + {{0x240b58cdc477a49b, 0xfd38dade6447f017, 0x19928d32a7c86aad, 0x50af7aed84afa081}}, + {{0x6e4fde0115f65be5, 0x29982621216109b2, 0x780205810badd6d9, 0x1921a316baebd006}}}, +{{{0x89422f7edfb870fc, 0x2c296beb4f76b3bd, 0x0738f1d436c24df7, 0x6458df41e273aeb0}}, + {{0xd75aad9ad9f3c18b, 0x566a0eef60b1c19c, 0x3e9a0bac255c0ed9, 0x7b049deca062c7f5}}, + {{0xdccbe37a35444483, 0x758879330fedbe93, 0x786004c312c5dd87, 0x6093dccbc2950e64}}}, +{{{0x1ff39a8585e0706d, 0x36d0a5d8b3e73933, 0x43b9f2e1718f453b, 0x57d1ea084827a97c}}, + {{0x6bdeeebe6084034b, 0x3199c2b6780fb854, 0x973376abb62d0695, 0x6e3180c98b647d90}}, + {{0xee7ab6e7a128b071, 0xa4c1596d93a88baa, 0xf7b4de82b2216130, 0x363e999ddd97bd18}}}, +{{{0x96a843c135ee1fc4, 0x976eb35508e4c8cf, 0xb42f6801b58cd330, 0x48ee9b78693a052b}}, + {{0x2f1848dce24baec6, 0x769b7255babcaf60, 0x90cb3c6e3cefe931, 0x231f979bc6f9b355}}, + {{0x5c31de4bcc2af3c6, 0xb04bb030fe208d1f, 0xb78d7009c14fb466, 0x079bfa9b08792413}}}, +{{{0xe3903a51da300df4, 0x843964233da95ab0, 0xed3cf12d0b356480, 0x038c77f684817194}}, + {{0xf3c9ed80a2d54245, 0x0aa08b7877f63952, 0xd76dac63d1085475, 0x1ef4fb159470636b}}, + {{0x854e5ee65b167bec, 0x59590a4296d0cdc2, 0x72b2df3498102199, 0x575ee92a4a0bff56}}}, +{{{0xd4c080908a182fcf, 0x30e170c299489dbd, 0x05babd5752f733de, 0x43d4e7112cd3fd00}}, + {{0x5d46bc450aa4d801, 0xc3af1227a533b9d8, 0x389e3b262b8906c2, 0x200a1e7e382f581b}}, + {{0x518db967eaf93ac5, 0x71bc989b056652c0, 0xfe2b85d9567197f5, 0x050eca52651e4e38}}}, +{{{0xc3431ade453f0c9c, 0xe9f5045eff703b9b, 0xfcd97ac9ed847b3d, 0x4b0ee6c21c58f4c6}}, + {{0x97ac397660e668ea, 0x9b19bbfe153ab497, 0x4cb179b534eca79f, 0x6151c09fa131ae57}}, + {{0x3af55c0dfdf05d96, 0xdd262ee02ab4ee7a, 0x11b2bb8712171709, 0x1fef24fa800f030b}}}, +{{{0x37d653fb1aa73196, 0x0f9495303fd76418, 0xad200b09fb3a17b2, 0x544d49292fc8613e}}, + {{0x22d2aff530976b86, 0x8d90b806c2d24604, 0xdca1896c4de5bae5, 0x28005fe6c8340c17}}, + {{0x6aefba9f34528688, 0x5c1bff9425107da1, 0xf75bbbcd66d94b36, 0x72e472930f316dfa}}}, +{{{0x2695208c9781084f, 0xb1502a0b23450ee1, 0xfd9daea603efde02, 0x5a9d2e8c2733a34c}}, + {{0x07f3f635d32a7627, 0x7aaa4d865f6566f0, 0x3c85e79728d04450, 0x1fee7f000fe06438}}, + {{0x765305da03dbf7e5, 0xa4daf2491434cdbd, 0x7b4ad5cdd24a88ec, 0x00f94051ee040543}}}, +{{{0x8d356b23c3d330b2, 0xf21c8b9bb0471b06, 0xb36c316c6e42b83c, 0x07d79c7e8beab10d}}, + {{0xd7ef93bb07af9753, 0x583ed0cf3db766a7, 0xce6998bf6e0b1ec5, 0x47b7ffd25dd40452}}, + {{0x87fbfb9cbc08dd12, 0x8a066b3ae1eec29b, 0x0d57242bdb1fc1bf, 0x1c3520a35ea64bb6}}}, +{{{0x80d253a6bccba34a, 0x3e61c3a13838219b, 0x90c3b6019882e396, 0x1c3d05775d0ee66f}}, + {{0xcda86f40216bc059, 0x1fbb231d12bcd87e, 0xb4956a9e17c70990, 0x38750c3b66d12e55}}, + {{0x692ef1409422e51a, 0xcbc0c73c2b5df671, 0x21014fe7744ce029, 0x0621e2c7d330487c}}}, +{{{0xaf9860cc8259838d, 0x90ea48c1c69f9adc, 0x6526483765581e30, 0x0007d6097bd3a5bc}}, + {{0xb7ae1796b0dbf0f3, 0x54dfafb9e17ce196, 0x25923071e9aaa3b4, 0x5d8e589ca1002e9d}}, + {{0xc0bf1d950842a94b, 0xb2d3c363588f2e3e, 0x0a961438bb51e2ef, 0x1583d7783c1cbf86}}}, +{{{0xeceea2ef5da27ae1, 0x597c3a1455670174, 0xc9a62a126609167a, 0x252a5f2e81ed8f70}}, + {{0x90034704cc9d28c7, 0x1d1b679ef72cc58f, 0x16e12b5fbe5b8726, 0x4958064e83c5580a}}, + {{0x0d2894265066e80d, 0xfcc3f785307c8c6b, 0x1b53da780c1112fd, 0x079c170bd843b388}}}, +{{{0x0506ece464fa6fff, 0xbee3431e6205e523, 0x3579422451b8ea42, 0x6dec05e34ac9fb00}}, + {{0xcdd6cd50c0d5d056, 0x9af7686dbb03573b, 0x3ca6723ff3c3ef48, 0x6768c0d7317b8acc}}, + {{0x94b625e5f155c1b3, 0x417bf3a7997b7b91, 0xc22cbddc6d6b2600, 0x51445e14ddcd52f4}}}, +{{{0x57502b4b3b144951, 0x8e67ff6b444bbcb3, 0xb8bd6927166385db, 0x13186f31e39295c8}}, + {{0x893147ab2bbea455, 0x8c53a24f92079129, 0x4b49f948be30f7a7, 0x12e990086e4fd43d}}, + {{0xf10c96b37fdfbb2e, 0x9f9a935e121ceaf9, 0xdf1136c43a5b983f, 0x77b2e3f05d3e99af}}}, +{{{0x296fa9c59c2ec4de, 0xbc8b61bf4f84f3cb, 0x1c7706d917a8f908, 0x63b795fc7ad3255d}}, + {{0xd598639c12ddb0a4, 0xa5d19f30c024866b, 0xd17c2f0358fce460, 0x07a195152e095e8a}}, + {{0xa8368f02389e5fc8, 0x90433b02cf8de43b, 0xafa1fd5dc5412643, 0x3e8fe83d032f0137}}}, +{{{0x2f8b15b90570a294, 0x94f2427067084549, 0xde1c5ae161bbfd84, 0x75ba3b797fac4007}}, + {{0x08704c8de8efd13c, 0xdfc51a8e33e03731, 0xa59d5da51260cde3, 0x22d60899a6258c86}}, + {{0x6239dbc070cdd196, 0x60fe8a8b6c7d8a9a, 0xb38847bceb401260, 0x0904d07b87779e5e}}}, +{{{0xb4ce1fd4ddba919c, 0xcf31db3ec74c8daa, 0x2c63cc63ad86cc51, 0x43e2143fbc1dde07}}, + {{0xf4322d6648f940b9, 0x06952f0cbd2d0c39, 0x167697ada081f931, 0x6240aacebaf72a6c}}, + {{0xf834749c5ba295a0, 0xd6947c5bca37d25a, 0x66f13ba7e7c9316a, 0x56bdaf238db40cac}}}, +{{{0x362ab9e3f53533eb, 0x338568d56eb93d40, 0x9e0e14521d5a5572, 0x1d24a86d83741318}}, + {{0x1310d36cc19d3bb2, 0x062a6bb7622386b9, 0x7c9b8591d7a14f5c, 0x03aa31507e1e5754}}, + {{0xf4ec7648ffd4ce1f, 0xe045eaf054ac8c1c, 0x88d225821d09357c, 0x43b261dc9aeb4859}}}, +{{{0xe55b1e1988bb79bb, 0xa09ed07dc17a359d, 0xb02c2ee2603dea33, 0x326055cf5b276bc2}}, + {{0x19513d8b6c951364, 0x94fe7126000bf47b, 0x028d10ddd54f9567, 0x02b4d5e242940964}}, + {{0xb4a155cb28d18df2, 0xeacc4646186ce508, 0xc49cf4936c824389, 0x27a6c809ae5d3410}}}, +{{{0x8ba6ebcd1f0db188, 0x37d3d73a675a5be8, 0xf22edfa315f5585a, 0x2cb67174ff60a17e}}, + {{0xcd2c270ac43d6954, 0xdd4a3e576a66cab2, 0x79fa592469d7036c, 0x221503603d8c2599}}, + {{0x59eecdf9390be1d0, 0xa9422044728ce3f1, 0x82891c667a94f0f4, 0x7b1df4b73890f436}}}, +{{{0xe492f2e0b3b2a224, 0x7c6c9e062b551160, 0x15eb8fe20d7f7b0e, 0x61fcef2658fc5992}}, + {{0x5f2e221807f8f58c, 0xe3555c9fd49409d4, 0xb2aaa88d1fb6a630, 0x68698245d352e03d}}, + {{0xdbb15d852a18187a, 0xf3e4aad386ddacd7, 0x44bae2810ff6c482, 0x46cf4c473daf01cf}}}, +{{{0x426525ed9ec4e5f9, 0x0e5eda0116903303, 0x72b1a7f2cbe5cadc, 0x29387bcd14eb5f40}}, + {{0x213c6ea7f1498140, 0x7c1e7ef8392b4854, 0x2488c38c5629ceba, 0x1065aae50d8cc5bb}}, + {{0x1c2c4525df200d57, 0x5c3b2dd6bfca674a, 0x0a07e7b1e1834030, 0x69a198e64f1ce716}}}, +{{{0x9062b2e0d91a78bc, 0x47c9889cc8509667, 0x9df54a66405070b8, 0x7369e6a92493a1bf}}, + {{0xe1014434dcc5caed, 0x47ed5d963c84fb33, 0x70019576ed86a0e7, 0x25b2697bd267f9e4}}, + {{0x9d673ffb13986864, 0x3ca5fbd9415dc7b8, 0xe04ecc3bdf273b5e, 0x1420683db54e4cd2}}}, +{{{0xb478bd1e249dd197, 0x620c35005e58c102, 0xfb02d32fccbaac5c, 0x60b63bebf508a72d}}, + {{0x34eebb6fc1cc5ad0, 0x6a1b0ce99646ac8b, 0xd3b0da49a66bde53, 0x31e83b4161d081c1}}, + {{0x97e8c7129e062b4f, 0x49e48f4f29320ad8, 0x5bece14b6f18683f, 0x55cf1eb62d550317}}}, +{{{0x5879101065c23d58, 0x8b9d086d5094819c, 0xe2402fa912c55fa7, 0x669a6564570891d4}}, + {{0x3076b5e37df58c52, 0xd73ab9dde799cc36, 0xbd831ce34913ee20, 0x1a56fbaa62ba0133}}, + {{0x943e6b505c9dc9ec, 0x302557bba77c371a, 0x9873ae5641347651, 0x13c4836799c58a5c}}}, +{{{0x423a5d465ab3e1b9, 0xfc13c187c7f13f61, 0x19f83664ecb5b9b6, 0x66f80c93a637b607}}, + {{0xc4dcfb6a5d8bd080, 0xdeebc4ec571a4842, 0xd4b2e883b8e55365, 0x50bdc87dc8e5b827}}, + {{0x606d37836edfe111, 0x32353e15f011abd9, 0x64b03ac325b73b96, 0x1dd56444725fd5ae}}}, +{{{0x8fa47ff83362127d, 0xbc9f6ac471cd7c15, 0x6e71454349220c8b, 0x0e645912219f732e}}, + {{0xc297e60008bac89a, 0x7d4cea11eae1c3e0, 0xf3e38be19fe7977c, 0x3a3a450f63a305cd}}, + {{0x078f2f31d8394627, 0x389d3183de94a510, 0xd1e36c6d17996f80, 0x318c8d9393a9a87b}}}, +{{{0xf2745d032afffe19, 0x0c9f3c497f24db66, 0xbc98d3e3ba8598ef, 0x224c7c679a1d5314}}, + {{0x5d669e29ab1dd398, 0xfc921658342d9e3b, 0x55851dfdf35973cd, 0x509a41c325950af6}}, + {{0xbdc06edca6f925e9, 0x793ef3f4641b1f33, 0x82ec12809d833e89, 0x05bff02328a11389}}}, +{{{0x3632137023cae00b, 0x544acf0ad1accf59, 0x96741049d21a1c88, 0x780b8cc3fa2a44a7}}, + {{0x6881a0dd0dc512e4, 0x4fe70dc844a5fafe, 0x1f748e6b8f4a5240, 0x576277cdee01a3ea}}, + {{0x1ef38abc234f305f, 0x9a577fbd1405de08, 0x5e82a51434e62a0d, 0x5ff418726271b7a1}}}, +{{{0x398e080c1789db9d, 0xa7602025f3e778f5, 0xfa98894c06bd035d, 0x106a03dc25a966be}}, + {{0xe5db47e813b69540, 0xf35d2a3b432610e1, 0xac1f26e938781276, 0x29d4db8ca0a0cb69}}, + {{0xd9ad0aaf333353d0, 0x38669da5acd309e5, 0x3c57658ac888f7f0, 0x4ab38a51052cbefa}}}, +{{{0xda7c2b256768d593, 0x98c1c0574422ca13, 0xf1a80bd5ca0ace1d, 0x29cdd1adc088a690}}, + {{0xd6cfd1ef5fddc09c, 0xe82b3efdf7575dce, 0x25d56b5d201634c2, 0x3041c6bb04ed2b9b}}, + {{0x0ff2f2f9d956e148, 0xade797759f356b2e, 0x1a4698bb5f6c025c, 0x104bbd6814049a7b}}}, +{{{0x51f0fd3168f1ed67, 0x2c811dcdd86f3bc2, 0x44dc5c4304d2f2de, 0x5be8cc57092a7149}}, + {{0xa95d9a5fd67ff163, 0xe92be69d4cc75681, 0xb7f8024cde20f257, 0x204f2a20fb072df5}}, + {{0xc8143b3d30ebb079, 0x7589155abd652e30, 0x653c3c318f6d5c31, 0x2570fb17c279161f}}}, +{{{0x3efa367f2cb61575, 0xf5f96f761cd6026c, 0xe8c7142a65b52562, 0x3dcb65ea53030acd}}, + {{0x192ea9550bb8245a, 0xc8e6fba88f9050d1, 0x7986ea2d88a4c935, 0x241c5f91de018668}}, + {{0x28d8172940de6caa, 0x8fbf2cf022d9733a, 0x16d7fcdd235b01d1, 0x08420edd5fcdf0e5}}}, +{{{0xcdff20ab8362fa4a, 0x57e118d4e21a3e6e, 0xe3179617fc39e62b, 0x0d9a53efbc1769fd}}, + {{0x0358c34e04f410ce, 0xb6135b5a276e0685, 0x5d9670c7ebb91521, 0x04d654f321db889c}}, + {{0x5e7dc116ddbdb5d5, 0x2954deb68da5dd2d, 0x1cb608173334a292, 0x4a7a4f2618991ad7}}}, +{{{0xf4a718025fb15f95, 0x3df65f346b5c1b8f, 0xcdfcf08500e01112, 0x11b50c4cddd31848}}, + {{0x24c3b291af372a4b, 0x93da8270718147f2, 0xdd84856486899ef2, 0x4a96314223e0ee33}}, + {{0xa6e8274408a4ffd6, 0x738e177e9c1576d9, 0x773348b63d02b3f2, 0x4f4bce4dce6bcc51}}}, +{{{0xa71fce5ae2242584, 0x26ea725692f58a9e, 0xd21a09d71cea3cf4, 0x73fcdd14b71c01e6}}, + {{0x30e2616ec49d0b6f, 0xe456718fcaec2317, 0x48eb409bf26b4fa6, 0x3042cee561595f37}}, + {{0x427e7079449bac41, 0x855ae36dbce2310a, 0x4cae76215f841a7c, 0x389e740c9a9ce1d6}}}, +{{{0x64fcb3ae34dcb9ce, 0x97500323e348d0ad, 0x45b3f07d62c6381b, 0x61545379465a6788}}, + {{0xc9bd78f6570eac28, 0xe55b0b3227919ce1, 0x65fc3eaba19b91ed, 0x25c425e5d6263690}}, + {{0x3f3e06a6f1d7de6e, 0x3ef976278e062308, 0x8c14f6264e8a6c77, 0x6539a08915484759}}}, +{{{0xe9d21f74c3d2f773, 0xc150544125c46845, 0x624e5ce8f9b99e33, 0x11c5e4aac5cd186c}}, + {{0xddc4dbd414bb4a19, 0x19b2bc3c98424f8e, 0x48a89fd736ca7169, 0x0f65320ef019bd90}}, + {{0xd486d1b1cafde0c6, 0x4f3fe6e3163b5181, 0x59a8af0dfaf2939a, 0x4cabc7bdec33072a}}}, +{{{0x239e9624089c0a2e, 0xc748c4c03afe4738, 0x17dbed2a764fa12a, 0x639b93f0321c8582}}, + {{0xc08f788f3f78d289, 0xfe30a72ca1404d9f, 0xf2778bfccf65cc9d, 0x7ee498165acb2021}}, + {{0x7bd508e39111a1c3, 0x2b2b90d480907489, 0xe7d2aec2ae72fd19, 0x0edf493c85b602a6}}}, +{{{0xaecc8158599b5a68, 0xea574f0febade20e, 0x4fe41d7422b67f07, 0x403b92e3019d4fb4}}, + {{0x6767c4d284764113, 0xa090403ff7f5f835, 0x1c8fcffacae6bede, 0x04c00c54d1dfa369}}, + {{0x4dc22f818b465cf8, 0x71a0f35a1480eff8, 0xaee8bfad04c7d657, 0x355bb12ab26176f4}}}, +{{{0xa71e64cc7493bbf4, 0xe5bd84d9eca3b0c3, 0x0a6bc50cfa05e785, 0x0f9b8132182ec312}}, + {{0xa301dac75a8c7318, 0xed90039db3ceaa11, 0x6f077cbf3bae3f2d, 0x7518eaf8e052ad8e}}, + {{0xa48859c41b7f6c32, 0x0f2d60bcf4383298, 0x1815a929c9b1d1d9, 0x47c3871bbb1755c4}}}, +{{{0x5144539771ec4f48, 0xf805b17dc98c5d6e, 0xf762c11a47c3c66b, 0x00b89b85764699dc}}, + {{0xfbe65d50c85066b0, 0x62ecc4b0b3a299b0, 0xe53754ea441ae8e0, 0x08fea02ce8d48d5f}}, + {{0x824ddd7668deead0, 0xc86445204b685d23, 0xb514cfcd5d89d665, 0x473829a74f75d537}}}, +{{{0x82d2da754679c418, 0xe63bd7d8b2618df0, 0x355eef24ac47eb0a, 0x2078684c4833c6b4}}, + {{0x23d9533aad3902c9, 0x64c2ddceef03588f, 0x15257390cfe12fb4, 0x6c668b4d44e4d390}}, + {{0x3b48cf217a78820c, 0xf76a0ab281273e97, 0xa96c65a78c8eed7b, 0x7411a6054f8a433f}}}, +{{{0x4d659d32b99dc86d, 0x044cdc75603af115, 0xb34c712cdcc2e488, 0x7c136574fb8134ff}}, + {{0x579ae53d18b175b4, 0x68713159f392a102, 0x8455ecba1eef35f5, 0x1ec9a872458c398f}}, + {{0xb8e6a4d400a2509b, 0x9b81d7020bc882b4, 0x57e7cc9bf1957561, 0x3add88a5c7cd6460}}}, +{{{0xab895770b635dcf2, 0x02dfef6cf66c1fbc, 0x85530268beb6d187, 0x249929fccc879e74}}, + {{0x85c298d459393046, 0x8f7e35985ff659ec, 0x1d2ca22af2f66e3a, 0x61ba1131a406a720}}, + {{0xa3d0a0f116959029, 0x023b6b6cba7ebd89, 0x7bf15a3e26783307, 0x5620310cbbd8ece7}}}, +{{{0x528993434934d643, 0xb9dbf806a51222f5, 0x8f6d878fc3f41c22, 0x37676a2a4d9d9730}}, + {{0x6646b5f477e285d6, 0x40e8ff676c8f6193, 0xa6ec7311abb594dd, 0x7ec846f3658cec4d}}, + {{0x9b5e8f3f1da22ec7, 0x130f1d776c01cd13, 0x214c8fcfa2989fb8, 0x6daaf723399b9dd5}}}, +{{{0x5f3a7562eb3dbe47, 0xf7ea38548ebda0b8, 0x00c3e53145747299, 0x1304e9e71627d551}}, + {{0x583b04bfacad8ea2, 0x29b743e8148be884, 0x2b1e583b0810c5db, 0x2b5449e58eb3bbaa}}, + {{0x789814d26adc9cfe, 0x3c1bab3f8b48dd0b, 0xda0fe1fff979c60a, 0x4468de2d7c2dd693}}}, +{{{0x51bb355e9419469e, 0x33e6dc4c23ddc754, 0x93a5b6d6447f9962, 0x6cce7c6ffb44bd63}}, + {{0x4b9ad8c6f86307ce, 0x21113531435d0c28, 0xd4a866c5657a772c, 0x5da6427e63247352}}, + {{0x1a94c688deac22ca, 0xb9066ef7bbae1ff8, 0x88ad8c388d59580f, 0x58f29abfe79f2ca8}}}, +{{{0xe90ecfab8de73e68, 0x54036f9f377e76a5, 0xf0495b0bbe015982, 0x577629c4a7f41e36}}, + {{0x4b5a64bf710ecdf6, 0xb14ce538462c293c, 0x3643d056d50b3ab9, 0x6af93724185b4870}}, + {{0x3220024509c6a888, 0xd2e036134b558973, 0x83e236233c33289f, 0x701f25bb0caec18f}}}, +{{{0xc3a8b0f8e4616ced, 0xf700660e9e25a87d, 0x61e3061ff4bca59c, 0x2e0c92bfbdc40be9}}, + {{0x9d18f6d97cbec113, 0x844a06e674bfdbe4, 0x20f5b522ac4e60d6, 0x720a5bc050955e51}}, + {{0x0c3f09439b805a35, 0xe84e8b376242abfc, 0x691417f35c229346, 0x0e9b9cbb144ef0ec}}}, +{{{0xfbbad48ffb5720ad, 0xee81916bdbf90d0e, 0xd4813152635543bf, 0x221104eb3f337bd8}}, + {{0x8dee9bd55db1beee, 0xc9c3ab370a723fb9, 0x44a8f1bf1c68d791, 0x366d44191cfd3cde}}, + {{0x9e3c1743f2bc8c14, 0x2eda26fcb5856c3b, 0xccb82f0e68a7fb97, 0x4167a4e6bc593244}}}, +{{{0x643b9d2876f62700, 0x5d1d9d400e7668eb, 0x1b4b430321fc0684, 0x7938bb7e2255246a}}, + {{0xc2be2665f8ce8fee, 0xe967ff14e880d62c, 0xf12e6e7e2f364eee, 0x34b33370cb7ed2f6}}, + {{0xcdc591ee8681d6cc, 0xce02109ced85a753, 0xed7485c158808883, 0x1176fc6e2dfe65e4}}}, +{{{0xb4af6cd05b9c619b, 0x2ddfc9f4b2a58480, 0x3d4fa502ebe94dc4, 0x08fc3a4c677d5f34}}, + {{0xdb90e28949770eb8, 0x98fbcc2aacf440a3, 0x21354ffeded7879b, 0x1f6a3e54f26906b6}}, + {{0x60a4c199d30734ea, 0x40c085b631165cd6, 0xe2333e23f7598295, 0x4f2fad0116b900d1}}}, +{{{0x44beb24194ae4e54, 0x5f541c511857ef6c, 0xa61e6b2d368d0498, 0x445484a4972ef7ab}}, + {{0x962cd91db73bb638, 0xe60577aafc129c08, 0x6f619b39f3b61689, 0x3451995f2944ee81}}, + {{0x9152fcd09fea7d7c, 0x4a816c94b0935cf6, 0x258e9aaa47285c40, 0x10b89ca6042893b7}}}, +{{{0x3d5947499718289c, 0x12ebf8c524533f26, 0x0262bfcb14c3ef15, 0x20b878d577b7518e}}, + {{0x753941be5a45f06e, 0xd07caeed6d9c5f65, 0x11776b9c72ff51b6, 0x17d2d1d9ef0d4da9}}, + {{0x27f2af18073f3e6a, 0xfd3fe519d7521069, 0x22e3b72c3ca60022, 0x72214f63cc65c6a7}}}, +{{{0xb4e37f405307a693, 0xaba714d72f336795, 0xd6fbd0a773761099, 0x5fdf48c58171cbc9}}, + {{0x1d9db7b9f43b29c9, 0xd605824a4f518f75, 0xf2c072bd312f9dc4, 0x1f24ac855a1545b0}}, + {{0x24d608328e9505aa, 0x4748c1d10c1420ee, 0xc7ffe45c06fb25a2, 0x00ba739e2ae395e6}}}, +{{{0x592e98de5c8790d6, 0xe5bfb7d345c2a2df, 0x115a3b60f9b49922, 0x03283a3e67ad78f3}}, + {{0xae4426f5ea88bb26, 0x360679d984973bfb, 0x5c9f030c26694e50, 0x72297de7d518d226}}, + {{0x48241dc7be0cb939, 0x32f19b4d8b633080, 0xd3dfc90d02289308, 0x05e1296846271945}}}, +{{{0xba82eeb32d9c495a, 0xceefc8fcf12bb97c, 0xb02dabae93b5d1e0, 0x39c00c9c13698d9b}}, + {{0xadbfbbc8242c4550, 0xbcc80cecd03081d9, 0x843566a6f5c8df92, 0x78cf25d38258ce4c}}, + {{0x15ae6b8e31489d68, 0xaa851cab9c2bf087, 0xc9a75a97f04efa05, 0x006b52076b3ff832}}}, +{{{0x29e0cfe19d95781c, 0xb681df18966310e2, 0x57df39d370516b39, 0x4d57e3443bc76122}}, + {{0xf5cb7e16b9ce082d, 0x3407f14c417abc29, 0xd4b36bce2bf4a7ab, 0x7de2e9561a9f75ce}}, + {{0xde70d4f4b6a55ecb, 0x4801527f5d85db99, 0xdbc9c440d3ee9a81, 0x6b2a90af1a6029ed}}}, +{{{0x6923f4fc9ae61e97, 0x5735281de03f5fd1, 0xa764ae43e6edd12d, 0x5fd8f4e9d12d3e4a}}, + {{0x77ebf3245bb2d80a, 0xd8301b472fb9079b, 0xc647e6f24cee7333, 0x465812c8276c2109}}, + {{0x4d43beb22a1062d9, 0x7065fb753831dc16, 0x180d4a7bde2968d7, 0x05b32c2b1cb16790}}}, +{{{0xc8c05eccd24da8fd, 0xa1cf1aac05dfef83, 0xdbbeeff27df9cd61, 0x3b5556a37b471e99}}, + {{0xf7fca42c7ad58195, 0x3214286e4333f3cc, 0xb6c29d0d340b979d, 0x31771a48567307e1}}, + {{0x32b0c524e14dd482, 0xedb351541a2ba4b6, 0xa3d16048282b5af3, 0x4fc079d27a7336eb}}}, +{{{0x51c938b089bf2f7f, 0x2497bd6502dfe9a7, 0xffffc09c7880e453, 0x124567cecaf98e92}}, + {{0xdc348b440c86c50d, 0x1337cbc9cc94e651, 0x6422f74d643e3cb9, 0x241170c2bae3cd08}}, + {{0x3ff9ab860ac473b4, 0xf0911dee0113e435, 0x4ae75060ebc6c4af, 0x3f8612966c87000d}}}, +{{{0x559a0cc9782a0dde, 0x551dcdb2ea718385, 0x7f62865b31ef238c, 0x504aa7767973613d}}, + {{0x9c18fcfa36048d13, 0x29159db373899ddd, 0xdc9f350b9f92d0aa, 0x26f57eee878a19d4}}, + {{0x0cab2cd55687efb1, 0x5180d162247af17b, 0x85c15a344f5a2467, 0x4041943d9dba3069}}}, +{{{0xc3c0eeba43ebcc96, 0x8d749c9c26ea9caf, 0xd9fa95ee1c77ccc6, 0x1420a1d97684340f}}, + {{0x4b217743a26caadd, 0x47a6b424648ab7ce, 0xcb1d4f7a03fbc9e3, 0x12d931429800d019}}, + {{0x00c67799d337594f, 0x5e3c5140b23aa47b, 0x44182854e35ff395, 0x1b4f92314359a012}}}, +{{{0x3e5c109d89150951, 0x39cefa912de9696a, 0x20eae43f975f3020, 0x239b572a7f132dae}}, + {{0x33cf3030a49866b1, 0x251f73d2215f4859, 0xab82aa4051def4f6, 0x5ff191d56f9a23f6}}, + {{0x819ed433ac2d9068, 0x2883ab795fc98523, 0xef4572805593eb3d, 0x020c526a758f36cb}}}, +{{{0x779834f89ed8dbbc, 0xc8f2aaf9dc7ca46c, 0xa9524cdca3e1b074, 0x02aacc4615313877}}, + {{0xe931ef59f042cc89, 0x2c589c9d8e124bb6, 0xadc8e18aaec75997, 0x452cfe0a5602c50c}}, + {{0x86a0f7a0647877df, 0xbbc464270e607c9f, 0xab17ea25f1fb11c9, 0x4cfb7d7b304b877b}}}, +{{{0x72b43d6cb89b75fe, 0x54c694d99c6adc80, 0xb8c3aa373ee34c9f, 0x14b4622b39075364}}, + {{0xe28699c29789ef12, 0x2b6ecd71df57190d, 0xc343c857ecc970d0, 0x5b1d4cbc434d3ac5}}, + {{0xb6fb2615cc0a9f26, 0x3a4f0e2bb88dcce5, 0x1301498b3369a705, 0x2f98f71258592dd1}}}, +{{{0x0c94a74cb50f9e56, 0x5b1ff4a98e8e1320, 0x9a2acc2182300f67, 0x3a6ae249d806aaf9}}, + {{0x2e12ae444f54a701, 0xfcfe3ef0a9cbd7de, 0xcebf890d75835de0, 0x1d8062e9e7614554}}, + {{0x657ada85a9907c5a, 0x1a0ea8b591b90f62, 0x8d0e1dfbdf34b4e9, 0x298b8ce8aef25ff3}}}, +{{{0x2a927953eff70cb2, 0x4b89c92a79157076, 0x9418457a30a7cf6a, 0x34b8a8404d5ce485}}, + {{0x837a72ea0a2165de, 0x3fab07b40bcf79f6, 0x521636c77738ae70, 0x6ba6271803a7d7dc}}, + {{0xc26eecb583693335, 0xd5a813df63b5fefd, 0xa293aa9aa4b22573, 0x71d62bdd465e1c6a}}}, +{{{0x6533cc28d378df80, 0xf6db43790a0fa4b4, 0xe3645ff9f701da5a, 0x74d5f317f3172ba4}}, + {{0xcd2db5dab1f75ef5, 0xd77f95cf16b065f5, 0x14571fea3f49f085, 0x1c333621262b2b3d}}, + {{0xa86fe55467d9ca81, 0x398b7c752b298c37, 0xda6d0892e3ac623b, 0x4aebcc4547e9d98c}}}, +{{{0x12f0071b276d01c9, 0xe7b8bac586c48c70, 0x5308129b71d6fba9, 0x5d88fbf95a3db792}}, + {{0x0b408d9e7354b610, 0x806b32535ba85b6e, 0xdbe63a034a58a207, 0x173bd9ddc9a1df2c}}, + {{0x2b500f1efe5872df, 0x58d6582ed43918c1, 0xe6ed278ec9673ae0, 0x06e1cd13b19ea319}}}, +{{{0x40d0ad516f166f23, 0x118e32931fab6abe, 0x3fe35e14a04d088e, 0x3080603526e16266}}, + {{0x472baf629e5b0353, 0x3baa0b90278d0447, 0x0c785f469643bf27, 0x7f3a6a1a8d837b13}}, + {{0xf7e644395d3d800b, 0x95a8d555c901edf6, 0x68cd7830592c6339, 0x30d0fded2e51307e}}}, +{{{0xe0594d1af21233b3, 0x1bdbe78ef0cc4d9c, 0x6965187f8f499a77, 0x0a9214202c099868}}, + {{0x9cb4971e68b84750, 0xa09572296664bbcf, 0x5c8de72672fa412b, 0x4615084351c589d9}}, + {{0xbc9019c0aeb9a02e, 0x55c7110d16034cae, 0x0e6df501659932ec, 0x3bca0d2895ca5dfe}}}, +{{{0x40f031bc3c5d62a4, 0x19fc8b3ecff07a60, 0x98183da2130fb545, 0x5631deddae8f13cd}}, + {{0x9c688eb69ecc01bf, 0xf0bc83ada644896f, 0xca2d955f5f7a9fe2, 0x4ea8b4038df28241}}, + {{0x2aed460af1cad202, 0x46305305a48cee83, 0x9121774549f11a5f, 0x24ce0930542ca463}}}, +{{{0x1fe890f5fd06c106, 0xb5c468355d8810f2, 0x827808fe6e8caf3e, 0x41d4e3c28a06d74b}}, + {{0x3fcfa155fdf30b85, 0xd2f7168e36372ea4, 0xb2e064de6492f844, 0x549928a7324f4280}}, + {{0xf26e32a763ee1a2e, 0xae91e4b7d25ffdea, 0xbc3bd33bd17f4d69, 0x491b66dec0dcff6a}}}, +{{{0x98f5b13dc7ea32a7, 0xe3d5f8cc7e16db98, 0xac0abf52cbf8d947, 0x08f338d0c85ee4ac}}, + {{0x75f04a8ed0da64a1, 0xed222caf67e2284b, 0x8234a3791f7b7ba4, 0x4cf6b8b0b7018b67}}, + {{0xc383a821991a73bd, 0xab27bc01df320c7a, 0xc13d331b84777063, 0x530d4a82eb078a99}}}, +{{{0x004c3630e1f94825, 0x7e2d78268cab535a, 0xc7482323cc84ff8b, 0x65ea753f101770b9}}, + {{0x6d6973456c9abf9e, 0x257fb2fc4900a880, 0x2bacf412c8cfb850, 0x0db3e7e00cbfbd5b}}, + {{0x3d66fc3ee2096363, 0x81d62c7f61b5cb6b, 0x0fbe044213443b1a, 0x02a4ec1921e1a1db}}}, +{{{0x5ce6259a3b24b8a2, 0xb8577acc45afa0b8, 0xcccbe6e88ba07037, 0x3d143c51127809bf}}, + {{0xf5c86162f1cf795f, 0x118c861926ee57f2, 0x172124851c063578, 0x36d12b5dec067fcf}}, + {{0x126d279179154557, 0xd5e48f5cfc783a0a, 0x36bdb6e8df179bac, 0x2ef517885ba82859}}}, +{{{0x4637974e8c58aedc, 0xb9ef22fbabf041a4, 0xe185d956e980718a, 0x2f1b78fab143a8a6}}, + {{0x96eebffb305b2f51, 0xd3f938ad889596b8, 0xf0f52dc746d5dd25, 0x57968290bb3a0095}}, + {{0xf71ab8430a20e101, 0xf393658d24f0ec47, 0xcf7509a86ee2eed1, 0x7dc43e35dc2aa3e1}}}, +{{{0x85966665887dd9c3, 0xc90f9b314bb05355, 0xc6e08df8ef2079b1, 0x7ef72016758cc12f}}, + {{0x5a782a5c273e9718, 0x3576c6995e4efd94, 0x0f2ed8051f237d3e, 0x044fb81d82d50a99}}, + {{0xc1df18c5a907e3d9, 0x57b3371dce4c6359, 0xca704534b201bb49, 0x7f79823f9c30dd2e}}}, +{{{0x8334d239a3b513e8, 0xc13670d4b91fa8d8, 0x12b54136f590bd33, 0x0a4e0373d784d9b4}}, + {{0x6a9c1ff068f587ba, 0x0827894e0050c8de, 0x3cbf99557ded5be7, 0x64a9b0431c06d6f0}}, + {{0x2eb3d6a15b7d2919, 0xb0b4f6a0d53a8235, 0x7156ce4389a45d47, 0x071a7d0ace18346c}}}, +{{{0xd3072daac887ba0b, 0x01262905bfa562ee, 0xcf543002c0ef768b, 0x2c3bcc7146ea7e9c}}, + {{0xcc0c355220e14431, 0x0d65950709b15141, 0x9af5621b209d5f36, 0x7c69bcf7617755d3}}, + {{0x07f0d7eb04e8295f, 0x10db18252f50f37d, 0xe951a9a3171798d7, 0x6f5a9a7322aca51d}}}, +{{{0x8ba1000c2f41c6c5, 0xc49f79c10cfefb9b, 0x4efa47703cc51c9f, 0x494e21a2e147afca}}, + {{0xe729d4eba3d944be, 0x8d9e09408078af9e, 0x4525567a47869c03, 0x02ab9680ee8d3b24}}, + {{0xefa48a85dde50d9a, 0x219a224e0fb9a249, 0xfa091f1dd91ef6d9, 0x6b5d76cbea46bb34}}}, +{{{0x8857556cec0cd994, 0x6472dc6f5cd01dba, 0xaf0169148f42b477, 0x0ae333f685277354}}, + {{0xe0f941171e782522, 0xf1e6ae74036936d3, 0x408b3ea2d0fcc746, 0x16fb869c03dd313e}}, + {{0x288e199733b60962, 0x24fc72b4d8abe133, 0x4811f7ed0991d03e, 0x3f81e38b8f70d075}}}, +{{{0x7f910fcc7ed9affe, 0x545cb8a12465874b, 0xa8397ed24b0c4704, 0x50510fc104f50993}}, + {{0x0adb7f355f17c824, 0x74b923c3d74299a4, 0xd57c3e8bcbf8eaf7, 0x0ad3e2d34cdedc3d}}, + {{0x6f0c0fc5336e249d, 0x745ede19c331cfd9, 0xf2d6fd0009eefe1c, 0x127c158bf0fa1ebe}}}, +{{{0xf6197c422e9879a2, 0xa44addd452ca3647, 0x9b413fc14b4eaccb, 0x354ef87d07ef4f68}}, + {{0xdea28fc4ae51b974, 0x1d9973d3744dfe96, 0x6240680b873848a8, 0x4ed82479d167df95}}, + {{0xfee3b52260c5d975, 0x50352efceb41b0b8, 0x8808ac30a9f6653c, 0x302d92d20539236d}}}, +{{{0x7813c1a2bca4283d, 0xed62f091a1863dd9, 0xaec7bcb8c268fa86, 0x10e5d3b76f1cae4c}}, + {{0x2dbc6fb6e4e0f177, 0x04e1bf29a4bd6a93, 0x5e1966d4787af6e8, 0x0edc5f5eb426d060}}, + {{0x5453bfd653da8e67, 0xe9dc1eec24a9f641, 0xbf87263b03578a23, 0x45b46c51361cba72}}}, +{{{0xa9402abf314f7fa1, 0xe257f1dc8e8cf450, 0x1dbbd54b23a8be84, 0x2177bfa36dcb713b}}, + {{0xce9d4ddd8a7fe3e4, 0xab13645676620e30, 0x4b594f7bb30e9958, 0x5c1c0aef321229df}}, + {{0x37081bbcfa79db8f, 0x6048811ec25f59b3, 0x087a76659c832487, 0x4ae619387d8ab5bb}}}, +{{{0x8ddbf6aa5344a32e, 0x7d88eab4b41b4078, 0x5eb0eb974a130d60, 0x1a00d91b17bf3e03}}, + {{0x61117e44985bfb83, 0xfce0462a71963136, 0x83ac3448d425904b, 0x75685abe5ba43d64}}, + {{0x6e960933eb61f2b2, 0x543d0fa8c9ff4952, 0xdf7275107af66569, 0x135529b623b0e6aa}}}, +{{{0x18f0dbd7add1d518, 0x979f7888cfc11f11, 0x8732e1f07114759b, 0x79b5b81a65ca3a01}}, + {{0xf5c716bce22e83fe, 0xb42beb19e80985c1, 0xec9da63714254aae, 0x5972ea051590a613}}, + {{0x0fd4ac20dc8f7811, 0x9a9ad294ac4d4fa8, 0xc01b2d64b3360434, 0x4f7e9c95905f3bdb}}}, +{{{0x62674bbc5781302e, 0xd8520f3989addc0f, 0x8c2999ae53fbd9c6, 0x31993ad92e638e4c}}, + {{0x71c8443d355299fe, 0x8bcd3b1cdbebead7, 0x8092499ef1a49466, 0x1942eec4a144adc8}}, + {{0x7dac5319ae234992, 0x2c1b3d910cea3e92, 0x553ce494253c1122, 0x2a0a65314ef9ca75}}}, +{{{0x2db7937ff7f927c2, 0xdb741f0617d0a635, 0x5982f3a21155af76, 0x4cf6e218647c2ded}}, + {{0xcf361acd3c1c793a, 0x2f9ebcac5a35bc3b, 0x60e860e9a8cda6ab, 0x055dc39b6dea1a13}}, + {{0xb119227cc28d5bb6, 0x07e24ebc774dffab, 0xa83c78cee4a32c89, 0x121a307710aa24b6}}}, +{{{0xe4db5d5e9f034a97, 0xe153fc093034bc2d, 0x460546919551d3b1, 0x333fc76c7a40e52d}}, + {{0xd659713ec77483c9, 0x88bfe077b82b96af, 0x289e28231097bcd3, 0x527bb94a6ced3a9b}}, + {{0x563d992a995b482e, 0x3405d07c6e383801, 0x485035de2f64d8e5, 0x6b89069b20a7a9f7}}}, +{{{0x812aa0416270220d, 0x995a89faf9245b4e, 0xffadc4ce5072ef05, 0x23bc2103aa73eb73}}, + {{0x4082fa8cb5c7db77, 0x068686f8c734c155, 0x29e6c8d9f6e7a57e, 0x0473d308a7639bcf}}, + {{0xcaee792603589e05, 0x2b4b421246dcc492, 0x02a1ef74e601a94f, 0x102f73bfde04341a}}}, +{{{0xeb18b9ab7f5745c6, 0x023a8aee5787c690, 0xb72712da2df7afa9, 0x36597d25ea5c013d}}, + {{0xa2b4dae0b5511c9a, 0x7ac860292bffff06, 0x981f375df5504234, 0x3f6bd725da4ea12d}}, + {{0x734d8d7b106058ac, 0xd940579e6fc6905f, 0x6466f8f99202932d, 0x7b7ecc19da60d6d0}}}, +{{{0x78c2373c695c690d, 0xdd252e660642906e, 0x951d44444ae12bd2, 0x4235ad7601743956}}, + {{0x6dae4a51a77cfa9b, 0x82263654e7a38650, 0x09bbffcd8f2d82db, 0x03bedc661bf5caba}}, + {{0x6258cb0d078975f5, 0x492942549189f298, 0xa0cab423e2e36ee4, 0x0e7ce2b0cdf066a1}}}, +{{{0xc494643ac48c85a3, 0xfd361df43c6139ad, 0x09db17dd3ae94d48, 0x666e0a5d8fb4674a}}, + {{0xfea6fedfd94b70f9, 0xf130c051c1fcba2d, 0x4882d47e7f2fab89, 0x615256138aeceeb5}}, + {{0x2abbf64e4870cb0d, 0xcd65bcf0aa458b6b, 0x9abe4eba75e8985d, 0x7f0bc810d514dee4}}}, +{{{0xb9006ba426f4136f, 0x8d67369e57e03035, 0xcbc8dfd94f463c28, 0x0d1f8dbcf8eedbf5}}, + {{0x83ac9dad737213a0, 0x9ff6f8ba2ef72e98, 0x311e2edd43ec6957, 0x1d3a907ddec5ab75}}, + {{0xba1693313ed081dc, 0x29329fad851b3480, 0x0128013c030321cb, 0x00011b44a31bfde3}}}, +{{{0x3fdfa06c3fc66c0c, 0x5d40e38e4dd60dd2, 0x7ae38b38268e4d71, 0x3ac48d916e8357e1}}, + {{0x16561f696a0aa75c, 0xc1bf725c5852bd6a, 0x11a8dd7f9a7966ad, 0x63d988a2d2851026}}, + {{0x00120753afbd232e, 0xe92bceb8fdd8f683, 0xf81669b384e72b91, 0x33fad52b2368a066}}}, +{{{0x540649c6c5e41e16, 0x0af86430333f7735, 0xb2acfcd2f305e746, 0x16c0f429a256dca7}}, + {{0x8d2cc8d0c422cfe8, 0x072b4f7b05a13acb, 0xa3feb6e6ecf6a56f, 0x3cc355ccb90a71e2}}, + {{0xe9b69443903e9131, 0xb8a494cb7a5637ce, 0xc87cd1a4baba9244, 0x631eaf426bae7568}}}, +{{{0xb3e90410da66fe9f, 0x85dd4b526c16e5a6, 0xbc3d97611ef9bf83, 0x5599648b1ea919b5}}, + {{0x47d975b9a3700de8, 0x7280c5fbe2f80552, 0x53658f2732e45de1, 0x431f2c7f665f80b5}}, + {{0xd6026344858f7b19, 0x14ab352fa1ea514a, 0x8900441a2090a9d7, 0x7b04715f91253b26}}}, +{{{0x83edbd28acf6ae43, 0x86357c8b7d5c7ab4, 0xc0404769b7eb2c44, 0x59b37bf5c2f6583f}}, + {{0xb376c280c4e6bac6, 0x970ed3dd6d1d9b0b, 0xb09a9558450bf944, 0x48d0acfa57cde223}}, + {{0xb60f26e47dabe671, 0xf1d1a197622f3a37, 0x4208ce7ee9960394, 0x16234191336d3bdb}}}, +{{{0xb9e499def6267ff6, 0x7772ca7b742c0843, 0x23a0153fe9a4f2b1, 0x2cdfdfecd5d05006}}, + {{0xdd499cd61ff38640, 0x29cd9bc3063625a0, 0x51e2d8023dd73dc3, 0x4a25707a203b9231}}, + {{0x2ab7668a53f6ed6a, 0x304242581dd170a1, 0x4000144c3ae20161, 0x5721896d248e49fc}}}, +{{{0x0b6e5517fd181bae, 0x9022629f2bb963b4, 0x5509bce932064625, 0x578edd74f63c13da}}, + {{0x285d5091a1d0da4e, 0x4baa6fa7b5fe3e08, 0x63e5177ce19393b3, 0x03c935afc4b030fd}}, + {{0x997276c6492b0c3d, 0x47ccc2c4dfe205fc, 0xdcd29b84dd623a3c, 0x3ec2ab590288c7a2}}}, +{{{0xa1a0d27be4d87bb9, 0xa98b4deb61391aed, 0x99a0ddd073cb9b83, 0x2dd5c25a200fcace}}, + {{0xa7213a09ae32d1cb, 0x0f2b87df40f5c2d5, 0x0baea4c6e81eab29, 0x0e1bf66c6adbac5e}}, + {{0xe2abd5e9792c887e, 0x1a020018cb926d5d, 0xbfba69cdbaae5f1e, 0x730548b35ae88f5f}}}, +{{{0xc43551a3cba8b8ee, 0x65a26f1db2115f16, 0x760f4f52ab8c3850, 0x3043443b411db8ca}}, + {{0x805b094ba1d6e334, 0xbf3ef17709353f19, 0x423f06cb0622702b, 0x585a2277d87845dd}}, + {{0xa18a5f8233d48962, 0x6698c4b5ec78257f, 0xa78e6fa5373e41ff, 0x7656278950ef981f}}}, +{{{0x38c3cf59d51fc8c0, 0x9bedd2fd0506b6f2, 0x26bf109fab570e8f, 0x3f4160a8c1b846a6}}, + {{0xe17073a3ea86cf9d, 0x3a8cfbb707155fdc, 0x4853e7fc31838a8e, 0x28bbf484b613f616}}, + {{0xf2612f5c6f136c7c, 0xafead107f6dd11be, 0x527e9ad213de6f33, 0x1e79cb358188f75d}}}, +{{{0x013436c3eef7e3f1, 0x828b6a7ffe9e10f8, 0x7ff908e5bcf9defc, 0x65d7951b3a3b3831}}, + {{0x77e953d8f5e08181, 0x84a50c44299dded9, 0xdc6c2d0c864525e5, 0x478ab52d39d1f2f4}}, + {{0x66a6a4d39252d159, 0xe5dde1bc871ac807, 0xb82c6b40a6c1c96f, 0x16d87a411a212214}}}, +{{{0xb3bd7e5a42066215, 0x879be3cd0c5a24c1, 0x57c05db1d6f994b7, 0x28f87c8165f38ca6}}, + {{0xfba4d5e2d54e0583, 0xe21fafd72ebd99fa, 0x497ac2736ee9778f, 0x1f990b577a5a6dde}}, + {{0xa3344ead1be8f7d6, 0x7d1e50ebacea798f, 0x77c6569e520de052, 0x45882fe1534d6d3e}}}, +{{{0x6669345d757983d6, 0x62b6ed1117aa11a6, 0x7ddd1857985e128f, 0x688fe5b8f626f6dd}}, + {{0xd8ac9929943c6fe4, 0xb5f9f161a38392a2, 0x2699db13bec89af3, 0x7dcf843ce405f074}}, + {{0x6c90d6484a4732c0, 0xd52143fdca563299, 0xb3be28c3915dc6e1, 0x6739687e7327191b}}}, +{{{0xef782014385675a6, 0xa2649f30aafda9e8, 0x4cd1eb505cdfa8cb, 0x46115aba1d4dc0b3}}, + {{0xa66dcc9dc80c1ac0, 0x97a05cf41b38a436, 0xa7ebf3be95dbd7c6, 0x7da0b8f68d7e7dab}}, + {{0xd40f1953c3b5da76, 0x1dac6f7321119e9b, 0x03cc6021feb25960, 0x5a5f887e83674b4b}}}, +{{{0x8f6301cf70a13d11, 0xcfceb815350dd0c4, 0xf70297d4a4bca47e, 0x3669b656e44d1434}}, + {{0x9e9628d3a0a643b9, 0xb5c3cb00e6c32064, 0x9b5302897c2dec32, 0x43e37ae2d5d1c70c}}, + {{0x387e3f06eda6e133, 0x67301d5199a13ac0, 0xbd5ad8f836263811, 0x6a21e6cd4fd5e9be}}}, +{{{0xf1c6170a3046e65f, 0x58712a2a00d23524, 0x69dbbd3c8c82b755, 0x586bf9f1a195ff57}}, + {{0xef4129126699b2e3, 0x71d30847708d1301, 0x325432d01182b0bd, 0x45371b07001e8b36}}, + {{0xa6db088d5ef8790b, 0x5278f0dc610937e5, 0xac0349d261a16eb8, 0x0eafb03790e52179}}}, +{{{0x960555c13748042f, 0x219a41e6820baa11, 0x1c81f73873486d0c, 0x309acc675a02c661}}, + {{0x5140805e0f75ae1d, 0xec02fbe32662cc30, 0x2cebdf1eea92396d, 0x44ae3344c5435bb3}}, + {{0x9cf289b9bba543ee, 0xf3760e9d5ac97142, 0x1d82e5c64f9360aa, 0x62d5221b7f94678f}}}, +{{{0x524c299c18d0936d, 0xc86bb56c8a0c1a0c, 0xa375052edb4a8631, 0x5c0efde4bc754562}}, + {{0x7585d4263af77a3c, 0xdfae7b11fee9144d, 0xa506708059f7193d, 0x14f29a5383922037}}, + {{0xdf717edc25b2d7f5, 0x21f970db99b53040, 0xda9234b7c3ed4c62, 0x5e72365c7bee093e}}}, +{{{0x575bfc074571217f, 0x3779675d0694d95b, 0x9a0a37bbf4191e33, 0x77f1104c47b4eabc}}, + {{0x7d9339062f08b33e, 0x5b9659e5df9f32be, 0xacff3dad1f9ebdfd, 0x70b20555cb7349b7}}, + {{0xbe5113c555112c4c, 0x6688423a9a881fcd, 0x446677855e503b47, 0x0e34398f4a06404a}}}, +{{{0xb67d22d93ecebde8, 0x09b3e84127822f07, 0x743fa61fb05b6d8d, 0x5e5405368a362372}}, + {{0x18930b093e4b1928, 0x7de3e10e73f3f640, 0xf43217da73395d6f, 0x6f8aded6ca379c3e}}, + {{0xe340123dfdb7b29a, 0x487b97e1a21ab291, 0xf9967d02fde6949e, 0x780de72ec8d3de97}}}, +{{{0x0ae28545089ae7bc, 0x388ddecf1c7f4d06, 0x38ac15510a4811b8, 0x0eb28bf671928ce4}}, + {{0x671feaf300f42772, 0x8f72eb2a2a8c41aa, 0x29a17fd797373292, 0x1defc6ad32b587a6}}, + {{0xaf5bbe1aef5195a7, 0x148c1277917b15ed, 0x2991f7fb7ae5da2e, 0x467d201bf8dd2867}}}, +{{{0x95fe919a74ef4fad, 0x3a827becf6a308a2, 0x964e01d309a47b01, 0x71c43c4f5ba3c797}}, + {{0xbc1ef4bd567ae7a9, 0x3f624cb2d64498bd, 0xe41064d22c1f4ec8, 0x2ef9c5a5ba384001}}, + {{0xb6fd6df6fa9e74cd, 0xf18278bce4af267a, 0x8255b3d0f1ef990e, 0x5a758ca390c5f293}}}, +{{{0xa2b72710d9462495, 0x3aa8c6d2d57d5003, 0xe3d400bfa0b487ca, 0x2dbae244b3eb72ec}}, + {{0x8ce0918b1d61dc94, 0x8ded36469a813066, 0xd4e6a829afe8aad3, 0x0a738027f639d43f}}, + {{0x980f4a2f57ffe1cc, 0x00670d0de1839843, 0x105c3f4a49fb15fd, 0x2698ca635126a69c}}}, +{{{0xe765318832b0ba78, 0x381831f7925cff8b, 0x08a81b91a0291fcc, 0x1fb43dcc49caeb07}}, + {{0x2e3d702f5e3dd90e, 0x9e3f0918e4d25386, 0x5e773ef6024da96a, 0x3c004b0c4afa3332}}, + {{0x9aa946ac06f4b82b, 0x1ca284a5a806c4f3, 0x3ed3265fc6cd4787, 0x6b43fd01cd1fd217}}}, +{{{0xc7a75d4b4697c544, 0x15fdf848df0fffbf, 0x2868b9ebaa46785a, 0x5a68d7105b52f714}}, + {{0xb5c742583e760ef3, 0x75dc52b9ee0ab990, 0xbf1427c2072b923f, 0x73420b2d6ff0d9f0}}, + {{0xaf2cf6cb9e851e06, 0x8f593913c62238c4, 0xda8ab89699fbf373, 0x3db5632fea34bc9e}}}, +{{{0xf46eee2bf75dd9d8, 0x0d17b1f6396759a5, 0x1bf2d131499e7273, 0x04321adf49d75f13}}, + {{0x2e4990b1829825d5, 0xedeaeb873e9a8991, 0xeef03d394c704af8, 0x59197ea495df2b0e}}, + {{0x04e16019e4e55aae, 0xe77b437a7e2f92e9, 0xc7ce2dc16f159aa4, 0x45eafdc1f4d70cc0}}}, +{{{0x698401858045d72b, 0x4c22faa2cf2f0651, 0x941a36656b222dc6, 0x5a5eebc80362dade}}, + {{0xb60e4624cfccb1ed, 0x59dbc292bd5c0395, 0x31a09d1ddc0481c9, 0x3f73ceea5d56d940}}, + {{0xb7a7bfd10a4e8dc6, 0xbe57007e44c9b339, 0x60c1207f1557aefa, 0x26058891266218db}}}, +{{{0x59f704a68360ff04, 0xc3d93fde7661e6f4, 0x831b2a7312873551, 0x54ad0c2e4e615d57}}, + {{0x4c818e3cc676e542, 0x5e422c9303ceccad, 0xec07cccab4129f08, 0x0dedfa10b24443b8}}, + {{0xee3b67d5b82b522a, 0x36f163469fa5c1eb, 0xa5b4d2f26ec19fd3, 0x62ecb2baa77a9408}}}, +{{{0xe5ed795261152b3d, 0x4962357d0eddd7d1, 0x7482c8d0b96b4c71, 0x2e59f919a966d8be}}, + {{0x92072836afb62874, 0x5fcd5e8579e104a5, 0x5aad01adc630a14a, 0x61913d5075663f98}}, + {{0x0dc62d361a3231da, 0xfa47583294200270, 0x02d801513f9594ce, 0x3ddbc2a131c05d5c}}}, +{{{0x9adc0ff9ce5ec54b, 0x039c2a6b8c2f130d, 0x028007c7f0f89515, 0x78968314ac04b36b}}, + {{0xf3aa57a22796bb14, 0x883abab79b07da21, 0xe54be21831a0391c, 0x5ee7fb38d83205f9}}, + {{0x538dfdcb41446a8e, 0xa5acfda9434937f9, 0x46af908d263c8c78, 0x61d0633c9bca0d09}}}, +{{{0x63744935ffdb2566, 0xc5bd6b89780b68bb, 0x6f1b3280553eec03, 0x6e965fd847aed7f5}}, + {{0xada328bcf8fc73df, 0xee84695da6f037fc, 0x637fb4db38c2a909, 0x5b23ac2df8067bdc}}, + {{0x9ad2b953ee80527b, 0xe88f19aafade6d8d, 0x0e711704150e82cf, 0x79b9bbb9dd95dedc}}}, +{{{0xebb355406a3126c2, 0xd26383a868c8c393, 0x6c0c6429e5b97a82, 0x5065f158c9fd2147}}, + {{0xd1997dae8e9f7374, 0xa032a2f8cfbb0816, 0xcd6cba126d445f0a, 0x1ba811460accb834}}, + {{0x708169fb0c429954, 0xe14600acd76ecf67, 0x2eaab98a70e645ba, 0x3981f39e58a4faf2}}}, +{{{0x18fb8a7559230a93, 0x1d168f6960e6f45d, 0x3a85a94514a93cb5, 0x38dc083705acd0fd}}, + {{0xc845dfa56de66fde, 0xe152a5002c40483a, 0xe9d2e163c7b4f632, 0x30f4452edcbc1b65}}, + {{0x856d2782c5759740, 0xfa134569f99cbecc, 0x8844fc73c0ea4e71, 0x632d9a1a593f2469}}}, +{{{0xf6bb6b15b807cba6, 0x1823c7dfbc54f0d7, 0xbb1d97036e29670b, 0x0b24f48847ed4a57}}, + {{0xbf09fd11ed0c84a7, 0x63f071810d9f693a, 0x21908c2d57cf8779, 0x3a5a7df28af64ba2}}, + {{0xdcdad4be511beac7, 0xa4538075ed26ccf2, 0xe19cff9f005f9a65, 0x34fcf74475481f63}}}, +{{{0xc197e04c789767ca, 0xb8714dcb38d9467d, 0x55de888283f95fa8, 0x3d3bdc164dfa63f7}}, + {{0xa5bb1dab78cfaa98, 0x5ceda267190b72f2, 0x9309c9110a92608e, 0x0119a3042fb374b0}}, + {{0x67a2d89ce8c2177d, 0x669da5f66895d0c1, 0xf56598e5b282a2b0, 0x56c088f1ede20a73}}}, +{{{0x336d3d1110a86e17, 0xd7f388320b75b2fa, 0xf915337625072988, 0x09674c6b99108b87}}, + {{0x581b5fac24f38f02, 0xa90be9febae30cbd, 0x9a2169028acf92f0, 0x038b7ea48359038f}}, + {{0x9f4ef82199316ff8, 0x2f49d282eaa78d4f, 0x0971a5ab5aef3174, 0x6e5e31025969eb65}}}, +{{{0xb16c62f587e593fb, 0x4999eddeca5d3e71, 0xb491c1e014cc3e6d, 0x08f5114789a8dba8}}, + {{0x3304fb0e63066222, 0xfb35068987acba3f, 0xbd1924778c1061a3, 0x3058ad43d1838620}}, + {{0x323c0ffde57663d0, 0x05c3df38a22ea610, 0xbdc78abdac994f9a, 0x26549fa4efe3dc99}}}, +{{{0x741d5a461e6bf9d6, 0x2305b3fc7777a581, 0xd45574a26474d3d9, 0x1926e1dc6401e0ff}}, + {{0xdb468549af3f666e, 0xd77fcf04f14a0ea5, 0x3df23ff7a4ba0c47, 0x3a10dfe132ce3c85}}, + {{0xe07f4e8aea17cea0, 0x2fd515463a1fc1fd, 0x175322fd31f2c0f1, 0x1fa1d01d861e5d15}}}, +{{{0xcc8055947d599832, 0x1e4656da37f15520, 0x99f6f7744e059320, 0x773563bc6a75cf33}}, + {{0x38dcac00d1df94ab, 0x2e712bddd1080de9, 0x7f13e93efdd5e262, 0x73fced18ee9a01e5}}, + {{0x06b1e90863139cb3, 0xa493da67c5a03ecd, 0x8d77cec8ad638932, 0x1f426b701b864f44}}}, +{{{0xefc9264c41911c01, 0xf1a3b7b817a22c25, 0x5875da6bf30f1447, 0x4e1af5271d31b090}}, + {{0xf17e35c891a12552, 0xb76b8153575e9c76, 0xfa83406f0d9b723e, 0x0b76bb1b3fa7e438}}, + {{0x08b8c1f97f92939b, 0xbe6771cbd444ab6e, 0x22e5646399bb8017, 0x7b6dd61eb772a955}}}, +{{{0xb7adc1e850f33d92, 0x7998fa4f608cd5cf, 0xad962dbd8dfc5bdb, 0x703e9bceaf1d2f4f}}, + {{0x5730abf9ab01d2c7, 0x16fb76dc40143b18, 0x866cbe65a0cbb281, 0x53fa9b659bff6afe}}, + {{0x6c14c8e994885455, 0x843a5d6665aed4e5, 0x181bb73ebcd65af1, 0x398d93e5c4c61f50}}}, +{{{0x1c4bd16733e248f3, 0xbd9e128715bf0a5f, 0xd43f8cf0a10b0376, 0x53b09b5ddf191b13}}, + {{0xc3877c60d2e7e3f2, 0x3b34aaa030828bb1, 0x283e26e7739ef138, 0x699c9c9002c30577}}, + {{0xf306a7235946f1cc, 0x921718b5cce5d97d, 0x28cdd24781b4e975, 0x51caf30c6fcdd907}}}, +{{{0xa60ba7427674e00a, 0x630e8570a17a7bf3, 0x3758563dcf3324cc, 0x5504aa292383fdaa}}, + {{0x737af99a18ac54c7, 0x903378dcc51cb30f, 0x2b89bc334ce10cc7, 0x12ae29c189f8e99a}}, + {{0xa99ec0cb1f0d01cf, 0x0dd1efcc3a34f7ae, 0x55ca7521d09c4e22, 0x5fd14fe958eba5ea}}}, +{{{0xb5dc2ddf2845ab2c, 0x069491b10a7fe993, 0x4daaf3d64002e346, 0x093ff26e586474d1}}, + {{0x3c42fe5ebf93cb8e, 0xbedfa85136d4565f, 0xe0f0859e884220e8, 0x7dd73f960725d128}}, + {{0xb10d24fe68059829, 0x75730672dbaf23e5, 0x1367253ab457ac29, 0x2f59bcbc86b470a4}}}, +{{{0x83847d429917135f, 0xad1b911f567d03d7, 0x7e7748d9be77aad1, 0x5458b42e2e51af4a}}, + {{0x7041d560b691c301, 0x85201b3fadd7e71e, 0x16c2e16311335585, 0x2aa55e3d010828b1}}, + {{0xed5192e60c07444f, 0x42c54e2d74421d10, 0x352b4c82fdb5c864, 0x13e9004a8a768664}}}, +{{{0x739d8845832fcedb, 0xfa38d6c9ae6bf863, 0x32bc0dcab74ffef7, 0x73937e8814bce45e}}, + {{0xbb2e00c9193b877f, 0xece3a890e0dc506b, 0xecf3b7c036de649f, 0x5f46040898de9e1a}}, + {{0xb9037116297bf48d, 0xa9d13b22d4f06834, 0xe19715574696bdc6, 0x2cf8a4e891d5e835}}}, +{{{0x6d93fd8707110f67, 0xdd4c09d37c38b549, 0x7cb16a4cc2736a86, 0x2049bd6e58252a09}}, + {{0x2cb5487e17d06ba2, 0x24d2381c3950196b, 0xd7659c8185978a30, 0x7a6f7f2891d6a4f6}}, + {{0x7d09fd8d6a9aef49, 0xf0ee60be5b3db90b, 0x4c21b52c519ebfd4, 0x6011aadfc545941d}}}, +{{{0x5f67926dcf95f83c, 0x7c7e856171289071, 0xd6a1e7f3998f7a5b, 0x6fc5cc1b0b62f9e0}}, + {{0x63ded0c802cbf890, 0xfbd098ca0dff6aaa, 0x624d0afdb9b6ed99, 0x69ce18b779340b1e}}, + {{0xd1ef5528b29879cb, 0xdd1aae3cd47e9092, 0x127e0442189f2352, 0x15596b3ae57101f1}}}, +{{{0x462739d23f9179a2, 0xff83123197d6ddcf, 0x1307deb553f2148a, 0x0d2237687b5f4dda}}, + {{0x09ff31167e5124ca, 0x0be4158bd9c745df, 0x292b7d227ef556e5, 0x3aa4e241afb6d138}}, + {{0x2cc138bf2a3305f5, 0x48583f8fa2e926c3, 0x083ab1a25549d2eb, 0x32fcaa6e4687a36c}}}, +{{{0x7bc56e8dc57d9af5, 0x3e0bd2ed9df0bdf2, 0xaac014de22efe4a3, 0x4627e9cefebd6a5c}}, + {{0x3207a4732787ccdf, 0x17e31908f213e3f8, 0xd5b2ecd7f60d964e, 0x746f6336c2600be9}}, + {{0x3f4af345ab6c971c, 0xe288eb729943731f, 0x33596a8a0344186d, 0x7b4917007ed66293}}}, +{{{0x2d85fb5cab84b064, 0x497810d289f3bc14, 0x476adc447b15ce0c, 0x122ba376f844fd7b}}, + {{0x54341b28dd53a2dd, 0xaa17905bdf42fc3f, 0x0ff592d94dd2f8f4, 0x1d03620fe08cd37d}}, + {{0xc20232cda2b4e554, 0x9ed0fd42115d187f, 0x2eabb4be7dd479d9, 0x02c70bf52b68ec4c}}}, +{{{0xa287ec4b5d0b2fbb, 0x415c5790074882ca, 0xe044a61ec1d0815c, 0x26334f0a409ef5e0}}, + {{0xace532bf458d72e1, 0x5be768e07cb73cb5, 0x56cf7d94ee8bbde7, 0x6b0697e3feb43a03}}, + {{0xb6c8f04adf62a3c0, 0x3ef000ef076da45d, 0x9c9cb95849f0d2a9, 0x1cc37f43441b2fae}}}, +{{{0x508f565a5cc7324f, 0xd061c4c0e506a922, 0xfb18abdb5c45ac19, 0x6c6809c10380314a}}, + {{0xd76656f1c9ceaeb9, 0x1c5b15f818e5656a, 0x26e72832844c2334, 0x3a346f772f196838}}, + {{0xd2d55112e2da6ac8, 0xe9bd0331b1e851ed, 0x960746dd8ec67262, 0x05911b9f6ef7c5d0}}}, +{{{0xc1339983f5df0ebb, 0xc0f3758f512c4cac, 0x2cf1130a0bb398e1, 0x6b3cecf9aa270c62}}, + {{0x5349acf3512eeaef, 0x20c141d31cc1cb49, 0x24180c07a99a688d, 0x555ef9d1c64b2d17}}, + {{0x36a770ba3b73bd08, 0x624aef08a3afbf0c, 0x5737ff98b40946f2, 0x675f4de13381749d}}}, +{{{0x0e2c52036b1782fc, 0x64816c816cad83b4, 0xd0dcbdd96964073e, 0x13d99df70164c520}}, + {{0xa12ff6d93bdab31d, 0x0725d80f9d652dfe, 0x019c4ff39abe9487, 0x60f450b882cd3c43}}, + {{0x014b5ec321e5c0ca, 0x4fcb69c9d719bfa2, 0x4e5f1c18750023a0, 0x1c06de9e55edac80}}}, +{{{0x990f7ad6a33ec4e2, 0x6608f938be2ee08e, 0x9ca143c563284515, 0x4cf38a1fec2db60d}}, + {{0xffd52b40ff6d69aa, 0x34530b18dc4049bb, 0x5e4a5c2fa34d9897, 0x78096f8e7d32ba2d}}, + {{0xa0aaaa650dfa5ce7, 0xf9c49e2a48b5478c, 0x4f09cc7d7003725b, 0x373cad3a26091abe}}}, +{{{0xb294634d82c9f57c, 0x1fcbfde124934536, 0x9e9c4db3418cdb5a, 0x0040f3d9454419fc}}, + {{0xf1bea8fb89ddbbad, 0x3bcb2cbc61aeaecb, 0x8f58a7bb1f9b8d9d, 0x21547eda5112a686}}, + {{0xdefde939fd5986d3, 0xf4272c89510a380c, 0xb72ba407bb3119b9, 0x63550a334a254df4}}}, +{{{0x6507d6edb569cf37, 0x178429b00ca52ee1, 0xea7c0090eb6bd65d, 0x3eea62c7daf78f51}}, + {{0x9bba584572547b49, 0xf305c6fae2c408e0, 0x60e8fa69c734f18d, 0x39a92bafaa7d767a}}, + {{0x9d24c713e693274e, 0x5f63857768dbd375, 0x70525560eb8ab39a, 0x68436a0665c9c4cd}}}, +{{{0xbc0235e8202f3f27, 0xc75c00e264f975b0, 0x91a4e9d5a38c2416, 0x17b6e7f68ab789f9}}, + {{0x1e56d317e820107c, 0xc5266844840ae965, 0xc1e0a1c6320ffc7a, 0x5373669c91611472}}, + {{0x5d2814ab9a0e5257, 0x908f2084c9cab3fc, 0xafcaf5885b2d1eca, 0x1cb4b5a678f87d11}}}, +{{{0xb664c06b394afc6c, 0x0c88de2498da5fb1, 0x4f8d03164bcad834, 0x330bca78de7434a2}}, + {{0x6b74aa62a2a007e7, 0xf311e0b0f071c7b1, 0x5707e438000be223, 0x2dc0fd2d82ef6eac}}, + {{0x982eff841119744e, 0xf9695e962b074724, 0xc58ac14fbfc953fb, 0x3c31be1b369f1cf5}}}, +{{{0xb0f4864d08948aee, 0x07dc19ee91ba1c6f, 0x7975cdaea6aca158, 0x330b61134262d4bb}}, + {{0xc168bc93f9cb4272, 0xaeb8711fc7cedb98, 0x7f0e52aa34ac8d7a, 0x41cec1097e7d55bb}}, + {{0xf79619d7a26d808a, 0xbb1fd49e1d9e156d, 0x73d7c36cdba1df27, 0x26b44cd91f28777d}}}, +{{{0x51f048478f387475, 0xb25dbcf49cbecb3c, 0x9aab1244d99f2055, 0x2c709e6c1c10a5d6}}, + {{0xe1b7f29362730383, 0x4b5279ffebca8a2c, 0xdafc778abfd41314, 0x7deb10149c72610f}}, + {{0xcb62af6a8766ee7a, 0x66cbec045553cd0e, 0x588001380f0be4b5, 0x08e68e9ff62ce2ea}}}, +{{{0x34ad500a4bc130ad, 0x8d38db493d0bd49c, 0xa25c3d98500a89be, 0x2f1f3f87eeba3b09}}, + {{0x2f2d09d50ab8f2f9, 0xacb9218dc55923df, 0x4a8f342673766cb9, 0x4cb13bd738f719f5}}, + {{0xf7848c75e515b64a, 0xa59501badb4a9038, 0xc20d313f3f751b50, 0x19a1e353c0ae2ee8}}}, +{{{0x7d1c7560bafa05c3, 0xb3e1a0a0c6e55e61, 0xe3529718c0d66473, 0x41546b11c20c3486}}, + {{0xb42172cdd596bdbd, 0x93e0454398eefc40, 0x9fb15347b44109b5, 0x736bd3990266ae34}}, + {{0x85532d509334b3b4, 0x46fd114b60816573, 0xcc5f5f30425c8375, 0x412295a2b87fab5c}}}, +{{{0x19c99b88f57ed6e9, 0x5393cb266df8c825, 0x5cee3213b30ad273, 0x14e153ebb52d2e34}}, + {{0x2e655261e293eac6, 0x845a92032133acdb, 0x460975cb7900996b, 0x0760bb8d195add80}}, + {{0x413e1a17cde6818a, 0x57156da9ed69a084, 0x2cbf268f46caccb1, 0x6b34be9bc33ac5f2}}}, +{{{0xf3df2f643a78c0b2, 0x4c3e971ef22e027c, 0xec7d1c5e49c1b5a3, 0x2012c18f0922dd2d}}, + {{0x11fc69656571f2d3, 0xc6c9e845530e737a, 0xe33ae7a2d4fe5035, 0x01b9c7b62e6dd30b}}, + {{0x880b55e55ac89d29, 0x1483241f45a0a763, 0x3d36efdfc2e76c1f, 0x08af5b784e4bade8}}}, +{{{0x283499dc881f2533, 0x9d0525da779323b6, 0x897addfb673441f4, 0x32b79d71163a168d}}, + {{0xe27314d289cc2c4b, 0x4be4bd11a287178d, 0x18d528d6fa3364ce, 0x6423c1d5afd9826e}}, + {{0xcc85f8d9edfcb36a, 0x22bcc28f3746e5f9, 0xe49de338f9e5d3cd, 0x480a5efbc13e2dcc}}}, +{{{0x0b51e70b01622071, 0x06b505cf8b1dafc5, 0x2c6bb061ef5aabcd, 0x47aa27600cb7bf31}}, + {{0xb6614ce442ce221f, 0x6e199dcc4c053928, 0x663fb4a4dc1cbe03, 0x24b31d47691c8e06}}, + {{0x2a541eedc015f8c3, 0x11a4fe7e7c693f7c, 0xf0af66134ea278d6, 0x545b585d14dda094}}}, +{{{0x67bf275ea0d43a0f, 0xade68e34089beebe, 0x4289134cd479e72e, 0x0f62f9c332ba5454}}, + {{0x6204e4d0e3b321e1, 0x3baa637a28ff1e95, 0x0b0ccffd5b99bd9e, 0x4d22dc3e64c8d071}}, + {{0xfcb46589d63b5f39, 0x5cae6a3f57cbcf61, 0xfebac2d2953afa05, 0x1c0fa01a36371436}}}, +{{{0xd2c604b622943dff, 0xbc8cbece44cfb3a0, 0x5d254ff397808678, 0x0fa3614f3b1ca6bf}}, + {{0x69082b0e8c936a50, 0xf9c9a035c1dac5b6, 0x6fb73e54c4dfb634, 0x4005419b1d2bc140}}, + {{0xa003febdb9be82f0, 0x2089c1af3a44ac90, 0xf8499f911954fa8e, 0x1fba218aef40ab42}}}, +{{{0xab549448fac8f53e, 0x81f6e89a7ba63741, 0x74fd6c7d6c2b5e01, 0x392e3acaa8c86e42}}, + {{0x4f3e57043e7b0194, 0xa81d3eee08daaf7f, 0xc839c6ab99dcdef1, 0x6c535d13ff7761d5}}, + {{0x4cbd34e93e8a35af, 0x2e0781445887e816, 0x19319c76f29ab0ab, 0x25e17fe4d50ac13b}}}, +{{{0x0a289bd71e04f676, 0x208e1c52d6420f95, 0x5186d8b034691fab, 0x255751442a9fb351}}, + {{0x915f7ff576f121a7, 0xc34a32272fcd87e3, 0xccba2fde4d1be526, 0x6bba828f8969899b}}, + {{0xe2d1bc6690fe3901, 0x4cb54a18a0997ad5, 0x971d6914af8460d4, 0x559d504f7f6b7be4}}}, +{{{0xa7738378b3eb54d5, 0x1d69d366a5553c7c, 0x0a26cf62f92800ba, 0x01ab12d5807e3217}}, + {{0x9c4891e7f6d266fd, 0x0744a19b0307781b, 0x88388f1d6061e23b, 0x123ea6a3354bd50e}}, + {{0x118d189041e32d96, 0xb9ede3c2d8315848, 0x1eab4271d83245d9, 0x4a3961e2c918a154}}}, +{{{0x71dc3be0f8e6bba0, 0xd6cef8347effe30a, 0xa992425fe13a476a, 0x2cd6bce3fb1db763}}, + {{0x0327d644f3233f1e, 0x499a260e34fcf016, 0x83b5a716f2dab979, 0x68aceead9bd4111f}}, + {{0x38b4c90ef3d7c210, 0x308e6e24b7ad040c, 0x3860d9f1b7e73e23, 0x595760d5b508f597}}}, +{{{0x6129bfe104aa6397, 0x8f960008a4a7fccb, 0x3f8bc0897d909458, 0x709fa43edcb291a9}}, + {{0x882acbebfd022790, 0x89af3305c4115760, 0x65f492e37d3473f4, 0x2cb2c5df54515a2b}}, + {{0xeb0a5d8c63fd2aca, 0xd22bc1662e694eff, 0x2723f36ef8cbb03a, 0x70f029ecf0c8131f}}}, +{{{0x461307b32eed3e33, 0xae042f33a45581e7, 0xc94449d3195f0366, 0x0b7d5d8a6c314858}}, + {{0x2a6aafaa5e10b0b9, 0x78f0a370ef041aa9, 0x773efb77aa3ad61f, 0x44eca5a2a74bd9e1}}, + {{0x25d448327b95d543, 0x70d38300a3340f1d, 0xde1c531c60e1c52b, 0x272224512c7de9e4}}}, +{{{0x1abc92af49c5342e, 0xffeed811b2e6fad0, 0xefa28c8dfcc84e29, 0x11b5df18a44cc543}}, + {{0xbf7bbb8a42a975fc, 0x8c5c397796ada358, 0xe27fc76fcdedaa48, 0x19735fd7f6bc20a6}}, + {{0xe3ab90d042c84266, 0xeb848e0f7f19547e, 0x2503a1d065a497b9, 0x0fef911191df895f}}} \ No newline at end of file diff --git a/ext/ed25519-amd64-asm/ge25519_base_slide_multiples.data b/ext/ed25519-amd64-asm/ge25519_base_slide_multiples.data new file mode 100644 index 0000000..32a5d47 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_base_slide_multiples.data @@ -0,0 +1,96 @@ +{{{0x9d103905d740913e, 0xfd399f05d140beb3, 0xa5c18434688f8a09, 0x44fd2f9298f81267}}, + {{0x2fbc93c6f58c3b85, 0xcf932dc6fb8c0e19, 0x270b4898643d42c2, 0x07cf9d3a33d4ba65}}, + {{0xabc91205877aaa68, 0x26d9e823ccaac49e, 0x5a1b7dcbdd43598c, 0x6f117b689f0c65a8}}}, +{{{0x56611fe8a4fcd265, 0x3bd353fde5c1ba7d, 0x8131f31a214bd6bd, 0x2ab91587555bda62}}, + {{0xaf25b0a84cee9730, 0x025a8430e8864b8a, 0xc11b50029f016732, 0x7a164e1b9a80f8f4}}, + {{0x14ae933f0dd0d889, 0x589423221c35da62, 0xd170e5458cf2db4c, 0x5a2826af12b9b4c6}}}, +{{{0x7f9182c3a447d6ba, 0xd50014d14b2729b7, 0xe33cf11cb864a087, 0x154a7e73eb1b55f3}}, + {{0xa212bc4408a5bb33, 0x8d5048c3c75eed02, 0xdd1beb0c5abfec44, 0x2945ccf146e206eb}}, + {{0xbcbbdbf1812a8285, 0x270e0807d0bdd1fc, 0xb41b670b1bbda72d, 0x43aabe696b3bb69a}}}, +{{{0xba6f2c9aaa3221b1, 0x6ca021533bba23a7, 0x9dea764f92192c3a, 0x1d6edd5d2e5317e0}}, + {{0x6b1a5cd0944ea3bf, 0x7470353ab39dc0d2, 0x71b2528228542e49, 0x461bea69283c927e}}, + {{0xf1836dc801b8b3a2, 0xb3035f47053ea49a, 0x529c41ba5877adf3, 0x7a9fbb1c6a0f90a7}}}, +{{{0xf36e217e039d8064, 0x98a081b6f520419b, 0x96cbc608e75eb044, 0x49c05a51fadc9c8f}}, + {{0x9b2e678aa6a8632f, 0xa6509e6f51bc46c5, 0xceb233c9c686f5b5, 0x34b9ed338add7f59}}, + {{0x06b4e8bf9045af1b, 0xe2ff83e8a719d22f, 0xaaf6fc2993d4cf16, 0x73c172021b008b06}}}, +{{{0x315f5b0249864348, 0x3ed6b36977088381, 0xa3a075556a8deb95, 0x18ab598029d5c77f}}, + {{0x2fbf00848a802ade, 0xe5d9fecf02302e27, 0x113e847117703406, 0x4275aae2546d8faf}}, + {{0xd82b2cc5fd6089e9, 0x031eb4a13282e4a4, 0x44311199b51a8622, 0x3dc65522b53df948}}}, +{{{0x506f013b327fbf93, 0xaefcebc99b776f6b, 0x9d12b232aaad5968, 0x0267882d176024a7}}, + {{0xbf70c222a2007f6d, 0xbf84b39ab5bcdedb, 0x537a0e12fb07ba07, 0x234fd7eec346f241}}, + {{0x5360a119732ea378, 0x2437e6b1df8dd471, 0xa2ef37f891a7e533, 0x497ba6fdaa097863}}}, +{{{0x040bcd86468ccf0b, 0xd3829ba42a9910d6, 0x7508300807b25192, 0x43b5cd4218d05ebf}}, + {{0x24cecc0313cfeaa0, 0x8648c28d189c246d, 0x2dbdbdfac1f2d4d0, 0x61e22917f12de72b}}, + {{0x5d9a762f9bd0b516, 0xeb38af4e373fdeee, 0x032e5a7d93d64270, 0x511d61210ae4d842}}}, +{{{0x081386484420de87, 0x8a1cf016b592edb4, 0x39fa4e2729942d25, 0x71a7fe6fe2482810}}, + {{0x92c676ef950e9d81, 0xa54620cdc0d7044f, 0xaa9b36646f8f1248, 0x6d325924ddb855e3}}, + {{0x6c7182b8a5c8c854, 0x33fd1479fe5f2a03, 0x72cf591883778d0c, 0x4746c4b6559eeaa9}}}, +{{{0x348546c864741147, 0x7d35aedd0efcc849, 0xff939a760672a332, 0x219663497db5e6d6}}, + {{0xd3777b3c6dc69a2b, 0xdefab2276f89f617, 0x45651cf7b53a16b5, 0x5c9a51de34fe9fb7}}, + {{0xf510f1cf79f10e67, 0xffdddaa1e658515b, 0x09c3a71710142277, 0x4804503c608223bb}}}, +{{{0x3b6821d23a36d175, 0xbbb40aa7e99b9e32, 0x5d9e5ce420838a47, 0x771e098858de4c5e}}, + {{0xc4249ed02ca37fc7, 0xa059a0e3a615acab, 0x88a96ed7c96e0e23, 0x553398a51650696d}}, + {{0x9a12f5d278451edf, 0x3ada5d7985899ccb, 0x477f4a2d9fa59508, 0x5a5ed1d68ff5a611}}}, +{{{0xbae5e0c558527359, 0x392e5c19cadb9d7e, 0x28653c1eda1cabe9, 0x019b60135fefdc44}}, + {{0x1195122afe150e83, 0xcf209a257e4b35d8, 0x7387f8291e711e20, 0x44acb897d8bf92f0}}, + {{0x1e6068145e134b83, 0xc4f5e64f24304c16, 0x506e88a8fc1a3ed7, 0x150c49fde6ad2f92}}}, +{{{0xb849863c9cdca868, 0xc83f44dbb8714ad0, 0xfe3ee3560c36168d, 0x78a6d7791e05fbc1}}, + {{0x8e7bf29509471138, 0x5d6fef394f75a651, 0x10af79c425a708ad, 0x6b2b5a075bb99922}}, + {{0x58bf704b47a0b976, 0xa601b355741748d5, 0xaa2b1fb1d542f590, 0x725c7ffc4ad55d00}}}, +{{{0x91802bf71cd098c0, 0xfe416ca4ed5e6366, 0xdf585d714902994c, 0x4cd54625f855fae7}}, + {{0xe4426715d1cf99b2, 0x7352d51102a20d34, 0x23d1157b8b12109f, 0x794cc9277cb1f3a3}}, + {{0x4af6c426c2ac5053, 0xbc9aedad32f67258, 0x2ad032f10a311021, 0x7008357b6fcc8e85}}}, +{{{0xd01b9fbb82584a34, 0x47ab6463d2b4792b, 0xb631639c48536202, 0x13a92a3669d6d428}}, + {{0x0b88672738773f01, 0xb8ccc8fa95fbccfb, 0x8d2dd5a3b9ad29b6, 0x06ef7e9851ad0f6a}}, + {{0xca93771cc0577de5, 0x7540e41e5035dc5c, 0x24680f01d802e071, 0x3c296ddf8a2af86a}}}, +{{{0xfceb4d2ebb1f2541, 0xb89510c740adb91f, 0xfc71a37dd0a1ad05, 0x0a892c700747717b}}, + {{0xaead15f9d914a713, 0xa92f7bf98c8ff912, 0xaff823179f53d730, 0x7a99d393490c77ba}}, + {{0x8f52ed2436bda3e8, 0x77a8c84157e80794, 0xa5a96563262f9ce0, 0x286762d28302f7d2}}}, +{{{0x7c558e2bce2ef5bd, 0xe4986cb46747bc63, 0x154a179f3bbb89b8, 0x7686f2a3d6f1767a}}, + {{0x4e7836093ce35b25, 0x82e1181db26baa97, 0x0cc192d3cbc7b83f, 0x32f1da046a9d9d3a}}, + {{0xaa8d12a66d597c6a, 0x8f11930304d3852b, 0x3f91dc73c209b022, 0x561305f8a9ad28a6}}}, +{{{0x6722cc28e7b0c0d5, 0x709de9bbdb075c53, 0xcaf68da7d7010a61, 0x030a1aef2c57cc6c}}, + {{0x100c978dec92aed1, 0xca43d5434d6d73e5, 0x83131b22d847ba48, 0x00aaec53e35d4d2c}}, + {{0x7bb1f773003ad2aa, 0x0b3f29802b216608, 0x7821dc86520ed23e, 0x20be9c1c24065480}}}, +{{{0x20e0e44ae2025e60, 0xb03b3b2fcbdcb938, 0x105d639cf95a0d1c, 0x69764c545067e311}}, + {{0xe15387d8249673a6, 0x5943bc2df546e493, 0x1c7f9a81c36f63b5, 0x750ab3361f0ac1de}}, + {{0x1e8a3283a2f81037, 0x6f2eda23bd7fcbf1, 0xb72fd15bac2e2563, 0x54f96b3fb7075040}}}, +{{{0x177dafc616b11ecd, 0x89764b9cfa576479, 0xb7a8a110e6ece785, 0x78e6839fbe85dbf0}}, + {{0x0fadf20429669279, 0x3adda2047d7d724a, 0x6f3d94828c5760f1, 0x3d7fe9c52bb7539e}}, + {{0x70332df737b8856b, 0x75d05d43041a178a, 0x320ff74aa0e59e22, 0x70f268f350088242}}}, +{{{0x2324112070dcf355, 0x380cc97ee7fce117, 0xb31ddeed3552b698, 0x404e56c039b8c4b9}}, + {{0x66864583b1805f47, 0xf535c5d160dd7c19, 0xe9874eb71e4cb006, 0x7c0d345cfad889d9}}, + {{0x591f1f4b8c78338a, 0xa0366ab167e0b5e1, 0x5cbc4152b45f3d44, 0x20d754762aaec777}}}, +{{{0x9d74feb135b9f543, 0x84b37df1de8c956c, 0xe9322b0757138ba9, 0x38b8ada8790b4ce1}}, + {{0x5e8fc36fc73bb758, 0xace543a5363cbb9a, 0xa9934a7d903bc922, 0x2b8f1e46f3ceec62}}, + {{0xb5c04a9cdf51f95d, 0x2b3952aecb1fdeac, 0x1d106d8b328b66da, 0x049aeb32ceba1953}}}, +{{{0xd7767d3c63dcfe7e, 0x209c594897856e40, 0xb6676861e14f7c13, 0x51c665e0c8d625fc}}, + {{0xaa507d0b75fc7931, 0x0fef924b7a6725d3, 0x1d82542b396b3930, 0x795ee17530f674fc}}, + {{0x254a5b0a52ecbd81, 0x5d411f6ee034afe7, 0xe6a24d0dcaee4a31, 0x6cd19bf49dc54477}}}, +{{{0x7e87619052179ca3, 0x571d0a060b2c9f85, 0x80a2baa88499711e, 0x7520f3db40b2e638}}, + {{0x1ffe612165afc386, 0x082a2a88b8d51b10, 0x76f6627e20990baa, 0x5e01b3a7429e43e7}}, + {{0x3db50be3d39357a1, 0x967b6cdd599e94a5, 0x1a309a64df311e6e, 0x71092c9ccef3c986}}}, +{{{0x53d8523f0364918c, 0xa2b404f43fab6b1c, 0x080b4a9e6681e5a4, 0x0ea15b03d0257ba7}}, + {{0x856bd8ac74051dcf, 0x03f6a40855b7aa1e, 0x3a4ae7cbc9743ceb, 0x4173a5bb7137abde}}, + {{0x17c56e31f0f9218a, 0x5a696e2b1afc4708, 0xf7931668f4b2f176, 0x5fc565614a4e3a67}}}, +{{{0x136e570dc46d7ae5, 0x0fd0aacc54f8dc8f, 0x59549f03310dad86, 0x62711c414c454aa1}}, + {{0x4892e1e67790988e, 0x01d5950f1c5cd722, 0xe3b0819ae5923eed, 0x3214c7409d46651b}}, + {{0x1329827406651770, 0x3ba4a0668a279436, 0xd9b6b8ec185d223c, 0x5bea94073ecb833c}}}, +{{{0x641dbf0912c89be4, 0xacf38b317d6e579c, 0xabfe9e02f697b065, 0x3aacd5c148f61eec}}, + {{0xb470ce63f343d2f8, 0x0067ba8f0543e8f1, 0x35da51a1a2117b6f, 0x4ad0785944f1bd2f}}, + {{0x858e3b34c3318301, 0xdc99c04707316826, 0x34085b2ed39da88c, 0x3aff0cb1d902853d}}}, +{{{0x87c5c7eb3a20405e, 0x8ee311efedad56c9, 0x29252e48ad29d5f9, 0x110e7e86f4cd251d}}, + {{0x9226430bf4c53505, 0x68e49c13261f2283, 0x09ef33788fd327c6, 0x2ccf9f732bd99e7f}}, + {{0x57c0d89ed603f5e4, 0x12888628f0b0200c, 0x53172709a02e3bb7, 0x05c557e0b9693a37}}}, +{{{0xd8f9ce311fc97e6f, 0x7a3f263011f9fdae, 0xe15b7ea08bed25dd, 0x6e154c178fe9875a}}, + {{0xf776bbb089c20eb0, 0x61f85bf6fa0fd85c, 0xb6b93f4e634421fb, 0x289fef0841861205}}, + {{0xcf616336fed69abf, 0x9b16e4e78335c94f, 0x13789765753a7fe7, 0x6afbf642a95ca319}}}, +{{{0x7da8de0c62f5d2c1, 0x98fc3da4b00e7b9a, 0x7deb6ada0dad70e0, 0x0db4b851b95038c4}}, + {{0x5de55070f913a8cc, 0x7d1d167b2b0cf561, 0xda2956b690ead489, 0x12c093cedb801ed9}}, + {{0xfc147f9308b8190f, 0x06969da0a11ae310, 0xcee75572dac7d7fd, 0x33aa8799c6635ce6}}}, +{{{0xaf0ff51ebd085cf2, 0x78f51a8967d33f1f, 0x6ec2bfe15060033c, 0x233c6f29e8e21a86}}, + {{0x8348f588fc156cb1, 0x6da2ba9b1a0a6d27, 0xe2262d5c87ca5ab6, 0x212cd0c1c8d589a6}}, + {{0xd2f4d5107f18c781, 0x122ecdf2527e9d28, 0xa70a862a3d3d3341, 0x1db7778911914ce3}}}, +{{{0xddf352397c6bc26f, 0x7a97e2cc53d50113, 0x7c74f43abf79a330, 0x31ad97ad26e2adfc}}, + {{0xb3394769dd701ab6, 0xe2b8ded419cf8da5, 0x15df4161fd2ac852, 0x7ae2ca8a017d24be}}, + {{0xb7e817ed0920b962, 0x1e8518cc3f19da9d, 0xe491c14f25560a64, 0x1ed1fc53a6622c83}}} \ No newline at end of file diff --git a/ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s b/ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s new file mode 100644 index 0000000..265daf0 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s @@ -0,0 +1,2975 @@ + +# qhasm: int64 rp + +# qhasm: int64 pp + +# qhasm: input rp + +# qhasm: input pp + +# qhasm: int64 a0 + +# qhasm: int64 a1 + +# qhasm: int64 a2 + +# qhasm: int64 a3 + +# qhasm: stack64 a0_stack + +# qhasm: stack64 a1_stack + +# qhasm: stack64 a2_stack + +# qhasm: stack64 a3_stack + +# qhasm: int64 b0 + +# qhasm: int64 b1 + +# qhasm: int64 b2 + +# qhasm: int64 b3 + +# qhasm: stack64 b0_stack + +# qhasm: stack64 b1_stack + +# qhasm: stack64 b2_stack + +# qhasm: stack64 b3_stack + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: stack64 c0_stack + +# qhasm: stack64 c1_stack + +# qhasm: stack64 c2_stack + +# qhasm: stack64 c3_stack + +# qhasm: int64 d0 + +# qhasm: int64 d1 + +# qhasm: int64 d2 + +# qhasm: int64 d3 + +# qhasm: stack64 d0_stack + +# qhasm: stack64 d1_stack + +# qhasm: stack64 d2_stack + +# qhasm: stack64 d3_stack + +# qhasm: int64 e0 + +# qhasm: int64 e1 + +# qhasm: int64 e2 + +# qhasm: int64 e3 + +# qhasm: stack64 e0_stack + +# qhasm: stack64 e1_stack + +# qhasm: stack64 e2_stack + +# qhasm: stack64 e3_stack + +# qhasm: int64 rx0 + +# qhasm: int64 rx1 + +# qhasm: int64 rx2 + +# qhasm: int64 rx3 + +# qhasm: stack64 rx0_stack + +# qhasm: stack64 rx1_stack + +# qhasm: stack64 rx2_stack + +# qhasm: stack64 rx3_stack + +# qhasm: int64 ry0 + +# qhasm: int64 ry1 + +# qhasm: int64 ry2 + +# qhasm: int64 ry3 + +# qhasm: int64 ry4 + +# qhasm: int64 rz0 + +# qhasm: int64 rz1 + +# qhasm: int64 rz2 + +# qhasm: int64 rz3 + +# qhasm: int64 rt0 + +# qhasm: int64 rt1 + +# qhasm: int64 rt2 + +# qhasm: int64 rt3 + +# qhasm: int64 mulr4 + +# qhasm: int64 mulr5 + +# qhasm: int64 mulr6 + +# qhasm: int64 mulr7 + +# qhasm: int64 mulr8 + +# qhasm: int64 mulrax + +# qhasm: int64 mulrdx + +# qhasm: int64 mulx0 + +# qhasm: int64 mulx1 + +# qhasm: int64 mulx2 + +# qhasm: int64 mulx3 + +# qhasm: int64 mulc + +# qhasm: int64 mulzero + +# qhasm: int64 muli38 + +# qhasm: int64 squarer4 + +# qhasm: int64 squarer5 + +# qhasm: int64 squarer6 + +# qhasm: int64 squarer7 + +# qhasm: int64 squarer8 + +# qhasm: int64 squarerax + +# qhasm: int64 squarerdx + +# qhasm: int64 squaret1 + +# qhasm: int64 squaret2 + +# qhasm: int64 squaret3 + +# qhasm: int64 squarec + +# qhasm: int64 squarezero + +# qhasm: int64 squarei38 + +# qhasm: int64 addt0 + +# qhasm: int64 addt1 + +# qhasm: int64 subt0 + +# qhasm: int64 subt1 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1 +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1 +.globl crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1 +_crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1: +crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1: +mov %rsp,%r11 +and $31,%r11 +add $192,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#4 +# asm 2: mov $0,>squarer7=%rcx +mov $0,%rcx + +# qhasm: squarerax = *(uint64 *)(pp + 8) +# asm 1: movq 8(squarerax=int64#7 +# asm 2: movq 8(squarerax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 0) +# asm 1: mulq 0(a1=int64#5 +# asm 2: mov a1=%r8 +mov %rax,%r8 + +# qhasm: a2 = squarerdx +# asm 1: mov a2=int64#6 +# asm 2: mov a2=%r9 +mov %rdx,%r9 + +# qhasm: squarerax = *(uint64 *)(pp + 16) +# asm 1: movq 16(squarerax=int64#7 +# asm 2: movq 16(squarerax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 8) +# asm 1: mulq 8(a3=int64#8 +# asm 2: mov a3=%r10 +mov %rax,%r10 + +# qhasm: squarer4 = squarerdx +# asm 1: mov squarer4=int64#9 +# asm 2: mov squarer4=%r11 +mov %rdx,%r11 + +# qhasm: squarerax = *(uint64 *)(pp + 24) +# asm 1: movq 24(squarerax=int64#7 +# asm 2: movq 24(squarerax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 16) +# asm 1: mulq 16(squarer5=int64#10 +# asm 2: mov squarer5=%r12 +mov %rax,%r12 + +# qhasm: squarer6 = squarerdx +# asm 1: mov squarer6=int64#11 +# asm 2: mov squarer6=%r13 +mov %rdx,%r13 + +# qhasm: squarerax = *(uint64 *)(pp + 16) +# asm 1: movq 16(squarerax=int64#7 +# asm 2: movq 16(squarerax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 0) +# asm 1: mulq 0(squarerax=int64#7 +# asm 2: movq 24(squarerax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 8) +# asm 1: mulq 8(squarerax=int64#7 +# asm 2: movq 24(squarerax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 0) +# asm 1: mulq 0(squarerax=int64#7 +# asm 2: movq 0(squarerax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 0) +# asm 1: mulq 0(a0=int64#12 +# asm 2: mov a0=%r14 +mov %rax,%r14 + +# qhasm: squaret1 = squarerdx +# asm 1: mov squaret1=int64#13 +# asm 2: mov squaret1=%r15 +mov %rdx,%r15 + +# qhasm: squarerax = *(uint64 *)(pp + 8) +# asm 1: movq 8(squarerax=int64#7 +# asm 2: movq 8(squarerax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 8) +# asm 1: mulq 8(squaret2=int64#14 +# asm 2: mov squaret2=%rbx +mov %rax,%rbx + +# qhasm: squaret3 = squarerdx +# asm 1: mov squaret3=int64#15 +# asm 2: mov squaret3=%rbp +mov %rdx,%rbp + +# qhasm: squarerax = *(uint64 *)(pp + 16) +# asm 1: movq 16(squarerax=int64#7 +# asm 2: movq 16(squarerax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 16) +# asm 1: mulq 16(squarerax=int64#7 +# asm 2: movq 24(squarerax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 24) +# asm 1: mulq 24(squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r11,%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: squarer4 = squarerax +# asm 1: mov squarer4=int64#9 +# asm 2: mov squarer4=%r11 +mov %rax,%r11 + +# qhasm: squarerax = squarer5 +# asm 1: mov squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r12,%rax + +# qhasm: squarer5 = squarerdx +# asm 1: mov squarer5=int64#10 +# asm 2: mov squarer5=%r12 +mov %rdx,%r12 + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? squarer5 += squarerax +# asm 1: add squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r13,%rax + +# qhasm: squarer6 = 0 +# asm 1: mov $0,>squarer6=int64#11 +# asm 2: mov $0,>squarer6=%r13 +mov $0,%r13 + +# qhasm: squarer6 += squarerdx + carry +# asm 1: adc squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %rcx,%rax + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#4 +# asm 2: mov $0,>squarer7=%rcx +mov $0,%rcx + +# qhasm: squarer7 += squarerdx + carry +# asm 1: adc squarer8=int64#7 +# asm 2: mov $0,>squarer8=%rax +mov $0,%rax + +# qhasm: squarer8 += squarerdx + carry +# asm 1: adc squarezero=int64#3 +# asm 2: mov $0,>squarezero=%rdx +mov $0,%rdx + +# qhasm: squarer8 += squarezero + carry +# asm 1: adc squarer8=int64#4 +# asm 2: imulq $38,squarer8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? a0 += squarer8 +# asm 1: add squarezero=int64#3 +# asm 2: imulq $38,squarezero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: a0 += squarezero +# asm 1: add a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %r14,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %r8,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r9,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %r10,80(%rsp) + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#4 +# asm 2: mov $0,>squarer7=%rcx +mov $0,%rcx + +# qhasm: squarerax = *(uint64 *)(pp + 40) +# asm 1: movq 40(squarerax=int64#7 +# asm 2: movq 40(squarerax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 32) +# asm 1: mulq 32(b1=int64#5 +# asm 2: mov b1=%r8 +mov %rax,%r8 + +# qhasm: b2 = squarerdx +# asm 1: mov b2=int64#6 +# asm 2: mov b2=%r9 +mov %rdx,%r9 + +# qhasm: squarerax = *(uint64 *)(pp + 48) +# asm 1: movq 48(squarerax=int64#7 +# asm 2: movq 48(squarerax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 40) +# asm 1: mulq 40(b3=int64#8 +# asm 2: mov b3=%r10 +mov %rax,%r10 + +# qhasm: squarer4 = squarerdx +# asm 1: mov squarer4=int64#9 +# asm 2: mov squarer4=%r11 +mov %rdx,%r11 + +# qhasm: squarerax = *(uint64 *)(pp + 56) +# asm 1: movq 56(squarerax=int64#7 +# asm 2: movq 56(squarerax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 48) +# asm 1: mulq 48(squarer5=int64#10 +# asm 2: mov squarer5=%r12 +mov %rax,%r12 + +# qhasm: squarer6 = squarerdx +# asm 1: mov squarer6=int64#11 +# asm 2: mov squarer6=%r13 +mov %rdx,%r13 + +# qhasm: squarerax = *(uint64 *)(pp + 48) +# asm 1: movq 48(squarerax=int64#7 +# asm 2: movq 48(squarerax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 32) +# asm 1: mulq 32(squarerax=int64#7 +# asm 2: movq 56(squarerax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 40) +# asm 1: mulq 40(squarerax=int64#7 +# asm 2: movq 56(squarerax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 32) +# asm 1: mulq 32(squarerax=int64#7 +# asm 2: movq 32(squarerax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 32) +# asm 1: mulq 32(b0=int64#12 +# asm 2: mov b0=%r14 +mov %rax,%r14 + +# qhasm: squaret1 = squarerdx +# asm 1: mov squaret1=int64#13 +# asm 2: mov squaret1=%r15 +mov %rdx,%r15 + +# qhasm: squarerax = *(uint64 *)(pp + 40) +# asm 1: movq 40(squarerax=int64#7 +# asm 2: movq 40(squarerax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 40) +# asm 1: mulq 40(squaret2=int64#14 +# asm 2: mov squaret2=%rbx +mov %rax,%rbx + +# qhasm: squaret3 = squarerdx +# asm 1: mov squaret3=int64#15 +# asm 2: mov squaret3=%rbp +mov %rdx,%rbp + +# qhasm: squarerax = *(uint64 *)(pp + 48) +# asm 1: movq 48(squarerax=int64#7 +# asm 2: movq 48(squarerax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 48) +# asm 1: mulq 48(squarerax=int64#7 +# asm 2: movq 56(squarerax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 56) +# asm 1: mulq 56(squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r11,%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: squarer4 = squarerax +# asm 1: mov squarer4=int64#9 +# asm 2: mov squarer4=%r11 +mov %rax,%r11 + +# qhasm: squarerax = squarer5 +# asm 1: mov squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r12,%rax + +# qhasm: squarer5 = squarerdx +# asm 1: mov squarer5=int64#10 +# asm 2: mov squarer5=%r12 +mov %rdx,%r12 + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? squarer5 += squarerax +# asm 1: add squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r13,%rax + +# qhasm: squarer6 = 0 +# asm 1: mov $0,>squarer6=int64#11 +# asm 2: mov $0,>squarer6=%r13 +mov $0,%r13 + +# qhasm: squarer6 += squarerdx + carry +# asm 1: adc squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %rcx,%rax + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#4 +# asm 2: mov $0,>squarer7=%rcx +mov $0,%rcx + +# qhasm: squarer7 += squarerdx + carry +# asm 1: adc squarer8=int64#7 +# asm 2: mov $0,>squarer8=%rax +mov $0,%rax + +# qhasm: squarer8 += squarerdx + carry +# asm 1: adc squarezero=int64#3 +# asm 2: mov $0,>squarezero=%rdx +mov $0,%rdx + +# qhasm: squarer8 += squarezero + carry +# asm 1: adc squarer8=int64#4 +# asm 2: imulq $38,squarer8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? b0 += squarer8 +# asm 1: add squarezero=int64#3 +# asm 2: imulq $38,squarezero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: b0 += squarezero +# asm 1: add b0_stack=stack64#12 +# asm 2: movq b0_stack=88(%rsp) +movq %r14,88(%rsp) + +# qhasm: b1_stack = b1 +# asm 1: movq b1_stack=stack64#13 +# asm 2: movq b1_stack=96(%rsp) +movq %r8,96(%rsp) + +# qhasm: b2_stack = b2 +# asm 1: movq b2_stack=stack64#14 +# asm 2: movq b2_stack=104(%rsp) +movq %r9,104(%rsp) + +# qhasm: b3_stack = b3 +# asm 1: movq b3_stack=stack64#15 +# asm 2: movq b3_stack=112(%rsp) +movq %r10,112(%rsp) + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#4 +# asm 2: mov $0,>squarer7=%rcx +mov $0,%rcx + +# qhasm: squarerax = *(uint64 *)(pp + 72) +# asm 1: movq 72(squarerax=int64#7 +# asm 2: movq 72(squarerax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 64) +# asm 1: mulq 64(c1=int64#5 +# asm 2: mov c1=%r8 +mov %rax,%r8 + +# qhasm: c2 = squarerdx +# asm 1: mov c2=int64#6 +# asm 2: mov c2=%r9 +mov %rdx,%r9 + +# qhasm: squarerax = *(uint64 *)(pp + 80) +# asm 1: movq 80(squarerax=int64#7 +# asm 2: movq 80(squarerax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 72) +# asm 1: mulq 72(c3=int64#8 +# asm 2: mov c3=%r10 +mov %rax,%r10 + +# qhasm: squarer4 = squarerdx +# asm 1: mov squarer4=int64#9 +# asm 2: mov squarer4=%r11 +mov %rdx,%r11 + +# qhasm: squarerax = *(uint64 *)(pp + 88) +# asm 1: movq 88(squarerax=int64#7 +# asm 2: movq 88(squarerax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 80) +# asm 1: mulq 80(squarer5=int64#10 +# asm 2: mov squarer5=%r12 +mov %rax,%r12 + +# qhasm: squarer6 = squarerdx +# asm 1: mov squarer6=int64#11 +# asm 2: mov squarer6=%r13 +mov %rdx,%r13 + +# qhasm: squarerax = *(uint64 *)(pp + 80) +# asm 1: movq 80(squarerax=int64#7 +# asm 2: movq 80(squarerax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 64) +# asm 1: mulq 64(squarerax=int64#7 +# asm 2: movq 88(squarerax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 72) +# asm 1: mulq 72(squarerax=int64#7 +# asm 2: movq 88(squarerax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 64) +# asm 1: mulq 64(squarerax=int64#7 +# asm 2: movq 64(squarerax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 64) +# asm 1: mulq 64(c0=int64#12 +# asm 2: mov c0=%r14 +mov %rax,%r14 + +# qhasm: squaret1 = squarerdx +# asm 1: mov squaret1=int64#13 +# asm 2: mov squaret1=%r15 +mov %rdx,%r15 + +# qhasm: squarerax = *(uint64 *)(pp + 72) +# asm 1: movq 72(squarerax=int64#7 +# asm 2: movq 72(squarerax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 72) +# asm 1: mulq 72(squaret2=int64#14 +# asm 2: mov squaret2=%rbx +mov %rax,%rbx + +# qhasm: squaret3 = squarerdx +# asm 1: mov squaret3=int64#15 +# asm 2: mov squaret3=%rbp +mov %rdx,%rbp + +# qhasm: squarerax = *(uint64 *)(pp + 80) +# asm 1: movq 80(squarerax=int64#7 +# asm 2: movq 80(squarerax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 80) +# asm 1: mulq 80(squarerax=int64#7 +# asm 2: movq 88(squarerax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 88) +# asm 1: mulq 88(squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r11,%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: squarer4 = squarerax +# asm 1: mov squarer4=int64#9 +# asm 2: mov squarer4=%r11 +mov %rax,%r11 + +# qhasm: squarerax = squarer5 +# asm 1: mov squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r12,%rax + +# qhasm: squarer5 = squarerdx +# asm 1: mov squarer5=int64#10 +# asm 2: mov squarer5=%r12 +mov %rdx,%r12 + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? squarer5 += squarerax +# asm 1: add squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r13,%rax + +# qhasm: squarer6 = 0 +# asm 1: mov $0,>squarer6=int64#11 +# asm 2: mov $0,>squarer6=%r13 +mov $0,%r13 + +# qhasm: squarer6 += squarerdx + carry +# asm 1: adc squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %rcx,%rax + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#4 +# asm 2: mov $0,>squarer7=%rcx +mov $0,%rcx + +# qhasm: squarer7 += squarerdx + carry +# asm 1: adc squarer8=int64#7 +# asm 2: mov $0,>squarer8=%rax +mov $0,%rax + +# qhasm: squarer8 += squarerdx + carry +# asm 1: adc squarezero=int64#3 +# asm 2: mov $0,>squarezero=%rdx +mov $0,%rdx + +# qhasm: squarer8 += squarezero + carry +# asm 1: adc squarer8=int64#4 +# asm 2: imulq $38,squarer8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? c0 += squarer8 +# asm 1: add squarezero=int64#3 +# asm 2: imulq $38,squarezero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: c0 += squarezero +# asm 1: add addt0=int64#3 +# asm 2: mov $0,>addt0=%rdx +mov $0,%rdx + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#4 +# asm 2: mov $38,>addt1=%rcx +mov $38,%rcx + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae c0_stack=stack64#16 +# asm 2: movq c0_stack=120(%rsp) +movq %r14,120(%rsp) + +# qhasm: c1_stack = c1 +# asm 1: movq c1_stack=stack64#17 +# asm 2: movq c1_stack=128(%rsp) +movq %r8,128(%rsp) + +# qhasm: c2_stack = c2 +# asm 1: movq c2_stack=stack64#18 +# asm 2: movq c2_stack=136(%rsp) +movq %r9,136(%rsp) + +# qhasm: c3_stack = c3 +# asm 1: movq c3_stack=stack64#19 +# asm 2: movq c3_stack=144(%rsp) +movq %r10,144(%rsp) + +# qhasm: d0 = 0 +# asm 1: mov $0,>d0=int64#3 +# asm 2: mov $0,>d0=%rdx +mov $0,%rdx + +# qhasm: d1 = 0 +# asm 1: mov $0,>d1=int64#4 +# asm 2: mov $0,>d1=%rcx +mov $0,%rcx + +# qhasm: d2 = 0 +# asm 1: mov $0,>d2=int64#5 +# asm 2: mov $0,>d2=%r8 +mov $0,%r8 + +# qhasm: d3 = 0 +# asm 1: mov $0,>d3=int64#6 +# asm 2: mov $0,>d3=%r9 +mov $0,%r9 + +# qhasm: carry? d0 -= a0_stack +# asm 1: subq subt0=int64#7 +# asm 2: mov $0,>subt0=%rax +mov $0,%rax + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#8 +# asm 2: mov $38,>subt1=%r10 +mov $38,%r10 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae d0_stack=stack64#8 +# asm 2: movq d0_stack=56(%rsp) +movq %rdx,56(%rsp) + +# qhasm: d1_stack = d1 +# asm 1: movq d1_stack=stack64#9 +# asm 2: movq d1_stack=64(%rsp) +movq %rcx,64(%rsp) + +# qhasm: d2_stack = d2 +# asm 1: movq d2_stack=stack64#10 +# asm 2: movq d2_stack=72(%rsp) +movq %r8,72(%rsp) + +# qhasm: d3_stack = d3 +# asm 1: movq d3_stack=stack64#11 +# asm 2: movq d3_stack=80(%rsp) +movq %r9,80(%rsp) + +# qhasm: e0 = 0 +# asm 1: mov $0,>e0=int64#7 +# asm 2: mov $0,>e0=%rax +mov $0,%rax + +# qhasm: e1 = 0 +# asm 1: mov $0,>e1=int64#8 +# asm 2: mov $0,>e1=%r10 +mov $0,%r10 + +# qhasm: e2 = 0 +# asm 1: mov $0,>e2=int64#9 +# asm 2: mov $0,>e2=%r11 +mov $0,%r11 + +# qhasm: e3 = 0 +# asm 1: mov $0,>e3=int64#10 +# asm 2: mov $0,>e3=%r12 +mov $0,%r12 + +# qhasm: carry? e0 -= b0_stack +# asm 1: subq subt0=int64#11 +# asm 2: mov $0,>subt0=%r13 +mov $0,%r13 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#12 +# asm 2: mov $38,>subt1=%r14 +mov $38,%r14 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae e0_stack=stack64#20 +# asm 2: movq e0_stack=152(%rsp) +movq %rax,152(%rsp) + +# qhasm: e1_stack = e1 +# asm 1: movq e1_stack=stack64#21 +# asm 2: movq e1_stack=160(%rsp) +movq %r10,160(%rsp) + +# qhasm: e2_stack = e2 +# asm 1: movq e2_stack=stack64#22 +# asm 2: movq e2_stack=168(%rsp) +movq %r11,168(%rsp) + +# qhasm: e3_stack = e3 +# asm 1: movq e3_stack=stack64#23 +# asm 2: movq e3_stack=176(%rsp) +movq %r12,176(%rsp) + +# qhasm: rz0 = d0 +# asm 1: mov rz0=int64#7 +# asm 2: mov rz0=%rax +mov %rdx,%rax + +# qhasm: rz1 = d1 +# asm 1: mov rz1=int64#8 +# asm 2: mov rz1=%r10 +mov %rcx,%r10 + +# qhasm: rz2 = d2 +# asm 1: mov rz2=int64#9 +# asm 2: mov rz2=%r11 +mov %r8,%r11 + +# qhasm: rz3 = d3 +# asm 1: mov rz3=int64#10 +# asm 2: mov rz3=%r12 +mov %r9,%r12 + +# qhasm: carry? rz0 += b0_stack +# asm 1: addq addt0=int64#11 +# asm 2: mov $0,>addt0=%r13 +mov $0,%r13 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#12 +# asm 2: mov $38,>addt1=%r14 +mov $38,%r14 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae subt0=int64#11 +# asm 2: mov $0,>subt0=%r13 +mov $0,%r13 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#12 +# asm 2: mov $38,>subt1=%r14 +mov $38,%r14 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae subt0=int64#3 +# asm 2: mov $0,>subt0=%rdx +mov $0,%rdx + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#4 +# asm 2: mov $38,>subt1=%rcx +mov $38,%rcx + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae rx0=int64#3 +# asm 2: movq 0(rx0=%rdx +movq 0(%rsi),%rdx + +# qhasm: rx1 = *(uint64 *)(pp + 8) +# asm 1: movq 8(rx1=int64#4 +# asm 2: movq 8(rx1=%rcx +movq 8(%rsi),%rcx + +# qhasm: rx2 = *(uint64 *)(pp + 16) +# asm 1: movq 16(rx2=int64#5 +# asm 2: movq 16(rx2=%r8 +movq 16(%rsi),%r8 + +# qhasm: rx3 = *(uint64 *)(pp + 24) +# asm 1: movq 24(rx3=int64#6 +# asm 2: movq 24(rx3=%r9 +movq 24(%rsi),%r9 + +# qhasm: carry? rx0 += *(uint64 *)(pp + 32) +# asm 1: addq 32(addt0=int64#2 +# asm 2: mov $0,>addt0=%rsi +mov $0,%rsi + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#7 +# asm 2: mov $38,>addt1=%rax +mov $38,%rax + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae rx0_stack=stack64#12 +# asm 2: movq rx0_stack=88(%rsp) +movq %rdx,88(%rsp) + +# qhasm: rx1_stack = rx1 +# asm 1: movq rx1_stack=stack64#13 +# asm 2: movq rx1_stack=96(%rsp) +movq %rcx,96(%rsp) + +# qhasm: rx2_stack = rx2 +# asm 1: movq rx2_stack=stack64#14 +# asm 2: movq rx2_stack=104(%rsp) +movq %r8,104(%rsp) + +# qhasm: rx3_stack = rx3 +# asm 1: movq rx3_stack=stack64#15 +# asm 2: movq rx3_stack=112(%rsp) +movq %r9,112(%rsp) + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#2 +# asm 2: mov $0,>squarer7=%rsi +mov $0,%rsi + +# qhasm: squarerax = rx1_stack +# asm 1: movq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 96(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx0_stack +# asm 1: mulq rx1=int64#4 +# asm 2: mov rx1=%rcx +mov %rax,%rcx + +# qhasm: rx2 = squarerdx +# asm 1: mov rx2=int64#5 +# asm 2: mov rx2=%r8 +mov %rdx,%r8 + +# qhasm: squarerax = rx2_stack +# asm 1: movq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 104(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx1_stack +# asm 1: mulq rx3=int64#6 +# asm 2: mov rx3=%r9 +mov %rax,%r9 + +# qhasm: squarer4 = squarerdx +# asm 1: mov squarer4=int64#8 +# asm 2: mov squarer4=%r10 +mov %rdx,%r10 + +# qhasm: squarerax = rx3_stack +# asm 1: movq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 112(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx2_stack +# asm 1: mulq squarer5=int64#9 +# asm 2: mov squarer5=%r11 +mov %rax,%r11 + +# qhasm: squarer6 = squarerdx +# asm 1: mov squarer6=int64#10 +# asm 2: mov squarer6=%r12 +mov %rdx,%r12 + +# qhasm: squarerax = rx2_stack +# asm 1: movq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 104(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx0_stack +# asm 1: mulq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 112(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx1_stack +# asm 1: mulq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 112(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx0_stack +# asm 1: mulq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 88(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx0_stack +# asm 1: mulq rx0=int64#11 +# asm 2: mov rx0=%r13 +mov %rax,%r13 + +# qhasm: squaret1 = squarerdx +# asm 1: mov squaret1=int64#12 +# asm 2: mov squaret1=%r14 +mov %rdx,%r14 + +# qhasm: squarerax = rx1_stack +# asm 1: movq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 96(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx1_stack +# asm 1: mulq squaret2=int64#13 +# asm 2: mov squaret2=%r15 +mov %rax,%r15 + +# qhasm: squaret3 = squarerdx +# asm 1: mov squaret3=int64#14 +# asm 2: mov squaret3=%rbx +mov %rdx,%rbx + +# qhasm: squarerax = rx2_stack +# asm 1: movq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 104(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx2_stack +# asm 1: mulq squarerax=int64#7 +# asm 2: movq squarerax=%rax +movq 112(%rsp),%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * rx3_stack +# asm 1: mulq squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r10,%rax + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: squarer4 = squarerax +# asm 1: mov squarer4=int64#8 +# asm 2: mov squarer4=%r10 +mov %rax,%r10 + +# qhasm: squarerax = squarer5 +# asm 1: mov squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r11,%rax + +# qhasm: squarer5 = squarerdx +# asm 1: mov squarer5=int64#9 +# asm 2: mov squarer5=%r11 +mov %rdx,%r11 + +# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? squarer5 += squarerax +# asm 1: add squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %r12,%rax + +# qhasm: squarer6 = 0 +# asm 1: mov $0,>squarer6=int64#10 +# asm 2: mov $0,>squarer6=%r12 +mov $0,%r12 + +# qhasm: squarer6 += squarerdx + carry +# asm 1: adc squarerax=int64#7 +# asm 2: mov squarerax=%rax +mov %rsi,%rax + +# qhasm: squarer7 = 0 +# asm 1: mov $0,>squarer7=int64#2 +# asm 2: mov $0,>squarer7=%rsi +mov $0,%rsi + +# qhasm: squarer7 += squarerdx + carry +# asm 1: adc squarer8=int64#7 +# asm 2: mov $0,>squarer8=%rax +mov $0,%rax + +# qhasm: squarer8 += squarerdx + carry +# asm 1: adc squarezero=int64#2 +# asm 2: mov $0,>squarezero=%rsi +mov $0,%rsi + +# qhasm: squarer8 += squarezero + carry +# asm 1: adc squarer8=int64#3 +# asm 2: imulq $38,squarer8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? rx0 += squarer8 +# asm 1: add squarezero=int64#2 +# asm 2: imulq $38,squarezero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: rx0 += squarezero +# asm 1: add addt0=int64#2 +# asm 2: mov $0,>addt0=%rsi +mov $0,%rsi + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#3 +# asm 2: mov $38,>addt1=%rdx +mov $38,%rdx + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae addt0=int64#2 +# asm 2: mov $0,>addt0=%rsi +mov $0,%rsi + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#3 +# asm 2: mov $38,>addt1=%rdx +mov $38,%rdx + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/ge25519_double.c b/ext/ed25519-amd64-asm/ge25519_double.c new file mode 100644 index 0000000..d55e2b4 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_double.c @@ -0,0 +1,8 @@ +#include "ge25519.h" + +void ge25519_double(ge25519_p3 *r, const ge25519_p3 *p) +{ + ge25519_p1p1 grp1p1; + ge25519_dbl_p1p1(&grp1p1, (ge25519_p2 *)p); + ge25519_p1p1_to_p3(r, &grp1p1); +} diff --git a/ext/ed25519-amd64-asm/ge25519_double_scalarmult.c b/ext/ed25519-amd64-asm/ge25519_double_scalarmult.c new file mode 100644 index 0000000..30c922a --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_double_scalarmult.c @@ -0,0 +1,102 @@ +#include "fe25519.h" +#include "sc25519.h" +#include "ge25519.h" + +#define S1_SWINDOWSIZE 5 +#define PRE1_SIZE (1<<(S1_SWINDOWSIZE-2)) +#define S2_SWINDOWSIZE 7 +#define PRE2_SIZE (1<<(S2_SWINDOWSIZE-2)) + +ge25519_niels pre2[PRE2_SIZE] = { +#include "ge25519_base_slide_multiples.data" +}; + +static const fe25519 ec2d = {{0xEBD69B9426B2F146, 0x00E0149A8283B156, 0x198E80F2EEF3D130, 0xA406D9DC56DFFCE7}}; + +static void setneutral(ge25519 *r) +{ + fe25519_setint(&r->x,0); + fe25519_setint(&r->y,1); + fe25519_setint(&r->z,1); + fe25519_setint(&r->t,0); +} + +/* computes [s1]p1 + [s2]p2 */ +void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const sc25519 *s2) +{ + signed char slide1[256], slide2[256]; + ge25519_pniels pre1[PRE1_SIZE], neg; + ge25519_p3 d1; + ge25519_p1p1 t; + ge25519_niels nneg; + fe25519 d; + int i; + + sc25519_slide(slide1, s1, S1_SWINDOWSIZE); + sc25519_slide(slide2, s2, S2_SWINDOWSIZE); + + /* precomputation */ + pre1[0] = *(ge25519_pniels *)p1; + ge25519_dbl_p1p1(&t,(ge25519_p2 *)pre1); ge25519_p1p1_to_p3(&d1, &t); + /* Convert pre[0] to projective Niels representation */ + d = pre1[0].ysubx; + fe25519_sub(&pre1[0].ysubx, &pre1[0].xaddy, &pre1[0].ysubx); + fe25519_add(&pre1[0].xaddy, &pre1[0].xaddy, &d); + fe25519_mul(&pre1[0].t2d, &pre1[0].t2d, &ec2d); + + for(i=0;i= 0;--i) { + if (slide1[i] || slide2[i]) goto firstbit; + } + + for(;i>=0;i--) + { + firstbit: + + ge25519_dbl_p1p1(&t, (ge25519_p2 *)r); + + if(slide1[i]>0) + { + ge25519_p1p1_to_p3(r, &t); + ge25519_pnielsadd_p1p1(&t, r, &pre1[slide1[i]/2]); + } + else if(slide1[i]<0) + { + ge25519_p1p1_to_p3(r, &t); + neg = pre1[-slide1[i]/2]; + d = neg.ysubx; + neg.ysubx = neg.xaddy; + neg.xaddy = d; + fe25519_neg(&neg.t2d, &neg.t2d); + ge25519_pnielsadd_p1p1(&t, r, &neg); + } + + if(slide2[i]>0) + { + ge25519_p1p1_to_p3(r, &t); + ge25519_nielsadd_p1p1(&t, r, &pre2[slide2[i]/2]); + } + else if(slide2[i]<0) + { + ge25519_p1p1_to_p3(r, &t); + nneg = pre2[-slide2[i]/2]; + d = nneg.ysubx; + nneg.ysubx = nneg.xaddy; + nneg.xaddy = d; + fe25519_neg(&nneg.t2d, &nneg.t2d); + ge25519_nielsadd_p1p1(&t, r, &nneg); + } + + ge25519_p1p1_to_p2((ge25519_p2 *)r, &t); + } +} diff --git a/ext/ed25519-amd64-asm/ge25519_isneutral.c b/ext/ed25519-amd64-asm/ge25519_isneutral.c new file mode 100644 index 0000000..cf566db --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_isneutral.c @@ -0,0 +1,9 @@ +#include "fe25519.h" +#include "ge25519.h" + +int ge25519_isneutral_vartime(const ge25519_p3 *p) +{ + if(!fe25519_iszero_vartime(&p->x)) return 0; + if(!fe25519_iseq_vartime(&p->y, &p->z)) return 0; + return 1; +} diff --git a/ext/ed25519-amd64-asm/ge25519_multi_scalarmult.c b/ext/ed25519-amd64-asm/ge25519_multi_scalarmult.c new file mode 100644 index 0000000..afc6aea --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_multi_scalarmult.c @@ -0,0 +1,102 @@ +#include "fe25519.h" +#include "sc25519.h" +#include "ge25519.h" +#include "index_heap.h" + +static void setneutral(ge25519 *r) +{ + fe25519_setint(&r->x,0); + fe25519_setint(&r->y,1); + fe25519_setint(&r->z,1); + fe25519_setint(&r->t,0); +} + +static void ge25519_scalarmult_vartime_2limbs(ge25519 *r, ge25519 *p, sc25519 *s) +{ + if (s->v[1] == 0 && s->v[0] == 1) /* This will happen most of the time after Bos-Coster */ + *r = *p; + else if (s->v[1] == 0 && s->v[0] == 0) /* This won't ever happen, except for all scalars == 0 in Bos-Coster */ + setneutral(r); + else + { + ge25519 d; + unsigned long long mask = (1ULL << 63); + int i = 1; + while(!(mask & s->v[1]) && mask != 0) + mask >>= 1; + if(mask == 0) + { + mask = (1ULL << 63); + i = 0; + while(!(mask & s->v[0]) && mask != 0) + mask >>= 1; + } + d = *p; + mask >>= 1; + for(;mask != 0;mask >>= 1) + { + ge25519_double(&d,&d); + if(s->v[i] & mask) + ge25519_add(&d,&d,p); + } + if(i==1) + { + mask = (1ULL << 63); + for(;mask != 0;mask >>= 1) + { + ge25519_double(&d,&d); + if(s->v[0] & mask) + ge25519_add(&d,&d,p); + } + } + *r = d; + } +} + +/* caller's responsibility to ensure npoints >= 5 */ +void ge25519_multi_scalarmult_vartime(ge25519_p3 *r, ge25519_p3 *p, sc25519 *s, const unsigned long long npoints) +{ + unsigned long long pos[npoints]; + unsigned long long hlen=((npoints+1)/2)|1; + unsigned long long max1, max2,i; + + heap_init(pos, hlen, s); + + for(i=0;;i++) + { + heap_get2max(pos, &max1, &max2, s); + if((s[max1].v[3] == 0) || (sc25519_iszero_vartime(&s[max2]))) break; + sc25519_sub_nored(&s[max1],&s[max1],&s[max2]); + ge25519_add(&p[max2],&p[max2],&p[max1]); + heap_rootreplaced(pos, hlen, s); + } + for(;;i++) + { + heap_get2max(pos, &max1, &max2, s); + if((s[max1].v[2] == 0) || (sc25519_iszero_vartime(&s[max2]))) break; + sc25519_sub_nored(&s[max1],&s[max1],&s[max2]); + ge25519_add(&p[max2],&p[max2],&p[max1]); + heap_rootreplaced_3limbs(pos, hlen, s); + } + /* We know that (npoints-1)/2 scalars are only 128-bit scalars */ + heap_extend(pos, hlen, npoints, s); + hlen = npoints; + for(;;i++) + { + heap_get2max(pos, &max1, &max2, s); + if((s[max1].v[1] == 0) || (sc25519_iszero_vartime(&s[max2]))) break; + sc25519_sub_nored(&s[max1],&s[max1],&s[max2]); + ge25519_add(&p[max2],&p[max2],&p[max1]); + heap_rootreplaced_2limbs(pos, hlen, s); + } + for(;;i++) + { + heap_get2max(pos, &max1, &max2, s); + if(sc25519_iszero_vartime(&s[max2])) break; + sc25519_sub_nored(&s[max1],&s[max1],&s[max2]); + ge25519_add(&p[max2],&p[max2],&p[max1]); + heap_rootreplaced_1limb(pos, hlen, s); + } + + ge25519_scalarmult_vartime_2limbs(r, &p[max1], &s[max1]); +} diff --git a/ext/ed25519-amd64-asm/ge25519_nielsadd2.s b/ext/ed25519-amd64-asm/ge25519_nielsadd2.s new file mode 100644 index 0000000..19d71f1 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_nielsadd2.s @@ -0,0 +1,5791 @@ + +# qhasm: int64 rp + +# qhasm: int64 qp + +# qhasm: input rp + +# qhasm: input qp + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 a0 + +# qhasm: int64 a1 + +# qhasm: int64 a2 + +# qhasm: int64 a3 + +# qhasm: stack64 a0_stack + +# qhasm: stack64 a1_stack + +# qhasm: stack64 a2_stack + +# qhasm: stack64 a3_stack + +# qhasm: int64 b0 + +# qhasm: int64 b1 + +# qhasm: int64 b2 + +# qhasm: int64 b3 + +# qhasm: stack64 b0_stack + +# qhasm: stack64 b1_stack + +# qhasm: stack64 b2_stack + +# qhasm: stack64 b3_stack + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: stack64 c0_stack + +# qhasm: stack64 c1_stack + +# qhasm: stack64 c2_stack + +# qhasm: stack64 c3_stack + +# qhasm: int64 d0 + +# qhasm: int64 d1 + +# qhasm: int64 d2 + +# qhasm: int64 d3 + +# qhasm: stack64 d0_stack + +# qhasm: stack64 d1_stack + +# qhasm: stack64 d2_stack + +# qhasm: stack64 d3_stack + +# qhasm: int64 e0 + +# qhasm: int64 e1 + +# qhasm: int64 e2 + +# qhasm: int64 e3 + +# qhasm: stack64 e0_stack + +# qhasm: stack64 e1_stack + +# qhasm: stack64 e2_stack + +# qhasm: stack64 e3_stack + +# qhasm: int64 f0 + +# qhasm: int64 f1 + +# qhasm: int64 f2 + +# qhasm: int64 f3 + +# qhasm: stack64 f0_stack + +# qhasm: stack64 f1_stack + +# qhasm: stack64 f2_stack + +# qhasm: stack64 f3_stack + +# qhasm: int64 g0 + +# qhasm: int64 g1 + +# qhasm: int64 g2 + +# qhasm: int64 g3 + +# qhasm: stack64 g0_stack + +# qhasm: stack64 g1_stack + +# qhasm: stack64 g2_stack + +# qhasm: stack64 g3_stack + +# qhasm: int64 h0 + +# qhasm: int64 h1 + +# qhasm: int64 h2 + +# qhasm: int64 h3 + +# qhasm: stack64 h0_stack + +# qhasm: stack64 h1_stack + +# qhasm: stack64 h2_stack + +# qhasm: stack64 h3_stack + +# qhasm: int64 qt0 + +# qhasm: int64 qt1 + +# qhasm: int64 qt2 + +# qhasm: int64 qt3 + +# qhasm: stack64 qt0_stack + +# qhasm: stack64 qt1_stack + +# qhasm: stack64 qt2_stack + +# qhasm: stack64 qt3_stack + +# qhasm: int64 t10 + +# qhasm: int64 t11 + +# qhasm: int64 t12 + +# qhasm: int64 t13 + +# qhasm: stack64 t10_stack + +# qhasm: stack64 t11_stack + +# qhasm: stack64 t12_stack + +# qhasm: stack64 t13_stack + +# qhasm: int64 t20 + +# qhasm: int64 t21 + +# qhasm: int64 t22 + +# qhasm: int64 t23 + +# qhasm: stack64 t20_stack + +# qhasm: stack64 t21_stack + +# qhasm: stack64 t22_stack + +# qhasm: stack64 t23_stack + +# qhasm: int64 rx0 + +# qhasm: int64 rx1 + +# qhasm: int64 rx2 + +# qhasm: int64 rx3 + +# qhasm: int64 ry0 + +# qhasm: int64 ry1 + +# qhasm: int64 ry2 + +# qhasm: int64 ry3 + +# qhasm: int64 rz0 + +# qhasm: int64 rz1 + +# qhasm: int64 rz2 + +# qhasm: int64 rz3 + +# qhasm: int64 rt0 + +# qhasm: int64 rt1 + +# qhasm: int64 rt2 + +# qhasm: int64 rt3 + +# qhasm: int64 mulr4 + +# qhasm: int64 mulr5 + +# qhasm: int64 mulr6 + +# qhasm: int64 mulr7 + +# qhasm: int64 mulr8 + +# qhasm: int64 mulrax + +# qhasm: int64 mulrdx + +# qhasm: int64 mulx0 + +# qhasm: int64 mulx1 + +# qhasm: int64 mulx2 + +# qhasm: int64 mulx3 + +# qhasm: int64 mulc + +# qhasm: int64 mulzero + +# qhasm: int64 muli38 + +# qhasm: int64 addt0 + +# qhasm: int64 addt1 + +# qhasm: int64 subt0 + +# qhasm: int64 subt1 + +# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_nielsadd2 +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_ge25519_nielsadd2 +.globl crypto_sign_ed25519_amd64_64_ge25519_nielsadd2 +_crypto_sign_ed25519_amd64_64_ge25519_nielsadd2: +crypto_sign_ed25519_amd64_64_ge25519_nielsadd2: +mov %rsp,%r11 +and $31,%r11 +add $192,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: a0 = *(uint64 *)(rp + 32) +# asm 1: movq 32(a0=int64#3 +# asm 2: movq 32(a0=%rdx +movq 32(%rdi),%rdx + +# qhasm: a1 = *(uint64 *)(rp + 40) +# asm 1: movq 40(a1=int64#4 +# asm 2: movq 40(a1=%rcx +movq 40(%rdi),%rcx + +# qhasm: a2 = *(uint64 *)(rp + 48) +# asm 1: movq 48(a2=int64#5 +# asm 2: movq 48(a2=%r8 +movq 48(%rdi),%r8 + +# qhasm: a3 = *(uint64 *)(rp + 56) +# asm 1: movq 56(a3=int64#6 +# asm 2: movq 56(a3=%r9 +movq 56(%rdi),%r9 + +# qhasm: b0 = a0 +# asm 1: mov b0=int64#7 +# asm 2: mov b0=%rax +mov %rdx,%rax + +# qhasm: b1 = a1 +# asm 1: mov b1=int64#8 +# asm 2: mov b1=%r10 +mov %rcx,%r10 + +# qhasm: b2 = a2 +# asm 1: mov b2=int64#9 +# asm 2: mov b2=%r11 +mov %r8,%r11 + +# qhasm: b3 = a3 +# asm 1: mov b3=int64#10 +# asm 2: mov b3=%r12 +mov %r9,%r12 + +# qhasm: carry? a0 -= *(uint64 *) (rp + 0) +# asm 1: subq 0(subt0=int64#11 +# asm 2: mov $0,>subt0=%r13 +mov $0,%r13 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#12 +# asm 2: mov $38,>subt1=%r14 +mov $38,%r14 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#11 +# asm 2: mov $0,>addt0=%r13 +mov $0,%r13 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#12 +# asm 2: mov $38,>addt1=%r14 +mov $38,%r14 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %rdx,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %rcx,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r8,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %r9,80(%rsp) + +# qhasm: b0_stack = b0 +# asm 1: movq b0_stack=stack64#12 +# asm 2: movq b0_stack=88(%rsp) +movq %rax,88(%rsp) + +# qhasm: b1_stack = b1 +# asm 1: movq b1_stack=stack64#13 +# asm 2: movq b1_stack=96(%rsp) +movq %r10,96(%rsp) + +# qhasm: b2_stack = b2 +# asm 1: movq b2_stack=stack64#14 +# asm 2: movq b2_stack=104(%rsp) +movq %r11,104(%rsp) + +# qhasm: b3_stack = b3 +# asm 1: movq b3_stack=stack64#15 +# asm 2: movq b3_stack=112(%rsp) +movq %r12,112(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = a0_stack +# asm 1: movq mulx0=int64#9 +# asm 2: movq mulx0=%r11 +movq 56(%rsp),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a0=int64#10 +# asm 2: mov a0=%r12 +mov %rax,%r12 + +# qhasm: a1 = mulrdx +# asm 1: mov a1=int64#11 +# asm 2: mov a1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(qp + 8) +# asm 1: movq 8(mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a2=int64#12 +# asm 2: mov $0,>a2=%r14 +mov $0,%r14 + +# qhasm: a2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a3=int64#13 +# asm 2: mov $0,>a3=%r15 +mov $0,%r15 + +# qhasm: a3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq mulx1=%r11 +movq 64(%rsp),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq mulx2=%r11 +movq 72(%rsp),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq mulx3=%r11 +movq 80(%rsp),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#4 +# asm 2: mov mulr4=%rcx +mov %rax,%rcx + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#5 +# asm 2: mov mulr5=%r8 +mov %rdx,%r8 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#4 +# asm 2: imulq $38,mulr8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? a0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: a0 += mulzero +# asm 1: add a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %r12,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %r13,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r14,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %r15,80(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = b0_stack +# asm 1: movq mulx0=int64#9 +# asm 2: movq mulx0=%r11 +movq 88(%rsp),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul e0=int64#10 +# asm 2: mov e0=%r12 +mov %rax,%r12 + +# qhasm: e1 = mulrdx +# asm 1: mov e1=int64#11 +# asm 2: mov e1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(qp + 40) +# asm 1: movq 40(mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul e2=int64#12 +# asm 2: mov $0,>e2=%r14 +mov $0,%r14 + +# qhasm: e2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul e3=int64#13 +# asm 2: mov $0,>e3=%r15 +mov $0,%r15 + +# qhasm: e3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq mulx1=%r11 +movq 96(%rsp),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq mulx2=%r11 +movq 104(%rsp),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq mulx3=%r11 +movq 112(%rsp),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#4 +# asm 2: mov mulr4=%rcx +mov %rax,%rcx + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#5 +# asm 2: mov mulr5=%r8 +mov %rdx,%r8 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#4 +# asm 2: imulq $38,mulr8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? e0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: e0 += mulzero +# asm 1: add h0=int64#3 +# asm 2: mov h0=%rdx +mov %r12,%rdx + +# qhasm: h1 = e1 +# asm 1: mov h1=int64#4 +# asm 2: mov h1=%rcx +mov %r13,%rcx + +# qhasm: h2 = e2 +# asm 1: mov h2=int64#5 +# asm 2: mov h2=%r8 +mov %r14,%r8 + +# qhasm: h3 = e3 +# asm 1: mov h3=int64#6 +# asm 2: mov h3=%r9 +mov %r15,%r9 + +# qhasm: carry? e0 -= a0_stack +# asm 1: subq subt0=int64#7 +# asm 2: mov $0,>subt0=%rax +mov $0,%rax + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#8 +# asm 2: mov $38,>subt1=%r10 +mov $38,%r10 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#7 +# asm 2: mov $0,>addt0=%rax +mov $0,%rax + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#8 +# asm 2: mov $38,>addt1=%r10 +mov $38,%r10 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae h0_stack=stack64#8 +# asm 2: movq h0_stack=56(%rsp) +movq %rdx,56(%rsp) + +# qhasm: h1_stack = h1 +# asm 1: movq h1_stack=stack64#9 +# asm 2: movq h1_stack=64(%rsp) +movq %rcx,64(%rsp) + +# qhasm: h2_stack = h2 +# asm 1: movq h2_stack=stack64#10 +# asm 2: movq h2_stack=72(%rsp) +movq %r8,72(%rsp) + +# qhasm: h3_stack = h3 +# asm 1: movq h3_stack=stack64#11 +# asm 2: movq h3_stack=80(%rsp) +movq %r9,80(%rsp) + +# qhasm: e0_stack = e0 +# asm 1: movq e0_stack=stack64#12 +# asm 2: movq e0_stack=88(%rsp) +movq %r12,88(%rsp) + +# qhasm: e1_stack = e1 +# asm 1: movq e1_stack=stack64#13 +# asm 2: movq e1_stack=96(%rsp) +movq %r13,96(%rsp) + +# qhasm: e2_stack = e2 +# asm 1: movq e2_stack=stack64#14 +# asm 2: movq e2_stack=104(%rsp) +movq %r14,104(%rsp) + +# qhasm: e3_stack = e3 +# asm 1: movq e3_stack=stack64#15 +# asm 2: movq e3_stack=112(%rsp) +movq %r15,112(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = *(uint64 *)(rp + 96) +# asm 1: movq 96(mulx0=int64#9 +# asm 2: movq 96(mulx0=%r11 +movq 96(%rdi),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c0=int64#10 +# asm 2: mov c0=%r12 +mov %rax,%r12 + +# qhasm: c1 = mulrdx +# asm 1: mov c1=int64#11 +# asm 2: mov c1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(qp + 72) +# asm 1: movq 72(mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c2=int64#12 +# asm 2: mov $0,>c2=%r14 +mov $0,%r14 + +# qhasm: c2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c3=int64#13 +# asm 2: mov $0,>c3=%r15 +mov $0,%r15 + +# qhasm: c3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq 104(mulx1=%r11 +movq 104(%rdi),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq 112(mulx2=%r11 +movq 112(%rdi),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq 120(mulx3=%r11 +movq 120(%rdi),%r11 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? c0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: c0 += mulzero +# asm 1: add f0=int64#2 +# asm 2: movq 64(f0=%rsi +movq 64(%rdi),%rsi + +# qhasm: f1 = *(uint64 *)(rp + 72) +# asm 1: movq 72(f1=int64#3 +# asm 2: movq 72(f1=%rdx +movq 72(%rdi),%rdx + +# qhasm: f2 = *(uint64 *)(rp + 80) +# asm 1: movq 80(f2=int64#4 +# asm 2: movq 80(f2=%rcx +movq 80(%rdi),%rcx + +# qhasm: f3 = *(uint64 *)(rp + 88) +# asm 1: movq 88(f3=int64#5 +# asm 2: movq 88(f3=%r8 +movq 88(%rdi),%r8 + +# qhasm: carry? f0 += f0 +# asm 1: add addt0=int64#6 +# asm 2: mov $0,>addt0=%r9 +mov $0,%r9 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#7 +# asm 2: mov $38,>addt1=%rax +mov $38,%rax + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae g0=int64#6 +# asm 2: mov g0=%r9 +mov %rsi,%r9 + +# qhasm: g1 = f1 +# asm 1: mov g1=int64#7 +# asm 2: mov g1=%rax +mov %rdx,%rax + +# qhasm: g2 = f2 +# asm 1: mov g2=int64#8 +# asm 2: mov g2=%r10 +mov %rcx,%r10 + +# qhasm: g3 = f3 +# asm 1: mov g3=int64#9 +# asm 2: mov g3=%r11 +mov %r8,%r11 + +# qhasm: carry? f0 -= c0 +# asm 1: sub subt0=int64#14 +# asm 2: mov $0,>subt0=%rbx +mov $0,%rbx + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#15 +# asm 2: mov $38,>subt1=%rbp +mov $38,%rbp + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#10 +# asm 2: mov $0,>addt0=%r12 +mov $0,%r12 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#11 +# asm 2: mov $38,>addt1=%r13 +mov $38,%r13 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae g0_stack=stack64#16 +# asm 2: movq g0_stack=120(%rsp) +movq %r9,120(%rsp) + +# qhasm: g1_stack = g1 +# asm 1: movq g1_stack=stack64#17 +# asm 2: movq g1_stack=128(%rsp) +movq %rax,128(%rsp) + +# qhasm: g2_stack = g2 +# asm 1: movq g2_stack=stack64#18 +# asm 2: movq g2_stack=136(%rsp) +movq %r10,136(%rsp) + +# qhasm: g3_stack = g3 +# asm 1: movq g3_stack=stack64#19 +# asm 2: movq g3_stack=144(%rsp) +movq %r11,144(%rsp) + +# qhasm: f0_stack = f0 +# asm 1: movq f0_stack=stack64#20 +# asm 2: movq f0_stack=152(%rsp) +movq %rsi,152(%rsp) + +# qhasm: f1_stack = f1 +# asm 1: movq f1_stack=stack64#21 +# asm 2: movq f1_stack=160(%rsp) +movq %rdx,160(%rsp) + +# qhasm: f2_stack = f2 +# asm 1: movq f2_stack=stack64#22 +# asm 2: movq f2_stack=168(%rsp) +movq %rcx,168(%rsp) + +# qhasm: f3_stack = f3 +# asm 1: movq f3_stack=stack64#23 +# asm 2: movq f3_stack=176(%rsp) +movq %r8,176(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#2 +# asm 2: mov $0,>mulr4=%rsi +mov $0,%rsi + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#4 +# asm 2: mov $0,>mulr5=%rcx +mov $0,%rcx + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulx0 = e0_stack +# asm 1: movq mulx0=int64#8 +# asm 2: movq mulx0=%r10 +movq 88(%rsp),%r10 + +# qhasm: mulrax = f0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx0=int64#9 +# asm 2: mov rx0=%r11 +mov %rax,%r11 + +# qhasm: rx1 = mulrdx +# asm 1: mov rx1=int64#10 +# asm 2: mov rx1=%r12 +mov %rdx,%r12 + +# qhasm: mulrax = f1_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx2=int64#11 +# asm 2: mov $0,>rx2=%r13 +mov $0,%r13 + +# qhasm: rx2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx3=int64#12 +# asm 2: mov $0,>rx3=%r14 +mov $0,%r14 + +# qhasm: rx3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#8 +# asm 2: movq mulx1=%r10 +movq 96(%rsp),%r10 + +# qhasm: mulrax = f0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#8 +# asm 2: movq mulx2=%r10 +movq 104(%rsp),%r10 + +# qhasm: mulrax = f0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#8 +# asm 2: movq mulx3=%r10 +movq 112(%rsp),%r10 + +# qhasm: mulrax = f0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rsi,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? rx0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: rx0 += mulzero +# asm 1: add mulr4=int64#2 +# asm 2: mov $0,>mulr4=%rsi +mov $0,%rsi + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#4 +# asm 2: mov $0,>mulr5=%rcx +mov $0,%rcx + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulx0 = h0_stack +# asm 1: movq mulx0=int64#8 +# asm 2: movq mulx0=%r10 +movq 56(%rsp),%r10 + +# qhasm: mulrax = g0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 120(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry0=int64#9 +# asm 2: mov ry0=%r11 +mov %rax,%r11 + +# qhasm: ry1 = mulrdx +# asm 1: mov ry1=int64#10 +# asm 2: mov ry1=%r12 +mov %rdx,%r12 + +# qhasm: mulrax = g1_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 128(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry2=int64#11 +# asm 2: mov $0,>ry2=%r13 +mov $0,%r13 + +# qhasm: ry2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 136(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry3=int64#12 +# asm 2: mov $0,>ry3=%r14 +mov $0,%r14 + +# qhasm: ry3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 144(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#8 +# asm 2: movq mulx1=%r10 +movq 64(%rsp),%r10 + +# qhasm: mulrax = g0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 120(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 128(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 136(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 144(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#8 +# asm 2: movq mulx2=%r10 +movq 72(%rsp),%r10 + +# qhasm: mulrax = g0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 120(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 128(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 136(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 144(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#8 +# asm 2: movq mulx3=%r10 +movq 80(%rsp),%r10 + +# qhasm: mulrax = g0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 120(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 128(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 136(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 144(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rsi,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? ry0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: ry0 += mulzero +# asm 1: add mulr4=int64#2 +# asm 2: mov $0,>mulr4=%rsi +mov $0,%rsi + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#4 +# asm 2: mov $0,>mulr5=%rcx +mov $0,%rcx + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulx0 = g0_stack +# asm 1: movq mulx0=int64#8 +# asm 2: movq mulx0=%r10 +movq 120(%rsp),%r10 + +# qhasm: mulrax = f0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz0=int64#9 +# asm 2: mov rz0=%r11 +mov %rax,%r11 + +# qhasm: rz1 = mulrdx +# asm 1: mov rz1=int64#10 +# asm 2: mov rz1=%r12 +mov %rdx,%r12 + +# qhasm: mulrax = f1_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz2=int64#11 +# asm 2: mov $0,>rz2=%r13 +mov $0,%r13 + +# qhasm: rz2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz3=int64#12 +# asm 2: mov $0,>rz3=%r14 +mov $0,%r14 + +# qhasm: rz3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#8 +# asm 2: movq mulx1=%r10 +movq 128(%rsp),%r10 + +# qhasm: mulrax = f0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#8 +# asm 2: movq mulx2=%r10 +movq 136(%rsp),%r10 + +# qhasm: mulrax = f0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#8 +# asm 2: movq mulx3=%r10 +movq 144(%rsp),%r10 + +# qhasm: mulrax = f0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 152(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 160(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 168(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 176(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rsi,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? rz0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: rz0 += mulzero +# asm 1: add mulr4=int64#2 +# asm 2: mov $0,>mulr4=%rsi +mov $0,%rsi + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#4 +# asm 2: mov $0,>mulr5=%rcx +mov $0,%rcx + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulx0 = e0_stack +# asm 1: movq mulx0=int64#8 +# asm 2: movq mulx0=%r10 +movq 88(%rsp),%r10 + +# qhasm: mulrax = h0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 56(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt0=int64#9 +# asm 2: mov rt0=%r11 +mov %rax,%r11 + +# qhasm: rt1 = mulrdx +# asm 1: mov rt1=int64#10 +# asm 2: mov rt1=%r12 +mov %rdx,%r12 + +# qhasm: mulrax = h1_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 64(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt2=int64#11 +# asm 2: mov $0,>rt2=%r13 +mov $0,%r13 + +# qhasm: rt2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 72(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt3=int64#12 +# asm 2: mov $0,>rt3=%r14 +mov $0,%r14 + +# qhasm: rt3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 80(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#8 +# asm 2: movq mulx1=%r10 +movq 96(%rsp),%r10 + +# qhasm: mulrax = h0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 56(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 64(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 72(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 80(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#8 +# asm 2: movq mulx2=%r10 +movq 104(%rsp),%r10 + +# qhasm: mulrax = h0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 56(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 64(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 72(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 80(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#8 +# asm 2: movq mulx3=%r10 +movq 112(%rsp),%r10 + +# qhasm: mulrax = h0_stack +# asm 1: movq mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 56(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 64(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 72(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#13 +# asm 2: mov $0,>mulc=%r15 +mov $0,%r15 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq mulrax=%rax +movq 80(%rsp),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rsi,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? rt0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: rt0 += mulzero +# asm 1: add caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s b/ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s new file mode 100644 index 0000000..b562946 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s @@ -0,0 +1,3072 @@ + +# qhasm: int64 rp + +# qhasm: int64 pp + +# qhasm: int64 qp + +# qhasm: input rp + +# qhasm: input pp + +# qhasm: input qp + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 a0 + +# qhasm: int64 a1 + +# qhasm: int64 a2 + +# qhasm: int64 a3 + +# qhasm: stack64 a0_stack + +# qhasm: stack64 a1_stack + +# qhasm: stack64 a2_stack + +# qhasm: stack64 a3_stack + +# qhasm: int64 b0 + +# qhasm: int64 b1 + +# qhasm: int64 b2 + +# qhasm: int64 b3 + +# qhasm: stack64 b0_stack + +# qhasm: stack64 b1_stack + +# qhasm: stack64 b2_stack + +# qhasm: stack64 b3_stack + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: stack64 c0_stack + +# qhasm: stack64 c1_stack + +# qhasm: stack64 c2_stack + +# qhasm: stack64 c3_stack + +# qhasm: int64 d0 + +# qhasm: int64 d1 + +# qhasm: int64 d2 + +# qhasm: int64 d3 + +# qhasm: stack64 d0_stack + +# qhasm: stack64 d1_stack + +# qhasm: stack64 d2_stack + +# qhasm: stack64 d3_stack + +# qhasm: int64 e0 + +# qhasm: int64 e1 + +# qhasm: int64 e2 + +# qhasm: int64 e3 + +# qhasm: stack64 e0_stack + +# qhasm: stack64 e1_stack + +# qhasm: stack64 e2_stack + +# qhasm: stack64 e3_stack + +# qhasm: int64 f0 + +# qhasm: int64 f1 + +# qhasm: int64 f2 + +# qhasm: int64 f3 + +# qhasm: stack64 f0_stack + +# qhasm: stack64 f1_stack + +# qhasm: stack64 f2_stack + +# qhasm: stack64 f3_stack + +# qhasm: int64 g0 + +# qhasm: int64 g1 + +# qhasm: int64 g2 + +# qhasm: int64 g3 + +# qhasm: stack64 g0_stack + +# qhasm: stack64 g1_stack + +# qhasm: stack64 g2_stack + +# qhasm: stack64 g3_stack + +# qhasm: int64 h0 + +# qhasm: int64 h1 + +# qhasm: int64 h2 + +# qhasm: int64 h3 + +# qhasm: stack64 h0_stack + +# qhasm: stack64 h1_stack + +# qhasm: stack64 h2_stack + +# qhasm: stack64 h3_stack + +# qhasm: int64 qt0 + +# qhasm: int64 qt1 + +# qhasm: int64 qt2 + +# qhasm: int64 qt3 + +# qhasm: stack64 qt0_stack + +# qhasm: stack64 qt1_stack + +# qhasm: stack64 qt2_stack + +# qhasm: stack64 qt3_stack + +# qhasm: int64 t10 + +# qhasm: int64 t11 + +# qhasm: int64 t12 + +# qhasm: int64 t13 + +# qhasm: stack64 t10_stack + +# qhasm: stack64 t11_stack + +# qhasm: stack64 t12_stack + +# qhasm: stack64 t13_stack + +# qhasm: int64 t20 + +# qhasm: int64 t21 + +# qhasm: int64 t22 + +# qhasm: int64 t23 + +# qhasm: stack64 t20_stack + +# qhasm: stack64 t21_stack + +# qhasm: stack64 t22_stack + +# qhasm: stack64 t23_stack + +# qhasm: int64 rx0 + +# qhasm: int64 rx1 + +# qhasm: int64 rx2 + +# qhasm: int64 rx3 + +# qhasm: int64 ry0 + +# qhasm: int64 ry1 + +# qhasm: int64 ry2 + +# qhasm: int64 ry3 + +# qhasm: int64 rz0 + +# qhasm: int64 rz1 + +# qhasm: int64 rz2 + +# qhasm: int64 rz3 + +# qhasm: int64 rt0 + +# qhasm: int64 rt1 + +# qhasm: int64 rt2 + +# qhasm: int64 rt3 + +# qhasm: int64 mulr4 + +# qhasm: int64 mulr5 + +# qhasm: int64 mulr6 + +# qhasm: int64 mulr7 + +# qhasm: int64 mulr8 + +# qhasm: int64 mulrax + +# qhasm: int64 mulrdx + +# qhasm: int64 mulx0 + +# qhasm: int64 mulx1 + +# qhasm: int64 mulx2 + +# qhasm: int64 mulx3 + +# qhasm: int64 mulc + +# qhasm: int64 mulzero + +# qhasm: int64 muli38 + +# qhasm: int64 addt0 + +# qhasm: int64 addt1 + +# qhasm: int64 subt0 + +# qhasm: int64 subt1 + +# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1 +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1 +.globl crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1 +_crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1: +crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1: +mov %rsp,%r11 +and $31,%r11 +add $128,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: qp = qp +# asm 1: mov qp=int64#4 +# asm 2: mov qp=%rcx +mov %rdx,%rcx + +# qhasm: a0 = *(uint64 *)(pp + 32) +# asm 1: movq 32(a0=int64#3 +# asm 2: movq 32(a0=%rdx +movq 32(%rsi),%rdx + +# qhasm: a1 = *(uint64 *)(pp + 40) +# asm 1: movq 40(a1=int64#5 +# asm 2: movq 40(a1=%r8 +movq 40(%rsi),%r8 + +# qhasm: a2 = *(uint64 *)(pp + 48) +# asm 1: movq 48(a2=int64#6 +# asm 2: movq 48(a2=%r9 +movq 48(%rsi),%r9 + +# qhasm: a3 = *(uint64 *)(pp + 56) +# asm 1: movq 56(a3=int64#7 +# asm 2: movq 56(a3=%rax +movq 56(%rsi),%rax + +# qhasm: b0 = a0 +# asm 1: mov b0=int64#8 +# asm 2: mov b0=%r10 +mov %rdx,%r10 + +# qhasm: b1 = a1 +# asm 1: mov b1=int64#9 +# asm 2: mov b1=%r11 +mov %r8,%r11 + +# qhasm: b2 = a2 +# asm 1: mov b2=int64#10 +# asm 2: mov b2=%r12 +mov %r9,%r12 + +# qhasm: b3 = a3 +# asm 1: mov b3=int64#11 +# asm 2: mov b3=%r13 +mov %rax,%r13 + +# qhasm: carry? a0 -= *(uint64 *) (pp + 0) +# asm 1: subq 0(subt0=int64#12 +# asm 2: mov $0,>subt0=%r14 +mov $0,%r14 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#13 +# asm 2: mov $38,>subt1=%r15 +mov $38,%r15 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#12 +# asm 2: mov $0,>addt0=%r14 +mov $0,%r14 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#13 +# asm 2: mov $38,>addt1=%r15 +mov $38,%r15 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %rdx,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %r8,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r9,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %rax,80(%rsp) + +# qhasm: b0_stack = b0 +# asm 1: movq b0_stack=stack64#12 +# asm 2: movq b0_stack=88(%rsp) +movq %r10,88(%rsp) + +# qhasm: b1_stack = b1 +# asm 1: movq b1_stack=stack64#13 +# asm 2: movq b1_stack=96(%rsp) +movq %r11,96(%rsp) + +# qhasm: b2_stack = b2 +# asm 1: movq b2_stack=stack64#14 +# asm 2: movq b2_stack=104(%rsp) +movq %r12,104(%rsp) + +# qhasm: b3_stack = b3 +# asm 1: movq b3_stack=stack64#15 +# asm 2: movq b3_stack=112(%rsp) +movq %r13,112(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = a0_stack +# asm 1: movq mulx0=int64#10 +# asm 2: movq mulx0=%r12 +movq 56(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a0=int64#11 +# asm 2: mov a0=%r13 +mov %rax,%r13 + +# qhasm: a1 = mulrdx +# asm 1: mov a1=int64#12 +# asm 2: mov a1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 8) +# asm 1: movq 8(mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a2=int64#13 +# asm 2: mov $0,>a2=%r15 +mov $0,%r15 + +# qhasm: a2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a3=int64#14 +# asm 2: mov $0,>a3=%rbx +mov $0,%rbx + +# qhasm: a3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq mulx1=%r12 +movq 64(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq mulx2=%r12 +movq 72(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq mulx3=%r12 +movq 80(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? a0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: a0 += mulzero +# asm 1: add a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %r13,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %r14,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r15,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %rbx,80(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = b0_stack +# asm 1: movq mulx0=int64#10 +# asm 2: movq mulx0=%r12 +movq 88(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul e0=int64#11 +# asm 2: mov e0=%r13 +mov %rax,%r13 + +# qhasm: e1 = mulrdx +# asm 1: mov e1=int64#12 +# asm 2: mov e1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 40) +# asm 1: movq 40(mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul e2=int64#13 +# asm 2: mov $0,>e2=%r15 +mov $0,%r15 + +# qhasm: e2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul e3=int64#14 +# asm 2: mov $0,>e3=%rbx +mov $0,%rbx + +# qhasm: e3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq mulx1=%r12 +movq 96(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq mulx2=%r12 +movq 104(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq mulx3=%r12 +movq 112(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? e0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: e0 += mulzero +# asm 1: add h0=int64#3 +# asm 2: mov h0=%rdx +mov %r13,%rdx + +# qhasm: h1 = e1 +# asm 1: mov h1=int64#5 +# asm 2: mov h1=%r8 +mov %r14,%r8 + +# qhasm: h2 = e2 +# asm 1: mov h2=int64#6 +# asm 2: mov h2=%r9 +mov %r15,%r9 + +# qhasm: h3 = e3 +# asm 1: mov h3=int64#7 +# asm 2: mov h3=%rax +mov %rbx,%rax + +# qhasm: carry? e0 -= a0_stack +# asm 1: subq subt0=int64#8 +# asm 2: mov $0,>subt0=%r10 +mov $0,%r10 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#9 +# asm 2: mov $38,>subt1=%r11 +mov $38,%r11 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#8 +# asm 2: mov $0,>addt0=%r10 +mov $0,%r10 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#9 +# asm 2: mov $38,>addt1=%r11 +mov $38,%r11 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulx0=int64#10 +# asm 2: movq 96(mulx0=%r12 +movq 96(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c0=int64#11 +# asm 2: mov c0=%r13 +mov %rax,%r13 + +# qhasm: c1 = mulrdx +# asm 1: mov c1=int64#12 +# asm 2: mov c1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 72) +# asm 1: movq 72(mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c2=int64#13 +# asm 2: mov $0,>c2=%r15 +mov $0,%r15 + +# qhasm: c2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c3=int64#14 +# asm 2: mov $0,>c3=%rbx +mov $0,%rbx + +# qhasm: c3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq 104(mulx1=%r12 +movq 104(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq 112(mulx2=%r12 +movq 112(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq 120(mulx3=%r12 +movq 120(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#4 +# asm 2: mov mulr4=%rcx +mov %rax,%rcx + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#5 +# asm 2: mov mulr5=%r8 +mov %rdx,%r8 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#4 +# asm 2: imulq $38,mulr8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? c0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: c0 += mulzero +# asm 1: add f0=int64#3 +# asm 2: movq 64(f0=%rdx +movq 64(%rsi),%rdx + +# qhasm: f1 = *(uint64 *)(pp + 72) +# asm 1: movq 72(f1=int64#4 +# asm 2: movq 72(f1=%rcx +movq 72(%rsi),%rcx + +# qhasm: f2 = *(uint64 *)(pp + 80) +# asm 1: movq 80(f2=int64#5 +# asm 2: movq 80(f2=%r8 +movq 80(%rsi),%r8 + +# qhasm: f3 = *(uint64 *)(pp + 88) +# asm 1: movq 88(f3=int64#2 +# asm 2: movq 88(f3=%rsi +movq 88(%rsi),%rsi + +# qhasm: carry? f0 += f0 +# asm 1: add addt0=int64#6 +# asm 2: mov $0,>addt0=%r9 +mov $0,%r9 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#7 +# asm 2: mov $38,>addt1=%rax +mov $38,%rax + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae g0=int64#6 +# asm 2: mov g0=%r9 +mov %rdx,%r9 + +# qhasm: g1 = f1 +# asm 1: mov g1=int64#7 +# asm 2: mov g1=%rax +mov %rcx,%rax + +# qhasm: g2 = f2 +# asm 1: mov g2=int64#8 +# asm 2: mov g2=%r10 +mov %r8,%r10 + +# qhasm: g3 = f3 +# asm 1: mov g3=int64#9 +# asm 2: mov g3=%r11 +mov %rsi,%r11 + +# qhasm: carry? f0 -= c0 +# asm 1: sub subt0=int64#10 +# asm 2: mov $0,>subt0=%r12 +mov $0,%r12 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#15 +# asm 2: mov $38,>subt1=%rbp +mov $38,%rbp + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#10 +# asm 2: mov $0,>addt0=%r12 +mov $0,%r12 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#11 +# asm 2: mov $38,>addt1=%r13 +mov $38,%r13 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s b/ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s new file mode 100644 index 0000000..beddbc7 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s @@ -0,0 +1,2236 @@ + +# qhasm: int64 rp + +# qhasm: int64 pp + +# qhasm: input rp + +# qhasm: input pp + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 rx0 + +# qhasm: int64 rx1 + +# qhasm: int64 rx2 + +# qhasm: int64 rx3 + +# qhasm: int64 ry0 + +# qhasm: int64 ry1 + +# qhasm: int64 ry2 + +# qhasm: int64 ry3 + +# qhasm: int64 rz0 + +# qhasm: int64 rz1 + +# qhasm: int64 rz2 + +# qhasm: int64 rz3 + +# qhasm: int64 mulr4 + +# qhasm: int64 mulr5 + +# qhasm: int64 mulr6 + +# qhasm: int64 mulr7 + +# qhasm: int64 mulr8 + +# qhasm: int64 mulrax + +# qhasm: int64 mulrdx + +# qhasm: int64 mulx0 + +# qhasm: int64 mulx1 + +# qhasm: int64 mulx2 + +# qhasm: int64 mulx3 + +# qhasm: int64 mulc + +# qhasm: int64 mulzero + +# qhasm: int64 muli38 + +# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2 +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2 +.globl crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2 +_crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2: +crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = *(uint64 *)(pp + 0) +# asm 1: movq 0(mulx0=int64#9 +# asm 2: movq 0(mulx0=%r11 +movq 0(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx0=int64#10 +# asm 2: mov rx0=%r12 +mov %rax,%r12 + +# qhasm: rx1 = mulrdx +# asm 1: mov rx1=int64#11 +# asm 2: mov rx1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(pp + 104) +# asm 1: movq 104(mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx2=int64#12 +# asm 2: mov $0,>rx2=%r14 +mov $0,%r14 + +# qhasm: rx2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx3=int64#13 +# asm 2: mov $0,>rx3=%r15 +mov $0,%r15 + +# qhasm: rx3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq 8(mulx1=%r11 +movq 8(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq 16(mulx2=%r11 +movq 16(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq 24(mulx3=%r11 +movq 24(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#4 +# asm 2: mov mulr4=%rcx +mov %rax,%rcx + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#5 +# asm 2: mov mulr5=%r8 +mov %rdx,%r8 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#4 +# asm 2: imulq $38,mulr8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? rx0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: rx0 += mulzero +# asm 1: add mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = *(uint64 *)(pp + 64) +# asm 1: movq 64(mulx0=int64#9 +# asm 2: movq 64(mulx0=%r11 +movq 64(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry0=int64#10 +# asm 2: mov ry0=%r12 +mov %rax,%r12 + +# qhasm: ry1 = mulrdx +# asm 1: mov ry1=int64#11 +# asm 2: mov ry1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(pp + 40) +# asm 1: movq 40(mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry2=int64#12 +# asm 2: mov $0,>ry2=%r14 +mov $0,%r14 + +# qhasm: ry2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry3=int64#13 +# asm 2: mov $0,>ry3=%r15 +mov $0,%r15 + +# qhasm: ry3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq 72(mulx1=%r11 +movq 72(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq 80(mulx2=%r11 +movq 80(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq 88(mulx3=%r11 +movq 88(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#4 +# asm 2: mov mulr4=%rcx +mov %rax,%rcx + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#5 +# asm 2: mov mulr5=%r8 +mov %rdx,%r8 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#4 +# asm 2: imulq $38,mulr8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? ry0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: ry0 += mulzero +# asm 1: add mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulx0=int64#9 +# asm 2: movq 32(mulx0=%r11 +movq 32(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz0=int64#10 +# asm 2: mov rz0=%r12 +mov %rax,%r12 + +# qhasm: rz1 = mulrdx +# asm 1: mov rz1=int64#11 +# asm 2: mov rz1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(pp + 104) +# asm 1: movq 104(mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz2=int64#12 +# asm 2: mov $0,>rz2=%r14 +mov $0,%r14 + +# qhasm: rz2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz3=int64#13 +# asm 2: mov $0,>rz3=%r15 +mov $0,%r15 + +# qhasm: rz3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq 40(mulx1=%r11 +movq 40(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq 48(mulx2=%r11 +movq 48(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq 56(mulx3=%r11 +movq 56(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? rz0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: rz0 += mulzero +# asm 1: add caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s b/ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s new file mode 100644 index 0000000..82433fb --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s @@ -0,0 +1,2926 @@ + +# qhasm: int64 rp + +# qhasm: int64 pp + +# qhasm: input rp + +# qhasm: input pp + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 rx0 + +# qhasm: int64 rx1 + +# qhasm: int64 rx2 + +# qhasm: int64 rx3 + +# qhasm: int64 ry0 + +# qhasm: int64 ry1 + +# qhasm: int64 ry2 + +# qhasm: int64 ry3 + +# qhasm: int64 rz0 + +# qhasm: int64 rz1 + +# qhasm: int64 rz2 + +# qhasm: int64 rz3 + +# qhasm: int64 rt0 + +# qhasm: int64 rt1 + +# qhasm: int64 rt2 + +# qhasm: int64 rt3 + +# qhasm: int64 mulr4 + +# qhasm: int64 mulr5 + +# qhasm: int64 mulr6 + +# qhasm: int64 mulr7 + +# qhasm: int64 mulr8 + +# qhasm: int64 mulrax + +# qhasm: int64 mulrdx + +# qhasm: int64 mulx0 + +# qhasm: int64 mulx1 + +# qhasm: int64 mulx2 + +# qhasm: int64 mulx3 + +# qhasm: int64 mulc + +# qhasm: int64 mulzero + +# qhasm: int64 muli38 + +# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3 +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3 +.globl crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3 +_crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3: +crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = *(uint64 *)(pp + 0) +# asm 1: movq 0(mulx0=int64#9 +# asm 2: movq 0(mulx0=%r11 +movq 0(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx0=int64#10 +# asm 2: mov rx0=%r12 +mov %rax,%r12 + +# qhasm: rx1 = mulrdx +# asm 1: mov rx1=int64#11 +# asm 2: mov rx1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(pp + 104) +# asm 1: movq 104(mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx2=int64#12 +# asm 2: mov $0,>rx2=%r14 +mov $0,%r14 + +# qhasm: rx2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx3=int64#13 +# asm 2: mov $0,>rx3=%r15 +mov $0,%r15 + +# qhasm: rx3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq 8(mulx1=%r11 +movq 8(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq 16(mulx2=%r11 +movq 16(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq 24(mulx3=%r11 +movq 24(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#4 +# asm 2: mov mulr4=%rcx +mov %rax,%rcx + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#5 +# asm 2: mov mulr5=%r8 +mov %rdx,%r8 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#4 +# asm 2: imulq $38,mulr8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? rx0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: rx0 += mulzero +# asm 1: add mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = *(uint64 *)(pp + 64) +# asm 1: movq 64(mulx0=int64#9 +# asm 2: movq 64(mulx0=%r11 +movq 64(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry0=int64#10 +# asm 2: mov ry0=%r12 +mov %rax,%r12 + +# qhasm: ry1 = mulrdx +# asm 1: mov ry1=int64#11 +# asm 2: mov ry1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(pp + 40) +# asm 1: movq 40(mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry2=int64#12 +# asm 2: mov $0,>ry2=%r14 +mov $0,%r14 + +# qhasm: ry2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul ry3=int64#13 +# asm 2: mov $0,>ry3=%r15 +mov $0,%r15 + +# qhasm: ry3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq 72(mulx1=%r11 +movq 72(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq 80(mulx2=%r11 +movq 80(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq 88(mulx3=%r11 +movq 88(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#4 +# asm 2: mov mulr4=%rcx +mov %rax,%rcx + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#5 +# asm 2: mov mulr5=%r8 +mov %rdx,%r8 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#4 +# asm 2: imulq $38,mulr8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? ry0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: ry0 += mulzero +# asm 1: add mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = *(uint64 *)(pp + 32) +# asm 1: movq 32(mulx0=int64#9 +# asm 2: movq 32(mulx0=%r11 +movq 32(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz0=int64#10 +# asm 2: mov rz0=%r12 +mov %rax,%r12 + +# qhasm: rz1 = mulrdx +# asm 1: mov rz1=int64#11 +# asm 2: mov rz1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(pp + 104) +# asm 1: movq 104(mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz2=int64#12 +# asm 2: mov $0,>rz2=%r14 +mov $0,%r14 + +# qhasm: rz2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rz3=int64#13 +# asm 2: mov $0,>rz3=%r15 +mov $0,%r15 + +# qhasm: rz3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq 40(mulx1=%r11 +movq 40(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq 48(mulx2=%r11 +movq 48(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq 56(mulx3=%r11 +movq 56(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#4 +# asm 2: mov mulr4=%rcx +mov %rax,%rcx + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#5 +# asm 2: mov mulr5=%r8 +mov %rdx,%r8 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#4 +# asm 2: imulq $38,mulr8=%rcx +imulq $38,%rax,%rcx + +# qhasm: carry? rz0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: rz0 += mulzero +# asm 1: add mulr4=int64#4 +# asm 2: mov $0,>mulr4=%rcx +mov $0,%rcx + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#5 +# asm 2: mov $0,>mulr5=%r8 +mov $0,%r8 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#6 +# asm 2: mov $0,>mulr6=%r9 +mov $0,%r9 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#8 +# asm 2: mov $0,>mulr7=%r10 +mov $0,%r10 + +# qhasm: mulx0 = *(uint64 *)(pp + 0) +# asm 1: movq 0(mulx0=int64#9 +# asm 2: movq 0(mulx0=%r11 +movq 0(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt0=int64#10 +# asm 2: mov rt0=%r12 +mov %rax,%r12 + +# qhasm: rt1 = mulrdx +# asm 1: mov rt1=int64#11 +# asm 2: mov rt1=%r13 +mov %rdx,%r13 + +# qhasm: mulrax = *(uint64 *)(pp + 72) +# asm 1: movq 72(mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt2=int64#12 +# asm 2: mov $0,>rt2=%r14 +mov $0,%r14 + +# qhasm: rt2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt3=int64#13 +# asm 2: mov $0,>rt3=%r15 +mov $0,%r15 + +# qhasm: rt3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#9 +# asm 2: movq 8(mulx1=%r11 +movq 8(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#9 +# asm 2: movq 16(mulx2=%r11 +movq 16(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#9 +# asm 2: movq 24(mulx3=%r11 +movq 24(%rsi),%r11 + +# qhasm: mulrax = *(uint64 *)(pp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#14 +# asm 2: mov $0,>mulc=%rbx +mov $0,%rbx + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rsi),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %rcx,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? rt0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: rt0 += mulzero +# asm 1: add caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/ge25519_pack.c b/ext/ed25519-amd64-asm/ge25519_pack.c new file mode 100644 index 0000000..f289fe5 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_pack.c @@ -0,0 +1,13 @@ +#include "fe25519.h" +#include "sc25519.h" +#include "ge25519.h" + +void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) +{ + fe25519 tx, ty, zi; + fe25519_invert(&zi, &p->z); + fe25519_mul(&tx, &p->x, &zi); + fe25519_mul(&ty, &p->y, &zi); + fe25519_pack(r, &ty); + r[31] ^= fe25519_getparity(&tx) << 7; +} diff --git a/ext/ed25519-amd64-asm/ge25519_pnielsadd_p1p1.s b/ext/ed25519-amd64-asm/ge25519_pnielsadd_p1p1.s new file mode 100644 index 0000000..aff2e75 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_pnielsadd_p1p1.s @@ -0,0 +1,3662 @@ + +# qhasm: int64 rp + +# qhasm: int64 pp + +# qhasm: int64 qp + +# qhasm: input rp + +# qhasm: input pp + +# qhasm: input qp + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 a0 + +# qhasm: int64 a1 + +# qhasm: int64 a2 + +# qhasm: int64 a3 + +# qhasm: stack64 a0_stack + +# qhasm: stack64 a1_stack + +# qhasm: stack64 a2_stack + +# qhasm: stack64 a3_stack + +# qhasm: int64 b0 + +# qhasm: int64 b1 + +# qhasm: int64 b2 + +# qhasm: int64 b3 + +# qhasm: stack64 b0_stack + +# qhasm: stack64 b1_stack + +# qhasm: stack64 b2_stack + +# qhasm: stack64 b3_stack + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: stack64 c0_stack + +# qhasm: stack64 c1_stack + +# qhasm: stack64 c2_stack + +# qhasm: stack64 c3_stack + +# qhasm: int64 d0 + +# qhasm: int64 d1 + +# qhasm: int64 d2 + +# qhasm: int64 d3 + +# qhasm: stack64 d0_stack + +# qhasm: stack64 d1_stack + +# qhasm: stack64 d2_stack + +# qhasm: stack64 d3_stack + +# qhasm: int64 t10 + +# qhasm: int64 t11 + +# qhasm: int64 t12 + +# qhasm: int64 t13 + +# qhasm: stack64 t10_stack + +# qhasm: stack64 t11_stack + +# qhasm: stack64 t12_stack + +# qhasm: stack64 t13_stack + +# qhasm: int64 t20 + +# qhasm: int64 t21 + +# qhasm: int64 t22 + +# qhasm: int64 t23 + +# qhasm: stack64 t20_stack + +# qhasm: stack64 t21_stack + +# qhasm: stack64 t22_stack + +# qhasm: stack64 t23_stack + +# qhasm: int64 rx0 + +# qhasm: int64 rx1 + +# qhasm: int64 rx2 + +# qhasm: int64 rx3 + +# qhasm: int64 ry0 + +# qhasm: int64 ry1 + +# qhasm: int64 ry2 + +# qhasm: int64 ry3 + +# qhasm: int64 rz0 + +# qhasm: int64 rz1 + +# qhasm: int64 rz2 + +# qhasm: int64 rz3 + +# qhasm: int64 rt0 + +# qhasm: int64 rt1 + +# qhasm: int64 rt2 + +# qhasm: int64 rt3 + +# qhasm: int64 x0 + +# qhasm: int64 x1 + +# qhasm: int64 x2 + +# qhasm: int64 x3 + +# qhasm: int64 mulr4 + +# qhasm: int64 mulr5 + +# qhasm: int64 mulr6 + +# qhasm: int64 mulr7 + +# qhasm: int64 mulr8 + +# qhasm: int64 mulrax + +# qhasm: int64 mulrdx + +# qhasm: int64 mulx0 + +# qhasm: int64 mulx1 + +# qhasm: int64 mulx2 + +# qhasm: int64 mulx3 + +# qhasm: int64 mulc + +# qhasm: int64 mulzero + +# qhasm: int64 muli38 + +# qhasm: int64 addt0 + +# qhasm: int64 addt1 + +# qhasm: int64 subt0 + +# qhasm: int64 subt1 + +# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1 +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1 +.globl crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1 +_crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1: +crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1: +mov %rsp,%r11 +and $31,%r11 +add $128,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: qp = qp +# asm 1: mov qp=int64#4 +# asm 2: mov qp=%rcx +mov %rdx,%rcx + +# qhasm: a0 = *(uint64 *)(pp + 32) +# asm 1: movq 32(a0=int64#3 +# asm 2: movq 32(a0=%rdx +movq 32(%rsi),%rdx + +# qhasm: a1 = *(uint64 *)(pp + 40) +# asm 1: movq 40(a1=int64#5 +# asm 2: movq 40(a1=%r8 +movq 40(%rsi),%r8 + +# qhasm: a2 = *(uint64 *)(pp + 48) +# asm 1: movq 48(a2=int64#6 +# asm 2: movq 48(a2=%r9 +movq 48(%rsi),%r9 + +# qhasm: a3 = *(uint64 *)(pp + 56) +# asm 1: movq 56(a3=int64#7 +# asm 2: movq 56(a3=%rax +movq 56(%rsi),%rax + +# qhasm: b0 = a0 +# asm 1: mov b0=int64#8 +# asm 2: mov b0=%r10 +mov %rdx,%r10 + +# qhasm: b1 = a1 +# asm 1: mov b1=int64#9 +# asm 2: mov b1=%r11 +mov %r8,%r11 + +# qhasm: b2 = a2 +# asm 1: mov b2=int64#10 +# asm 2: mov b2=%r12 +mov %r9,%r12 + +# qhasm: b3 = a3 +# asm 1: mov b3=int64#11 +# asm 2: mov b3=%r13 +mov %rax,%r13 + +# qhasm: carry? a0 -= *(uint64 *)(pp + 0) +# asm 1: subq 0(subt0=int64#12 +# asm 2: mov $0,>subt0=%r14 +mov $0,%r14 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#13 +# asm 2: mov $38,>subt1=%r15 +mov $38,%r15 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae addt0=int64#12 +# asm 2: mov $0,>addt0=%r14 +mov $0,%r14 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#13 +# asm 2: mov $38,>addt1=%r15 +mov $38,%r15 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %rdx,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %r8,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r9,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %rax,80(%rsp) + +# qhasm: b0_stack = b0 +# asm 1: movq b0_stack=stack64#12 +# asm 2: movq b0_stack=88(%rsp) +movq %r10,88(%rsp) + +# qhasm: b1_stack = b1 +# asm 1: movq b1_stack=stack64#13 +# asm 2: movq b1_stack=96(%rsp) +movq %r11,96(%rsp) + +# qhasm: b2_stack = b2 +# asm 1: movq b2_stack=stack64#14 +# asm 2: movq b2_stack=104(%rsp) +movq %r12,104(%rsp) + +# qhasm: b3_stack = b3 +# asm 1: movq b3_stack=stack64#15 +# asm 2: movq b3_stack=112(%rsp) +movq %r13,112(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = a0_stack +# asm 1: movq mulx0=int64#10 +# asm 2: movq mulx0=%r12 +movq 56(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a0=int64#11 +# asm 2: mov a0=%r13 +mov %rax,%r13 + +# qhasm: a1 = mulrdx +# asm 1: mov a1=int64#12 +# asm 2: mov a1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 8) +# asm 1: movq 8(mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a2=int64#13 +# asm 2: mov $0,>a2=%r15 +mov $0,%r15 + +# qhasm: a2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul a3=int64#14 +# asm 2: mov $0,>a3=%rbx +mov $0,%rbx + +# qhasm: a3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq mulx1=%r12 +movq 64(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq mulx2=%r12 +movq 72(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq mulx3=%r12 +movq 80(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 0) +# asm 1: movq 0(mulrax=int64#7 +# asm 2: movq 0(mulrax=%rax +movq 0(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 8(mulrax=%rax +movq 8(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 16(mulrax=%rax +movq 16(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 24(mulrax=%rax +movq 24(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? a0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: a0 += mulzero +# asm 1: add a0_stack=stack64#8 +# asm 2: movq a0_stack=56(%rsp) +movq %r13,56(%rsp) + +# qhasm: a1_stack = a1 +# asm 1: movq a1_stack=stack64#9 +# asm 2: movq a1_stack=64(%rsp) +movq %r14,64(%rsp) + +# qhasm: a2_stack = a2 +# asm 1: movq a2_stack=stack64#10 +# asm 2: movq a2_stack=72(%rsp) +movq %r15,72(%rsp) + +# qhasm: a3_stack = a3 +# asm 1: movq a3_stack=stack64#11 +# asm 2: movq a3_stack=80(%rsp) +movq %rbx,80(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = b0_stack +# asm 1: movq mulx0=int64#10 +# asm 2: movq mulx0=%r12 +movq 88(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx0=int64#11 +# asm 2: mov rx0=%r13 +mov %rax,%r13 + +# qhasm: rx1 = mulrdx +# asm 1: mov rx1=int64#12 +# asm 2: mov rx1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 40) +# asm 1: movq 40(mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx2=int64#13 +# asm 2: mov $0,>rx2=%r15 +mov $0,%r15 + +# qhasm: rx2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rx3=int64#14 +# asm 2: mov $0,>rx3=%rbx +mov $0,%rbx + +# qhasm: rx3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq mulx1=%r12 +movq 96(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq mulx2=%r12 +movq 104(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq mulx3=%r12 +movq 112(%rsp),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 32) +# asm 1: movq 32(mulrax=int64#7 +# asm 2: movq 32(mulrax=%rax +movq 32(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 40(mulrax=%rax +movq 40(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 48(mulrax=%rax +movq 48(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 56(mulrax=%rax +movq 56(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? rx0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: rx0 += mulzero +# asm 1: add ry0=int64#3 +# asm 2: mov ry0=%rdx +mov %r13,%rdx + +# qhasm: ry1 = rx1 +# asm 1: mov ry1=int64#5 +# asm 2: mov ry1=%r8 +mov %r14,%r8 + +# qhasm: ry2 = rx2 +# asm 1: mov ry2=int64#6 +# asm 2: mov ry2=%r9 +mov %r15,%r9 + +# qhasm: ry3 = rx3 +# asm 1: mov ry3=int64#7 +# asm 2: mov ry3=%rax +mov %rbx,%rax + +# qhasm: carry? ry0 += a0_stack +# asm 1: addq addt0=int64#8 +# asm 2: mov $0,>addt0=%r10 +mov $0,%r10 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#9 +# asm 2: mov $38,>addt1=%r11 +mov $38,%r11 + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae subt0=int64#8 +# asm 2: mov $0,>subt0=%r10 +mov $0,%r10 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#9 +# asm 2: mov $38,>subt1=%r11 +mov $38,%r11 + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = *(uint64 *)(pp + 96) +# asm 1: movq 96(mulx0=int64#10 +# asm 2: movq 96(mulx0=%r12 +movq 96(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c0=int64#11 +# asm 2: mov c0=%r13 +mov %rax,%r13 + +# qhasm: c1 = mulrdx +# asm 1: mov c1=int64#12 +# asm 2: mov c1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 104) +# asm 1: movq 104(mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c2=int64#13 +# asm 2: mov $0,>c2=%r15 +mov $0,%r15 + +# qhasm: c2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul c3=int64#14 +# asm 2: mov $0,>c3=%rbx +mov $0,%rbx + +# qhasm: c3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq 104(mulx1=%r12 +movq 104(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq 112(mulx2=%r12 +movq 112(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#10 +# asm 2: movq 120(mulx3=%r12 +movq 120(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 96) +# asm 1: movq 96(mulrax=int64#7 +# asm 2: movq 96(mulrax=%rax +movq 96(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 104(mulrax=%rax +movq 104(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 112(mulrax=%rax +movq 112(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 120(mulrax=%rax +movq 120(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#5 +# asm 2: mov mulr4=%r8 +mov %rax,%r8 + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#6 +# asm 2: mov mulr5=%r9 +mov %rdx,%r9 + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#3 +# asm 2: mov $0,>mulzero=%rdx +mov $0,%rdx + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#5 +# asm 2: imulq $38,mulr8=%r8 +imulq $38,%rax,%r8 + +# qhasm: carry? c0 += mulr8 +# asm 1: add mulzero=int64#3 +# asm 2: imulq $38,mulzero=%rdx +imulq $38,%rdx,%rdx + +# qhasm: c0 += mulzero +# asm 1: add c0_stack=stack64#8 +# asm 2: movq c0_stack=56(%rsp) +movq %r13,56(%rsp) + +# qhasm: c1_stack = c1 +# asm 1: movq c1_stack=stack64#9 +# asm 2: movq c1_stack=64(%rsp) +movq %r14,64(%rsp) + +# qhasm: c2_stack = c2 +# asm 1: movq c2_stack=stack64#10 +# asm 2: movq c2_stack=72(%rsp) +movq %r15,72(%rsp) + +# qhasm: c3_stack = c3 +# asm 1: movq c3_stack=stack64#11 +# asm 2: movq c3_stack=80(%rsp) +movq %rbx,80(%rsp) + +# qhasm: mulr4 = 0 +# asm 1: mov $0,>mulr4=int64#5 +# asm 2: mov $0,>mulr4=%r8 +mov $0,%r8 + +# qhasm: mulr5 = 0 +# asm 1: mov $0,>mulr5=int64#6 +# asm 2: mov $0,>mulr5=%r9 +mov $0,%r9 + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#8 +# asm 2: mov $0,>mulr6=%r10 +mov $0,%r10 + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#9 +# asm 2: mov $0,>mulr7=%r11 +mov $0,%r11 + +# qhasm: mulx0 = *(uint64 *)(pp + 64) +# asm 1: movq 64(mulx0=int64#10 +# asm 2: movq 64(mulx0=%r12 +movq 64(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt0=int64#11 +# asm 2: mov rt0=%r13 +mov %rax,%r13 + +# qhasm: rt1 = mulrdx +# asm 1: mov rt1=int64#12 +# asm 2: mov rt1=%r14 +mov %rdx,%r14 + +# qhasm: mulrax = *(uint64 *)(qp + 72) +# asm 1: movq 72(mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt2=int64#13 +# asm 2: mov $0,>rt2=%r15 +mov $0,%r15 + +# qhasm: rt2 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul rt3=int64#14 +# asm 2: mov $0,>rt3=%rbx +mov $0,%rbx + +# qhasm: rt3 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 +# asm 1: mul mulx1=int64#10 +# asm 2: movq 72(mulx1=%r12 +movq 72(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 +# asm 1: mul mulx2=int64#10 +# asm 2: movq 80(mulx2=%r12 +movq 80(%rsi),%r12 + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulc=int64#15 +# asm 2: mov $0,>mulc=%rbp +mov $0,%rbp + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 +# asm 1: mul mulx3=int64#2 +# asm 2: movq 88(mulx3=%rsi +movq 88(%rsi),%rsi + +# qhasm: mulrax = *(uint64 *)(qp + 64) +# asm 1: movq 64(mulrax=int64#7 +# asm 2: movq 64(mulrax=%rax +movq 64(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 72(mulrax=%rax +movq 72(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 80(mulrax=%rax +movq 80(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulc=int64#10 +# asm 2: mov $0,>mulc=%r12 +mov $0,%r12 + +# qhasm: mulc += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: movq 88(mulrax=%rax +movq 88(%rcx),%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 +# asm 1: mul mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r8,%rax + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: mulr4 = mulrax +# asm 1: mov mulr4=int64#2 +# asm 2: mov mulr4=%rsi +mov %rax,%rsi + +# qhasm: mulrax = mulr5 +# asm 1: mov mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r9,%rax + +# qhasm: mulr5 = mulrdx +# asm 1: mov mulr5=int64#4 +# asm 2: mov mulr5=%rcx +mov %rdx,%rcx + +# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 +mulq crypto_sign_ed25519_amd64_64_38(%rip) + +# qhasm: carry? mulr5 += mulrax +# asm 1: add mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r10,%rax + +# qhasm: mulr6 = 0 +# asm 1: mov $0,>mulr6=int64#5 +# asm 2: mov $0,>mulr6=%r8 +mov $0,%r8 + +# qhasm: mulr6 += mulrdx + carry +# asm 1: adc mulrax=int64#7 +# asm 2: mov mulrax=%rax +mov %r11,%rax + +# qhasm: mulr7 = 0 +# asm 1: mov $0,>mulr7=int64#6 +# asm 2: mov $0,>mulr7=%r9 +mov $0,%r9 + +# qhasm: mulr7 += mulrdx + carry +# asm 1: adc mulr8=int64#7 +# asm 2: mov $0,>mulr8=%rax +mov $0,%rax + +# qhasm: mulr8 += mulrdx + carry +# asm 1: adc mulzero=int64#2 +# asm 2: mov $0,>mulzero=%rsi +mov $0,%rsi + +# qhasm: mulr8 += mulzero + carry +# asm 1: adc mulr8=int64#3 +# asm 2: imulq $38,mulr8=%rdx +imulq $38,%rax,%rdx + +# qhasm: carry? rt0 += mulr8 +# asm 1: add mulzero=int64#2 +# asm 2: imulq $38,mulzero=%rsi +imulq $38,%rsi,%rsi + +# qhasm: rt0 += mulzero +# asm 1: add addt0=int64#2 +# asm 2: mov $0,>addt0=%rsi +mov $0,%rsi + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#3 +# asm 2: mov $38,>addt1=%rdx +mov $38,%rdx + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae rz0=int64#2 +# asm 2: mov rz0=%rsi +mov %r13,%rsi + +# qhasm: rz1 = rt1 +# asm 1: mov rz1=int64#3 +# asm 2: mov rz1=%rdx +mov %r14,%rdx + +# qhasm: rz2 = rt2 +# asm 1: mov rz2=int64#4 +# asm 2: mov rz2=%rcx +mov %r15,%rcx + +# qhasm: rz3 = rt3 +# asm 1: mov rz3=int64#5 +# asm 2: mov rz3=%r8 +mov %rbx,%r8 + +# qhasm: carry? rz0 += c0_stack +# asm 1: addq addt0=int64#6 +# asm 2: mov $0,>addt0=%r9 +mov $0,%r9 + +# qhasm: addt1 = 38 +# asm 1: mov $38,>addt1=int64#7 +# asm 2: mov $38,>addt1=%rax +mov $38,%rax + +# qhasm: addt1 = addt0 if !carry +# asm 1: cmovae subt0=int64#6 +# asm 2: mov $0,>subt0=%r9 +mov $0,%r9 + +# qhasm: subt1 = 38 +# asm 1: mov $38,>subt1=int64#7 +# asm 2: mov $38,>subt1=%rax +mov $38,%rax + +# qhasm: subt1 = subt0 if !carry +# asm 1: cmovae caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/ge25519_scalarmult_base.c b/ext/ed25519-amd64-asm/ge25519_scalarmult_base.c new file mode 100644 index 0000000..ffa6e2f --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_scalarmult_base.c @@ -0,0 +1,68 @@ +#include "fe25519.h" +#include "sc25519.h" +#include "ge25519.h" + +/* Multiples of the base point in Niels' representation */ +static const ge25519_niels ge25519_base_multiples_niels[] = { +#ifdef SMALLTABLES +#include "ge25519_base_niels_smalltables.data" +#else +#include "ge25519_base_niels.data" +#endif +}; + +/* d */ +/*static const fe25519 ecd = {{0x75EB4DCA135978A3, 0x00700A4D4141D8AB, 0x8CC740797779E898, 0x52036CEE2B6FFE73}};*/ + +void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s) +{ + signed char b[64]; + int i; + ge25519_niels t; + fe25519 d; + + sc25519_window4(b,s); + +#ifdef SMALLTABLES + ge25519_p1p1 tp1p1; + choose_t((ge25519_niels *)r, 0, (signed long long) b[1], ge25519_base_multiples_niels); + fe25519_sub(&d, &r->y, &r->x); + fe25519_add(&r->y, &r->y, &r->x); + r->x = d; + r->t = r->z; + fe25519_setint(&r->z,2); + for(i=3;i<64;i+=2) + { + choose_t(&t, (unsigned long long) i/2, (signed long long) b[i], ge25519_base_multiples_niels); + ge25519_nielsadd2(r, &t); + } + ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)r); + ge25519_p1p1_to_p2((ge25519_p2 *)r, &tp1p1); + ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)r); + ge25519_p1p1_to_p2((ge25519_p2 *)r, &tp1p1); + ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)r); + ge25519_p1p1_to_p2((ge25519_p2 *)r, &tp1p1); + ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)r); + ge25519_p1p1_to_p3(r, &tp1p1); + choose_t(&t, (unsigned long long) 0, (signed long long) b[0], ge25519_base_multiples_niels); + fe25519_mul(&t.t2d, &t.t2d, &ecd); + ge25519_nielsadd2(r, &t); + for(i=2;i<64;i+=2) + { + choose_t(&t, (unsigned long long) i/2, (signed long long) b[i], ge25519_base_multiples_niels); + ge25519_nielsadd2(r, &t); + } +#else + choose_t((ge25519_niels *)r, 0, (signed long long) b[0], ge25519_base_multiples_niels); + fe25519_sub(&d, &r->y, &r->x); + fe25519_add(&r->y, &r->y, &r->x); + r->x = d; + r->t = r->z; + fe25519_setint(&r->z,2); + for(i=1;i<64;i++) + { + choose_t(&t, (unsigned long long) i, (signed long long) b[i], ge25519_base_multiples_niels); + ge25519_nielsadd2(r, &t); + } +#endif +} diff --git a/ext/ed25519-amd64-asm/ge25519_unpackneg.c b/ext/ed25519-amd64-asm/ge25519_unpackneg.c new file mode 100644 index 0000000..ff16fd2 --- /dev/null +++ b/ext/ed25519-amd64-asm/ge25519_unpackneg.c @@ -0,0 +1,60 @@ +#include "fe25519.h" +#include "ge25519.h" + +/* d */ +static const fe25519 ecd = {{0x75EB4DCA135978A3, 0x00700A4D4141D8AB, 0x8CC740797779E898, 0x52036CEE2B6FFE73}}; +/* sqrt(-1) */ +static const fe25519 sqrtm1 = {{0xC4EE1B274A0EA0B0, 0x2F431806AD2FE478, 0x2B4D00993DFBD7A7, 0x2B8324804FC1DF0B}}; + +/* return 0 on success, -1 otherwise */ +int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32]) +{ + fe25519 t, chk, num, den, den2, den4, den6; + unsigned char par = p[31] >> 7; + + fe25519_setint(&r->z,1); + fe25519_unpack(&r->y, p); + fe25519_square(&num, &r->y); /* x = y^2 */ + fe25519_mul(&den, &num, &ecd); /* den = dy^2 */ + fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */ + fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */ + + /* Computation of sqrt(num/den) + 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) + */ + fe25519_square(&den2, &den); + fe25519_square(&den4, &den2); + fe25519_mul(&den6, &den4, &den2); + fe25519_mul(&t, &den6, &num); + fe25519_mul(&t, &t, &den); + + fe25519_pow2523(&t, &t); + /* 2. computation of r->x = t * num * den^3 + */ + fe25519_mul(&t, &t, &num); + fe25519_mul(&t, &t, &den); + fe25519_mul(&t, &t, &den); + fe25519_mul(&r->x, &t, &den); + + /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: + */ + fe25519_square(&chk, &r->x); + fe25519_mul(&chk, &chk, &den); + if (!fe25519_iseq_vartime(&chk, &num)) + fe25519_mul(&r->x, &r->x, &sqrtm1); + + /* 4. Now we have one of the two square roots, except if input was not a square + */ + fe25519_square(&chk, &r->x); + fe25519_mul(&chk, &chk, &den); + if (!fe25519_iseq_vartime(&chk, &num)) + return -1; + + /* 5. Choose the desired square root according to parity: + */ + if(fe25519_getparity(&r->x) != (1-par)) + fe25519_neg(&r->x, &r->x); + + fe25519_mul(&r->t, &r->x, &r->y); + return 0; +} diff --git a/ext/ed25519-amd64-asm/heap_rootreplaced.s b/ext/ed25519-amd64-asm/heap_rootreplaced.s new file mode 100644 index 0000000..8fe385b --- /dev/null +++ b/ext/ed25519-amd64-asm/heap_rootreplaced.s @@ -0,0 +1,476 @@ + +# qhasm: int64 hp + +# qhasm: int64 hlen + +# qhasm: int64 sp + +# qhasm: int64 pp + +# qhasm: input hp + +# qhasm: input hlen + +# qhasm: input sp + +# qhasm: int64 prc + +# qhasm: int64 plc + +# qhasm: int64 pc + +# qhasm: int64 d + +# qhasm: int64 spp + +# qhasm: int64 sprc + +# qhasm: int64 spc + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: int64 t0 + +# qhasm: int64 t1 + +# qhasm: int64 t2 + +# qhasm: int64 t3 + +# qhasm: int64 p0 + +# qhasm: int64 p1 + +# qhasm: int64 p2 + +# qhasm: int64 p3 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_heap_rootreplaced +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_heap_rootreplaced +.globl crypto_sign_ed25519_amd64_64_heap_rootreplaced +_crypto_sign_ed25519_amd64_64_heap_rootreplaced: +crypto_sign_ed25519_amd64_64_heap_rootreplaced: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: pp = 0 +# asm 1: mov $0,>pp=int64#4 +# asm 2: mov $0,>pp=%rcx +mov $0,%rcx + +# qhasm: siftdownloop: +._siftdownloop: + +# qhasm: prc = pp +# asm 1: mov prc=int64#5 +# asm 2: mov prc=%r8 +mov %rcx,%r8 + +# qhasm: prc *= 2 +# asm 1: imulq $2,prc=int64#5 +# asm 2: imulq $2,prc=%r8 +imulq $2,%r8,%r8 + +# qhasm: pc = prc +# asm 1: mov pc=int64#6 +# asm 2: mov pc=%r9 +mov %r8,%r9 + +# qhasm: prc += 2 +# asm 1: add $2,? hlen - prc +# asm 1: cmp +jbe ._siftuploop + +# qhasm: sprc = *(uint64 *)(hp + prc * 8) +# asm 1: movq (sprc=int64#7 +# asm 2: movq (sprc=%rax +movq (%rdi,%r8,8),%rax + +# qhasm: sprc <<= 5 +# asm 1: shl $5,spc=int64#8 +# asm 2: movq (spc=%r10 +movq (%rdi,%r9,8),%r10 + +# qhasm: spc <<= 5 +# asm 1: shl $5,c0=int64#9 +# asm 2: movq 0(c0=%r11 +movq 0(%r10),%r11 + +# qhasm: c1 = *(uint64 *)(spc + 8) +# asm 1: movq 8(c1=int64#10 +# asm 2: movq 8(c1=%r12 +movq 8(%r10),%r12 + +# qhasm: c2 = *(uint64 *)(spc + 16) +# asm 1: movq 16(c2=int64#11 +# asm 2: movq 16(c2=%r13 +movq 16(%r10),%r13 + +# qhasm: c3 = *(uint64 *)(spc + 24) +# asm 1: movq 24(c3=int64#12 +# asm 2: movq 24(c3=%r14 +movq 24(%r10),%r14 + +# qhasm: carry? c0 -= *(uint64 *)(sprc + 0) +# asm 1: subq 0(>= 5 +# asm 1: shr $5,spp=int64#5 +# asm 2: movq (spp=%r8 +movq (%rdi,%rcx,8),%r8 + +# qhasm: *(uint64 *)(hp + pp * 8) = spc +# asm 1: movq pp=int64#4 +# asm 2: mov pp=%rcx +mov %r9,%rcx +# comment:fp stack unchanged by jump + +# qhasm: goto siftdownloop +jmp ._siftdownloop + +# qhasm: siftuploop: +._siftuploop: + +# qhasm: pc = pp +# asm 1: mov pc=int64#2 +# asm 2: mov pc=%rsi +mov %rcx,%rsi + +# qhasm: pp -= 1 +# asm 1: sub $1,>= 1 +# asm 1: shr $1,? pc - 0 +# asm 1: cmp $0, +jbe ._end + +# qhasm: spp = *(uint64 *)(hp + pp * 8) +# asm 1: movq (spp=int64#5 +# asm 2: movq (spp=%r8 +movq (%rdi,%rcx,8),%r8 + +# qhasm: spc = *(uint64 *)(hp + pc * 8) +# asm 1: movq (spc=int64#6 +# asm 2: movq (spc=%r9 +movq (%rdi,%rsi,8),%r9 + +# qhasm: spp <<= 5 +# asm 1: shl $5,c0=int64#7 +# asm 2: movq 0(c0=%rax +movq 0(%r9),%rax + +# qhasm: c1 = *(uint64 *)(spc + 8) +# asm 1: movq 8(c1=int64#8 +# asm 2: movq 8(c1=%r10 +movq 8(%r9),%r10 + +# qhasm: c2 = *(uint64 *)(spc + 16) +# asm 1: movq 16(c2=int64#9 +# asm 2: movq 16(c2=%r11 +movq 16(%r9),%r11 + +# qhasm: c3 = *(uint64 *)(spc + 24) +# asm 1: movq 24(c3=int64#10 +# asm 2: movq 24(c3=%r12 +movq 24(%r9),%r12 + +# qhasm: carry? c0 -= *(uint64 *)(spp + 0) +# asm 1: subq 0(>= 5 +# asm 1: shr $5,>= 5 +# asm 1: shr $5,caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/heap_rootreplaced_1limb.s b/ext/ed25519-amd64-asm/heap_rootreplaced_1limb.s new file mode 100644 index 0000000..488e9c5 --- /dev/null +++ b/ext/ed25519-amd64-asm/heap_rootreplaced_1limb.s @@ -0,0 +1,416 @@ + +# qhasm: int64 hp + +# qhasm: int64 hlen + +# qhasm: int64 sp + +# qhasm: int64 pp + +# qhasm: input hp + +# qhasm: input hlen + +# qhasm: input sp + +# qhasm: int64 prc + +# qhasm: int64 plc + +# qhasm: int64 pc + +# qhasm: int64 d + +# qhasm: int64 spp + +# qhasm: int64 sprc + +# qhasm: int64 spc + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: int64 t0 + +# qhasm: int64 t1 + +# qhasm: int64 t2 + +# qhasm: int64 t3 + +# qhasm: int64 p0 + +# qhasm: int64 p1 + +# qhasm: int64 p2 + +# qhasm: int64 p3 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb +.globl crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb +_crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb: +crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: pp = 0 +# asm 1: mov $0,>pp=int64#4 +# asm 2: mov $0,>pp=%rcx +mov $0,%rcx + +# qhasm: siftdownloop: +._siftdownloop: + +# qhasm: prc = pp +# asm 1: mov prc=int64#5 +# asm 2: mov prc=%r8 +mov %rcx,%r8 + +# qhasm: prc *= 2 +# asm 1: imulq $2,prc=int64#5 +# asm 2: imulq $2,prc=%r8 +imulq $2,%r8,%r8 + +# qhasm: pc = prc +# asm 1: mov pc=int64#6 +# asm 2: mov pc=%r9 +mov %r8,%r9 + +# qhasm: prc += 2 +# asm 1: add $2,? hlen - prc +# asm 1: cmp +jbe ._siftuploop + +# qhasm: sprc = *(uint64 *)(hp + prc * 8) +# asm 1: movq (sprc=int64#7 +# asm 2: movq (sprc=%rax +movq (%rdi,%r8,8),%rax + +# qhasm: sprc <<= 5 +# asm 1: shl $5,spc=int64#8 +# asm 2: movq (spc=%r10 +movq (%rdi,%r9,8),%r10 + +# qhasm: spc <<= 5 +# asm 1: shl $5,c0=int64#9 +# asm 2: movq 0(c0=%r11 +movq 0(%r10),%r11 + +# qhasm: carry? c0 -= *(uint64 *)(sprc + 0) +# asm 1: subq 0(>= 5 +# asm 1: shr $5,spp=int64#5 +# asm 2: movq (spp=%r8 +movq (%rdi,%rcx,8),%r8 + +# qhasm: *(uint64 *)(hp + pp * 8) = spc +# asm 1: movq pp=int64#4 +# asm 2: mov pp=%rcx +mov %r9,%rcx +# comment:fp stack unchanged by jump + +# qhasm: goto siftdownloop +jmp ._siftdownloop + +# qhasm: siftuploop: +._siftuploop: + +# qhasm: pc = pp +# asm 1: mov pc=int64#2 +# asm 2: mov pc=%rsi +mov %rcx,%rsi + +# qhasm: pp -= 1 +# asm 1: sub $1,>= 1 +# asm 1: shr $1,? pc - 0 +# asm 1: cmp $0, +jbe ._end + +# qhasm: spp = *(uint64 *)(hp + pp * 8) +# asm 1: movq (spp=int64#5 +# asm 2: movq (spp=%r8 +movq (%rdi,%rcx,8),%r8 + +# qhasm: spc = *(uint64 *)(hp + pc * 8) +# asm 1: movq (spc=int64#6 +# asm 2: movq (spc=%r9 +movq (%rdi,%rsi,8),%r9 + +# qhasm: spp <<= 5 +# asm 1: shl $5,c0=int64#7 +# asm 2: movq 0(c0=%rax +movq 0(%r9),%rax + +# qhasm: carry? c0 -= *(uint64 *)(spp + 0) +# asm 1: subq 0(>= 5 +# asm 1: shr $5,>= 5 +# asm 1: shr $5,caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/heap_rootreplaced_2limbs.s b/ext/ed25519-amd64-asm/heap_rootreplaced_2limbs.s new file mode 100644 index 0000000..f925918 --- /dev/null +++ b/ext/ed25519-amd64-asm/heap_rootreplaced_2limbs.s @@ -0,0 +1,436 @@ + +# qhasm: int64 hp + +# qhasm: int64 hlen + +# qhasm: int64 sp + +# qhasm: int64 pp + +# qhasm: input hp + +# qhasm: input hlen + +# qhasm: input sp + +# qhasm: int64 prc + +# qhasm: int64 plc + +# qhasm: int64 pc + +# qhasm: int64 d + +# qhasm: int64 spp + +# qhasm: int64 sprc + +# qhasm: int64 spc + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: int64 t0 + +# qhasm: int64 t1 + +# qhasm: int64 t2 + +# qhasm: int64 t3 + +# qhasm: int64 p0 + +# qhasm: int64 p1 + +# qhasm: int64 p2 + +# qhasm: int64 p3 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs +.globl crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs +_crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs: +crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: pp = 0 +# asm 1: mov $0,>pp=int64#4 +# asm 2: mov $0,>pp=%rcx +mov $0,%rcx + +# qhasm: siftdownloop: +._siftdownloop: + +# qhasm: prc = pp +# asm 1: mov prc=int64#5 +# asm 2: mov prc=%r8 +mov %rcx,%r8 + +# qhasm: prc *= 2 +# asm 1: imulq $2,prc=int64#5 +# asm 2: imulq $2,prc=%r8 +imulq $2,%r8,%r8 + +# qhasm: pc = prc +# asm 1: mov pc=int64#6 +# asm 2: mov pc=%r9 +mov %r8,%r9 + +# qhasm: prc += 2 +# asm 1: add $2,? hlen - prc +# asm 1: cmp +jbe ._siftuploop + +# qhasm: sprc = *(uint64 *)(hp + prc * 8) +# asm 1: movq (sprc=int64#7 +# asm 2: movq (sprc=%rax +movq (%rdi,%r8,8),%rax + +# qhasm: sprc <<= 5 +# asm 1: shl $5,spc=int64#8 +# asm 2: movq (spc=%r10 +movq (%rdi,%r9,8),%r10 + +# qhasm: spc <<= 5 +# asm 1: shl $5,c0=int64#9 +# asm 2: movq 0(c0=%r11 +movq 0(%r10),%r11 + +# qhasm: c1 = *(uint64 *)(spc + 8) +# asm 1: movq 8(c1=int64#10 +# asm 2: movq 8(c1=%r12 +movq 8(%r10),%r12 + +# qhasm: carry? c0 -= *(uint64 *)(sprc + 0) +# asm 1: subq 0(>= 5 +# asm 1: shr $5,spp=int64#5 +# asm 2: movq (spp=%r8 +movq (%rdi,%rcx,8),%r8 + +# qhasm: *(uint64 *)(hp + pp * 8) = spc +# asm 1: movq pp=int64#4 +# asm 2: mov pp=%rcx +mov %r9,%rcx +# comment:fp stack unchanged by jump + +# qhasm: goto siftdownloop +jmp ._siftdownloop + +# qhasm: siftuploop: +._siftuploop: + +# qhasm: pc = pp +# asm 1: mov pc=int64#2 +# asm 2: mov pc=%rsi +mov %rcx,%rsi + +# qhasm: pp -= 1 +# asm 1: sub $1,>= 1 +# asm 1: shr $1,? pc - 0 +# asm 1: cmp $0, +jbe ._end + +# qhasm: spp = *(uint64 *)(hp + pp * 8) +# asm 1: movq (spp=int64#5 +# asm 2: movq (spp=%r8 +movq (%rdi,%rcx,8),%r8 + +# qhasm: spc = *(uint64 *)(hp + pc * 8) +# asm 1: movq (spc=int64#6 +# asm 2: movq (spc=%r9 +movq (%rdi,%rsi,8),%r9 + +# qhasm: spp <<= 5 +# asm 1: shl $5,c0=int64#7 +# asm 2: movq 0(c0=%rax +movq 0(%r9),%rax + +# qhasm: c1 = *(uint64 *)(spc + 8) +# asm 1: movq 8(c1=int64#8 +# asm 2: movq 8(c1=%r10 +movq 8(%r9),%r10 + +# qhasm: carry? c0 -= *(uint64 *)(spp + 0) +# asm 1: subq 0(>= 5 +# asm 1: shr $5,>= 5 +# asm 1: shr $5,caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/heap_rootreplaced_3limbs.s b/ext/ed25519-amd64-asm/heap_rootreplaced_3limbs.s new file mode 100644 index 0000000..dcf890e --- /dev/null +++ b/ext/ed25519-amd64-asm/heap_rootreplaced_3limbs.s @@ -0,0 +1,456 @@ + +# qhasm: int64 hp + +# qhasm: int64 hlen + +# qhasm: int64 sp + +# qhasm: int64 pp + +# qhasm: input hp + +# qhasm: input hlen + +# qhasm: input sp + +# qhasm: int64 prc + +# qhasm: int64 plc + +# qhasm: int64 pc + +# qhasm: int64 d + +# qhasm: int64 spp + +# qhasm: int64 sprc + +# qhasm: int64 spc + +# qhasm: int64 c0 + +# qhasm: int64 c1 + +# qhasm: int64 c2 + +# qhasm: int64 c3 + +# qhasm: int64 t0 + +# qhasm: int64 t1 + +# qhasm: int64 t2 + +# qhasm: int64 t3 + +# qhasm: int64 p0 + +# qhasm: int64 p1 + +# qhasm: int64 p2 + +# qhasm: int64 p3 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs +.globl crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs +_crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs: +crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: pp = 0 +# asm 1: mov $0,>pp=int64#4 +# asm 2: mov $0,>pp=%rcx +mov $0,%rcx + +# qhasm: siftdownloop: +._siftdownloop: + +# qhasm: prc = pp +# asm 1: mov prc=int64#5 +# asm 2: mov prc=%r8 +mov %rcx,%r8 + +# qhasm: prc *= 2 +# asm 1: imulq $2,prc=int64#5 +# asm 2: imulq $2,prc=%r8 +imulq $2,%r8,%r8 + +# qhasm: pc = prc +# asm 1: mov pc=int64#6 +# asm 2: mov pc=%r9 +mov %r8,%r9 + +# qhasm: prc += 2 +# asm 1: add $2,? hlen - prc +# asm 1: cmp +jbe ._siftuploop + +# qhasm: sprc = *(uint64 *)(hp + prc * 8) +# asm 1: movq (sprc=int64#7 +# asm 2: movq (sprc=%rax +movq (%rdi,%r8,8),%rax + +# qhasm: sprc <<= 5 +# asm 1: shl $5,spc=int64#8 +# asm 2: movq (spc=%r10 +movq (%rdi,%r9,8),%r10 + +# qhasm: spc <<= 5 +# asm 1: shl $5,c0=int64#9 +# asm 2: movq 0(c0=%r11 +movq 0(%r10),%r11 + +# qhasm: c1 = *(uint64 *)(spc + 8) +# asm 1: movq 8(c1=int64#10 +# asm 2: movq 8(c1=%r12 +movq 8(%r10),%r12 + +# qhasm: c2 = *(uint64 *)(spc + 16) +# asm 1: movq 16(c2=int64#11 +# asm 2: movq 16(c2=%r13 +movq 16(%r10),%r13 + +# qhasm: carry? c0 -= *(uint64 *)(sprc + 0) +# asm 1: subq 0(>= 5 +# asm 1: shr $5,spp=int64#5 +# asm 2: movq (spp=%r8 +movq (%rdi,%rcx,8),%r8 + +# qhasm: *(uint64 *)(hp + pp * 8) = spc +# asm 1: movq pp=int64#4 +# asm 2: mov pp=%rcx +mov %r9,%rcx +# comment:fp stack unchanged by jump + +# qhasm: goto siftdownloop +jmp ._siftdownloop + +# qhasm: siftuploop: +._siftuploop: + +# qhasm: pc = pp +# asm 1: mov pc=int64#2 +# asm 2: mov pc=%rsi +mov %rcx,%rsi + +# qhasm: pp -= 1 +# asm 1: sub $1,>= 1 +# asm 1: shr $1,? pc - 0 +# asm 1: cmp $0, +jbe ._end + +# qhasm: spp = *(uint64 *)(hp + pp * 8) +# asm 1: movq (spp=int64#5 +# asm 2: movq (spp=%r8 +movq (%rdi,%rcx,8),%r8 + +# qhasm: spc = *(uint64 *)(hp + pc * 8) +# asm 1: movq (spc=int64#6 +# asm 2: movq (spc=%r9 +movq (%rdi,%rsi,8),%r9 + +# qhasm: spp <<= 5 +# asm 1: shl $5,c0=int64#7 +# asm 2: movq 0(c0=%rax +movq 0(%r9),%rax + +# qhasm: c1 = *(uint64 *)(spc + 8) +# asm 1: movq 8(c1=int64#8 +# asm 2: movq 8(c1=%r10 +movq 8(%r9),%r10 + +# qhasm: c2 = *(uint64 *)(spc + 16) +# asm 1: movq 16(c2=int64#9 +# asm 2: movq 16(c2=%r11 +movq 16(%r9),%r11 + +# qhasm: carry? c0 -= *(uint64 *)(spp + 0) +# asm 1: subq 0(>= 5 +# asm 1: shr $5,>= 5 +# asm 1: shr $5,caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/hram.c b/ext/ed25519-amd64-asm/hram.c new file mode 100644 index 0000000..6f99fc6 --- /dev/null +++ b/ext/ed25519-amd64-asm/hram.c @@ -0,0 +1,16 @@ +/*#include "crypto_hash_sha512.h"*/ +#include "hram.h" + +extern void ZT_sha512internal(void *digest,const void *data,unsigned int len); + +void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) +{ + unsigned long long i; + + for (i = 0;i < 32;++i) playground[i] = sm[i]; + for (i = 32;i < 64;++i) playground[i] = pk[i-32]; + for (i = 64;i < smlen;++i) playground[i] = sm[i]; + + /*crypto_hash_sha512(hram,playground,smlen);*/ + ZT_sha512internal(hram,playground,smlen); +} diff --git a/ext/ed25519-amd64-asm/hram.h b/ext/ed25519-amd64-asm/hram.h new file mode 100644 index 0000000..1740c78 --- /dev/null +++ b/ext/ed25519-amd64-asm/hram.h @@ -0,0 +1,8 @@ +#ifndef HRAM_H +#define HRAM_H + +#define get_hram crypto_sign_ed25519_amd64_64_get_hram + +extern void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen); + +#endif diff --git a/ext/ed25519-amd64-asm/implementors b/ext/ed25519-amd64-asm/implementors new file mode 100644 index 0000000..9b5399a --- /dev/null +++ b/ext/ed25519-amd64-asm/implementors @@ -0,0 +1,5 @@ +Daniel J. Bernstein +Niels Duif +Tanja Lange +lead: Peter Schwabe +Bo-Yin Yang diff --git a/ext/ed25519-amd64-asm/index_heap.c b/ext/ed25519-amd64-asm/index_heap.c new file mode 100644 index 0000000..f29f7a2 --- /dev/null +++ b/ext/ed25519-amd64-asm/index_heap.c @@ -0,0 +1,58 @@ +#include "sc25519.h" +#include "index_heap.h" + +/* caller's responsibility to ensure hlen>=3 */ +void heap_init(unsigned long long *h, unsigned long long hlen, sc25519 *scalars) +{ + h[0] = 0; + unsigned long long i=1; + while(i 0) + { + /* if(sc25519_lt_vartime(&scalars[h[ppos]], &scalars[h[pos]])) */ + if(sc25519_lt(&scalars[h[ppos]], &scalars[h[pos]])) + { + t = h[ppos]; + h[ppos] = h[pos]; + h[pos] = t; + pos = ppos; + ppos = (pos-1)/2; + } + else break; + } + (*hlen)++; +} + +/* Put the largest value in the heap in max1, the second largest in max2 */ +void heap_get2max(unsigned long long *h, unsigned long long *max1, unsigned long long *max2, sc25519 *scalars) +{ + *max1 = h[0]; + *max2 = h[1]; + if(sc25519_lt(&scalars[h[1]],&scalars[h[2]])) + *max2 = h[2]; +} + +/* After the root has been replaced, restore heap property */ +/* extern void heap_rootreplaced(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); +*/ +/* extern void heap_rootreplaced_shortscalars(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); +*/ diff --git a/ext/ed25519-amd64-asm/index_heap.h b/ext/ed25519-amd64-asm/index_heap.h new file mode 100644 index 0000000..7dee916 --- /dev/null +++ b/ext/ed25519-amd64-asm/index_heap.h @@ -0,0 +1,31 @@ +#ifndef INDEX_HEAP_H +#define INDEX_HEAP_H + +#include "sc25519.h" + +#define heap_init crypto_sign_ed25519_amd64_64_heap_init +#define heap_extend crypto_sign_ed25519_amd64_64_heap_extend +#define heap_pop crypto_sign_ed25519_amd64_64_heap_pop +#define heap_push crypto_sign_ed25519_amd64_64_heap_push +#define heap_get2max crypto_sign_ed25519_amd64_64_heap_get2max +#define heap_rootreplaced crypto_sign_ed25519_amd64_64_heap_rootreplaced +#define heap_rootreplaced_3limbs crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs +#define heap_rootreplaced_2limbs crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs +#define heap_rootreplaced_1limb crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb + +void heap_init(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); + +void heap_extend(unsigned long long *h, unsigned long long oldlen, unsigned long long newlen, sc25519 *scalars); + +unsigned long long heap_pop(unsigned long long *h, unsigned long long *hlen, sc25519 *scalars); + +void heap_push(unsigned long long *h, unsigned long long *hlen, unsigned long long elem, sc25519 *scalars); + +void heap_get2max(unsigned long long *h, unsigned long long *max1, unsigned long long *max2, sc25519 *scalars); + +void heap_rootreplaced(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); +void heap_rootreplaced_3limbs(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); +void heap_rootreplaced_2limbs(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); +void heap_rootreplaced_1limb(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); + +#endif diff --git a/ext/ed25519-amd64-asm/keypair.c b/ext/ed25519-amd64-asm/keypair.c new file mode 100644 index 0000000..7e09471 --- /dev/null +++ b/ext/ed25519-amd64-asm/keypair.c @@ -0,0 +1,25 @@ +#include +#include "crypto_sign.h" +#include "crypto_hash_sha512.h" +#include "randombytes.h" +#include "ge25519.h" + +int crypto_sign_keypair(unsigned char *pk,unsigned char *sk) +{ + unsigned char az[64]; + sc25519 scsk; + ge25519 gepk; + + randombytes(sk,32); + crypto_hash_sha512(az,sk,32); + az[0] &= 248; + az[31] &= 127; + az[31] |= 64; + + sc25519_from32bytes(&scsk,az); + + ge25519_scalarmult_base(&gepk, &scsk); + ge25519_pack(pk, &gepk); + memmove(sk + 32,pk,32); + return 0; +} diff --git a/ext/ed25519-amd64-asm/open.c b/ext/ed25519-amd64-asm/open.c new file mode 100644 index 0000000..104d48d --- /dev/null +++ b/ext/ed25519-amd64-asm/open.c @@ -0,0 +1,49 @@ +#include +#include "crypto_sign.h" +#include "crypto_verify_32.h" +#include "crypto_hash_sha512.h" +#include "ge25519.h" + +int crypto_sign_open( + unsigned char *m,unsigned long long *mlen, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk + ) +{ + unsigned char pkcopy[32]; + unsigned char rcopy[32]; + unsigned char hram[64]; + unsigned char rcheck[32]; + ge25519 get1, get2; + sc25519 schram, scs; + + if (smlen < 64) goto badsig; + if (sm[63] & 224) goto badsig; + if (ge25519_unpackneg_vartime(&get1,pk)) goto badsig; + + memmove(pkcopy,pk,32); + memmove(rcopy,sm,32); + + sc25519_from32bytes(&scs, sm+32); + + memmove(m,sm,smlen); + memmove(m + 32,pkcopy,32); + crypto_hash_sha512(hram,m,smlen); + + sc25519_from64bytes(&schram, hram); + + ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &scs); + ge25519_pack(rcheck, &get2); + + if (crypto_verify_32(rcopy,rcheck) == 0) { + memmove(m,m + 64,smlen - 64); + memset(m + smlen - 64,0,64); + *mlen = smlen - 64; + return 0; + } + +badsig: + *mlen = (unsigned long long) -1; + memset(m,0,smlen); + return -1; +} diff --git a/ext/ed25519-amd64-asm/sc25519.h b/ext/ed25519-amd64-asm/sc25519.h new file mode 100644 index 0000000..8ff1b1c --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519.h @@ -0,0 +1,66 @@ +#ifndef SC25519_H +#define SC25519_H + +#define sc25519 crypto_sign_ed25519_amd64_64_sc25519 +#define shortsc25519 crypto_sign_ed25519_amd64_64_shortsc25519 +#define sc25519_from32bytes crypto_sign_ed25519_amd64_64_sc25519_from32bytes +#define shortsc25519_from16bytes crypto_sign_ed25519_amd64_64_shortsc25519_from16bytes +#define sc25519_from64bytes crypto_sign_ed25519_amd64_64_sc25519_from64bytes +#define sc25519_from_shortsc crypto_sign_ed25519_amd64_64_sc25519_from_shortsc +#define sc25519_to32bytes crypto_sign_ed25519_amd64_64_sc25519_to32bytes +#define sc25519_iszero_vartime crypto_sign_ed25519_amd64_64_sc25519_iszero_vartime +#define sc25519_isshort_vartime crypto_sign_ed25519_amd64_64_sc25519_isshort_vartime +#define sc25519_lt crypto_sign_ed25519_amd64_64_sc25519_lt +#define sc25519_add crypto_sign_ed25519_amd64_64_sc25519_add +#define sc25519_sub_nored crypto_sign_ed25519_amd64_64_sc25519_sub_nored +#define sc25519_mul crypto_sign_ed25519_amd64_64_sc25519_mul +#define sc25519_mul_shortsc crypto_sign_ed25519_amd64_64_sc25519_mul_shortsc +#define sc25519_window4 crypto_sign_ed25519_amd64_64_sc25519_window4 +#define sc25519_slide crypto_sign_ed25519_amd64_64_sc25519_slide +#define sc25519_2interleave2 crypto_sign_ed25519_amd64_64_sc25519_2interleave2 +#define sc25519_barrett crypto_sign_ed25519_amd64_64_sc25519_barrett + +typedef struct +{ + unsigned long long v[4]; +} +sc25519; + +typedef struct +{ + unsigned long long v[2]; +} +shortsc25519; + +void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]); + +void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]); + +void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x); + +void sc25519_to32bytes(unsigned char r[32], const sc25519 *x); + +int sc25519_iszero_vartime(const sc25519 *x); + +int sc25519_lt(const sc25519 *x, const sc25519 *y); + +void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y); + +void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y); + +void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y); + +void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y); + +/* Convert s into a representation of the form \sum_{i=0}^{63}r[i]2^(4*i) + * with r[i] in {-8,...,7} + */ +void sc25519_window4(signed char r[85], const sc25519 *s); + +void sc25519_slide(signed char r[256], const sc25519 *s, int swindowsize); + +void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2); + +void sc25519_barrett(sc25519 *r, unsigned long long x[8]); + +#endif diff --git a/ext/ed25519-amd64-asm/sc25519_add.s b/ext/ed25519-amd64-asm/sc25519_add.s new file mode 100644 index 0000000..d5b941c --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_add.s @@ -0,0 +1,232 @@ + +# qhasm: int64 rp + +# qhasm: int64 xp + +# qhasm: int64 yp + +# qhasm: input rp + +# qhasm: input xp + +# qhasm: input yp + +# qhasm: int64 r0 + +# qhasm: int64 r1 + +# qhasm: int64 r2 + +# qhasm: int64 r3 + +# qhasm: int64 t0 + +# qhasm: int64 t1 + +# qhasm: int64 t2 + +# qhasm: int64 t3 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_sc25519_add +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_sc25519_add +.globl crypto_sign_ed25519_amd64_64_sc25519_add +_crypto_sign_ed25519_amd64_64_sc25519_add: +crypto_sign_ed25519_amd64_64_sc25519_add: +mov %rsp,%r11 +and $31,%r11 +add $32,%r11 +sub %r11,%rsp + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#1 +# asm 2: movq caller4_stack=0(%rsp) +movq %r14,0(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#2 +# asm 2: movq caller5_stack=8(%rsp) +movq %r15,8(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#3 +# asm 2: movq caller6_stack=16(%rsp) +movq %rbx,16(%rsp) + +# qhasm: r0 = *(uint64 *)(xp + 0) +# asm 1: movq 0(r0=int64#4 +# asm 2: movq 0(r0=%rcx +movq 0(%rsi),%rcx + +# qhasm: r1 = *(uint64 *)(xp + 8) +# asm 1: movq 8(r1=int64#5 +# asm 2: movq 8(r1=%r8 +movq 8(%rsi),%r8 + +# qhasm: r2 = *(uint64 *)(xp + 16) +# asm 1: movq 16(r2=int64#6 +# asm 2: movq 16(r2=%r9 +movq 16(%rsi),%r9 + +# qhasm: r3 = *(uint64 *)(xp + 24) +# asm 1: movq 24(r3=int64#2 +# asm 2: movq 24(r3=%rsi +movq 24(%rsi),%rsi + +# qhasm: carry? r0 += *(uint64 *)(yp + 0) +# asm 1: addq 0(t0=int64#3 +# asm 2: mov t0=%rdx +mov %rcx,%rdx + +# qhasm: t1 = r1 +# asm 1: mov t1=int64#7 +# asm 2: mov t1=%rax +mov %r8,%rax + +# qhasm: t2 = r2 +# asm 1: mov t2=int64#8 +# asm 2: mov t2=%r10 +mov %r9,%r10 + +# qhasm: t3 = r3 +# asm 1: mov t3=int64#12 +# asm 2: mov t3=%r14 +mov %rsi,%r14 + +# qhasm: carry? t0 -= *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 +# asm 1: sub crypto_sign_ed25519_amd64_64_ORDER0,caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 0(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 8(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 16(%rsp),%rbx + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/sc25519_barrett.s b/ext/ed25519-amd64-asm/sc25519_barrett.s new file mode 100644 index 0000000..7eb56fa --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_barrett.s @@ -0,0 +1,1188 @@ + +# qhasm: int64 rp + +# qhasm: int64 xp + +# qhasm: input rp + +# qhasm: input xp + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: int64 q23 + +# qhasm: int64 q24 + +# qhasm: int64 q30 + +# qhasm: int64 q31 + +# qhasm: int64 q32 + +# qhasm: int64 q33 + +# qhasm: int64 r20 + +# qhasm: int64 r21 + +# qhasm: int64 r22 + +# qhasm: int64 r23 + +# qhasm: int64 r24 + +# qhasm: int64 r0 + +# qhasm: int64 r1 + +# qhasm: int64 r2 + +# qhasm: int64 r3 + +# qhasm: int64 t0 + +# qhasm: int64 t1 + +# qhasm: int64 t2 + +# qhasm: int64 t3 + +# qhasm: int64 rax + +# qhasm: int64 rdx + +# qhasm: int64 c + +# qhasm: int64 zero + +# qhasm: int64 mask + +# qhasm: int64 nmask + +# qhasm: stack64 q30_stack + +# qhasm: stack64 q31_stack + +# qhasm: stack64 q32_stack + +# qhasm: stack64 q33_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_sc25519_barrett +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_sc25519_barrett +.globl crypto_sign_ed25519_amd64_64_sc25519_barrett +_crypto_sign_ed25519_amd64_64_sc25519_barrett: +crypto_sign_ed25519_amd64_64_sc25519_barrett: +mov %rsp,%r11 +and $31,%r11 +add $96,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: zero ^= zero +# asm 1: xor rax=int64#7 +# asm 2: movq 24(rax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 +mulq crypto_sign_ed25519_amd64_64_MU3(%rip) + +# qhasm: q23 = rax +# asm 1: mov q23=int64#10 +# asm 2: mov q23=%r12 +mov %rax,%r12 + +# qhasm: c = rdx +# asm 1: mov c=int64#11 +# asm 2: mov c=%r13 +mov %rdx,%r13 + +# qhasm: rax = *(uint64 *)(xp + 24) +# asm 1: movq 24(rax=int64#7 +# asm 2: movq 24(rax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 +mulq crypto_sign_ed25519_amd64_64_MU4(%rip) + +# qhasm: q24 = rax +# asm 1: mov q24=int64#12 +# asm 2: mov q24=%r14 +mov %rax,%r14 + +# qhasm: carry? q24 += c +# asm 1: add rax=int64#7 +# asm 2: movq 32(rax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU2 +mulq crypto_sign_ed25519_amd64_64_MU2(%rip) + +# qhasm: carry? q23 += rax +# asm 1: add c=int64#11 +# asm 2: mov $0,>c=%r13 +mov $0,%r13 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 32(rax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 +mulq crypto_sign_ed25519_amd64_64_MU3(%rip) + +# qhasm: carry? q24 += rax +# asm 1: add c=int64#11 +# asm 2: mov $0,>c=%r13 +mov $0,%r13 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 32(rax=%rax +movq 32(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 +mulq crypto_sign_ed25519_amd64_64_MU4(%rip) + +# qhasm: carry? q30 += rax +# asm 1: add rax=int64#7 +# asm 2: movq 40(rax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU1 +mulq crypto_sign_ed25519_amd64_64_MU1(%rip) + +# qhasm: carry? q23 += rax +# asm 1: add c=int64#11 +# asm 2: mov $0,>c=%r13 +mov $0,%r13 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 40(rax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU2 +mulq crypto_sign_ed25519_amd64_64_MU2(%rip) + +# qhasm: carry? q24 += rax +# asm 1: add c=int64#11 +# asm 2: mov $0,>c=%r13 +mov $0,%r13 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 40(rax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 +mulq crypto_sign_ed25519_amd64_64_MU3(%rip) + +# qhasm: carry? q30 += rax +# asm 1: add c=int64#11 +# asm 2: mov $0,>c=%r13 +mov $0,%r13 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 40(rax=%rax +movq 40(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 +mulq crypto_sign_ed25519_amd64_64_MU4(%rip) + +# qhasm: carry? q31 += rax +# asm 1: add rax=int64#7 +# asm 2: movq 48(rax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU0 +mulq crypto_sign_ed25519_amd64_64_MU0(%rip) + +# qhasm: carry? q23 += rax +# asm 1: add c=int64#10 +# asm 2: mov $0,>c=%r12 +mov $0,%r12 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 48(rax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU1 +mulq crypto_sign_ed25519_amd64_64_MU1(%rip) + +# qhasm: carry? q24 += rax +# asm 1: add c=int64#10 +# asm 2: mov $0,>c=%r12 +mov $0,%r12 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 48(rax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU2 +mulq crypto_sign_ed25519_amd64_64_MU2(%rip) + +# qhasm: carry? q30 += rax +# asm 1: add c=int64#10 +# asm 2: mov $0,>c=%r12 +mov $0,%r12 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 48(rax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 +mulq crypto_sign_ed25519_amd64_64_MU3(%rip) + +# qhasm: carry? q31 += rax +# asm 1: add c=int64#10 +# asm 2: mov $0,>c=%r12 +mov $0,%r12 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 48(rax=%rax +movq 48(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 +mulq crypto_sign_ed25519_amd64_64_MU4(%rip) + +# qhasm: carry? q32 += rax +# asm 1: add rax=int64#7 +# asm 2: movq 56(rax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU0 +mulq crypto_sign_ed25519_amd64_64_MU0(%rip) + +# qhasm: carry? q24 += rax +# asm 1: add c=int64#10 +# asm 2: mov $0,>c=%r12 +mov $0,%r12 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 56(rax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU1 +mulq crypto_sign_ed25519_amd64_64_MU1(%rip) + +# qhasm: carry? q30 += rax +# asm 1: add c=int64#10 +# asm 2: mov $0,>c=%r12 +mov $0,%r12 + +# qhasm: c += rdx + carry +# asm 1: adc q30_stack=stack64#8 +# asm 2: movq q30_stack=56(%rsp) +movq %r8,56(%rsp) + +# qhasm: rax = *(uint64 *)(xp + 56) +# asm 1: movq 56(rax=int64#7 +# asm 2: movq 56(rax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU2 +mulq crypto_sign_ed25519_amd64_64_MU2(%rip) + +# qhasm: carry? q31 += rax +# asm 1: add c=int64#5 +# asm 2: mov $0,>c=%r8 +mov $0,%r8 + +# qhasm: c += rdx + carry +# asm 1: adc q31_stack=stack64#9 +# asm 2: movq q31_stack=64(%rsp) +movq %r9,64(%rsp) + +# qhasm: rax = *(uint64 *)(xp + 56) +# asm 1: movq 56(rax=int64#7 +# asm 2: movq 56(rax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 +mulq crypto_sign_ed25519_amd64_64_MU3(%rip) + +# qhasm: carry? q32 += rax +# asm 1: add c=int64#5 +# asm 2: mov $0,>c=%r8 +mov $0,%r8 + +# qhasm: c += rdx + carry +# asm 1: adc q32_stack=stack64#10 +# asm 2: movq q32_stack=72(%rsp) +movq %r10,72(%rsp) + +# qhasm: rax = *(uint64 *)(xp + 56) +# asm 1: movq 56(rax=int64#7 +# asm 2: movq 56(rax=%rax +movq 56(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 +mulq crypto_sign_ed25519_amd64_64_MU4(%rip) + +# qhasm: carry? q33 += rax +# asm 1: add q33_stack=stack64#11 +# asm 2: movq q33_stack=80(%rsp) +movq %r11,80(%rsp) + +# qhasm: rax = q30_stack +# asm 1: movq rax=int64#7 +# asm 2: movq rax=%rax +movq 56(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 +mulq crypto_sign_ed25519_amd64_64_ORDER0(%rip) + +# qhasm: r20 = rax +# asm 1: mov r20=int64#5 +# asm 2: mov r20=%r8 +mov %rax,%r8 + +# qhasm: c = rdx +# asm 1: mov c=int64#6 +# asm 2: mov c=%r9 +mov %rdx,%r9 + +# qhasm: rax = q30_stack +# asm 1: movq rax=int64#7 +# asm 2: movq rax=%rax +movq 56(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER1 +mulq crypto_sign_ed25519_amd64_64_ORDER1(%rip) + +# qhasm: r21 = rax +# asm 1: mov r21=int64#8 +# asm 2: mov r21=%r10 +mov %rax,%r10 + +# qhasm: carry? r21 += c +# asm 1: add c=int64#6 +# asm 2: mov $0,>c=%r9 +mov $0,%r9 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq rax=%rax +movq 56(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER2 +mulq crypto_sign_ed25519_amd64_64_ORDER2(%rip) + +# qhasm: r22 = rax +# asm 1: mov r22=int64#9 +# asm 2: mov r22=%r11 +mov %rax,%r11 + +# qhasm: carry? r22 += c +# asm 1: add c=int64#6 +# asm 2: mov $0,>c=%r9 +mov $0,%r9 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq rax=%rax +movq 56(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER3 +mulq crypto_sign_ed25519_amd64_64_ORDER3(%rip) + +# qhasm: free rdx + +# qhasm: r23 = rax +# asm 1: mov r23=int64#10 +# asm 2: mov r23=%r12 +mov %rax,%r12 + +# qhasm: r23 += c +# asm 1: add rax=int64#7 +# asm 2: movq rax=%rax +movq 64(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 +mulq crypto_sign_ed25519_amd64_64_ORDER0(%rip) + +# qhasm: carry? r21 += rax +# asm 1: add c=int64#6 +# asm 2: mov $0,>c=%r9 +mov $0,%r9 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq rax=%rax +movq 64(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER1 +mulq crypto_sign_ed25519_amd64_64_ORDER1(%rip) + +# qhasm: carry? r22 += rax +# asm 1: add c=int64#4 +# asm 2: mov $0,>c=%rcx +mov $0,%rcx + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq rax=%rax +movq 64(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER2 +mulq crypto_sign_ed25519_amd64_64_ORDER2(%rip) + +# qhasm: free rdx + +# qhasm: r23 += rax +# asm 1: add rax=int64#7 +# asm 2: movq rax=%rax +movq 72(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 +mulq crypto_sign_ed25519_amd64_64_ORDER0(%rip) + +# qhasm: carry? r22 += rax +# asm 1: add c=int64#4 +# asm 2: mov $0,>c=%rcx +mov $0,%rcx + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq rax=%rax +movq 72(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER1 +mulq crypto_sign_ed25519_amd64_64_ORDER1(%rip) + +# qhasm: free rdx + +# qhasm: r23 += rax +# asm 1: add rax=int64#7 +# asm 2: movq rax=%rax +movq 80(%rsp),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 +mulq crypto_sign_ed25519_amd64_64_ORDER0(%rip) + +# qhasm: free rdx + +# qhasm: r23 += rax +# asm 1: add r0=int64#3 +# asm 2: movq 0(r0=%rdx +movq 0(%rsi),%rdx + +# qhasm: carry? r0 -= r20 +# asm 1: sub t0=int64#4 +# asm 2: mov t0=%rcx +mov %rdx,%rcx + +# qhasm: r1 = *(uint64 *)(xp + 8) +# asm 1: movq 8(r1=int64#5 +# asm 2: movq 8(r1=%r8 +movq 8(%rsi),%r8 + +# qhasm: carry? r1 -= r21 - carry +# asm 1: sbb t1=int64#6 +# asm 2: mov t1=%r9 +mov %r8,%r9 + +# qhasm: r2 = *(uint64 *)(xp + 16) +# asm 1: movq 16(r2=int64#7 +# asm 2: movq 16(r2=%rax +movq 16(%rsi),%rax + +# qhasm: carry? r2 -= r22 - carry +# asm 1: sbb t2=int64#8 +# asm 2: mov t2=%r10 +mov %rax,%r10 + +# qhasm: r3 = *(uint64 *)(xp + 24) +# asm 1: movq 24(r3=int64#2 +# asm 2: movq 24(r3=%rsi +movq 24(%rsi),%rsi + +# qhasm: r3 -= r23 - carry +# asm 1: sbb t3=int64#9 +# asm 2: mov t3=%r11 +mov %rsi,%r11 + +# qhasm: carry? t0 -= *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 +# asm 1: sub crypto_sign_ed25519_amd64_64_ORDER0,t0=int64#4 +# asm 2: mov t0=%rcx +mov %rdx,%rcx + +# qhasm: r1 = t1 if !unsigned< +# asm 1: cmovae t1=int64#6 +# asm 2: mov t1=%r9 +mov %r8,%r9 + +# qhasm: r2 = t2 if !unsigned< +# asm 1: cmovae t2=int64#8 +# asm 2: mov t2=%r10 +mov %rax,%r10 + +# qhasm: r3 = t3 if !unsigned< +# asm 1: cmovae t3=int64#9 +# asm 2: mov t3=%r11 +mov %rsi,%r11 + +# qhasm: carry? t0 -= *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 +# asm 1: sub crypto_sign_ed25519_amd64_64_ORDER0,caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/ed25519-amd64-asm/sc25519_from32bytes.c b/ext/ed25519-amd64-asm/sc25519_from32bytes.c new file mode 100644 index 0000000..7f21e68 --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_from32bytes.c @@ -0,0 +1,55 @@ +#include "sc25519.h" + +/*Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 + * = 7237005577332262213973186563042994240857116359379907606001950938285454250989 + */ + +/* Contains order, 2*order, 4*order, 8*order, each represented in 4 consecutive unsigned long long */ +static const unsigned long long order[16] = {0x5812631A5CF5D3EDULL, 0x14DEF9DEA2F79CD6ULL, + 0x0000000000000000ULL, 0x1000000000000000ULL, + 0xB024C634B9EBA7DAULL, 0x29BDF3BD45EF39ACULL, + 0x0000000000000000ULL, 0x2000000000000000ULL, + 0x60498C6973D74FB4ULL, 0x537BE77A8BDE7359ULL, + 0x0000000000000000ULL, 0x4000000000000000ULL, + 0xC09318D2E7AE9F68ULL, 0xA6F7CEF517BCE6B2ULL, + 0x0000000000000000ULL, 0x8000000000000000ULL}; + +static unsigned long long smaller(unsigned long long a,unsigned long long b) +{ + unsigned long long atop = a >> 32; + unsigned long long abot = a & 4294967295; + unsigned long long btop = b >> 32; + unsigned long long bbot = b & 4294967295; + unsigned long long atopbelowbtop = (atop - btop) >> 63; + unsigned long long atopeqbtop = ((atop ^ btop) - 1) >> 63; + unsigned long long abotbelowbbot = (abot - bbot) >> 63; + return atopbelowbtop | (atopeqbtop & abotbelowbbot); +} + +void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]) +{ + unsigned long long t[4]; + unsigned long long b; + unsigned long long mask; + int i, j; + + /* assuming little-endian */ + r->v[0] = *(unsigned long long *)x; + r->v[1] = *(((unsigned long long *)x)+1); + r->v[2] = *(((unsigned long long *)x)+2); + r->v[3] = *(((unsigned long long *)x)+3); + + for(j=3;j>=0;j--) + { + b=0; + for(i=0;i<4;i++) + { + b += order[4*j+i]; /* no overflow for this particular order */ + t[i] = r->v[i] - b; + b = smaller(r->v[i],b); + } + mask = b - 1; + for(i=0;i<4;i++) + r->v[i] ^= mask & (r->v[i] ^ t[i]); + } +} diff --git a/ext/ed25519-amd64-asm/sc25519_from64bytes.c b/ext/ed25519-amd64-asm/sc25519_from64bytes.c new file mode 100644 index 0000000..8e76a1b --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_from64bytes.c @@ -0,0 +1,7 @@ +#include "sc25519.h" + +void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]) +{ + /* assuming little-endian representation of unsigned long long */ + sc25519_barrett(r, (unsigned long long *)x); +} diff --git a/ext/ed25519-amd64-asm/sc25519_from_shortsc.c b/ext/ed25519-amd64-asm/sc25519_from_shortsc.c new file mode 100644 index 0000000..3b8ff2f --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_from_shortsc.c @@ -0,0 +1,9 @@ +#include "sc25519.h" + +void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x) +{ + r->v[0] = x->v[0]; + r->v[1] = x->v[1]; + r->v[2] = 0; + r->v[3] = 0; +} diff --git a/ext/ed25519-amd64-asm/sc25519_iszero.c b/ext/ed25519-amd64-asm/sc25519_iszero.c new file mode 100644 index 0000000..21f593d --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_iszero.c @@ -0,0 +1,10 @@ +#include "sc25519.h" + +int sc25519_iszero_vartime(const sc25519 *x) +{ + if(x->v[0] != 0) return 0; + if(x->v[1] != 0) return 0; + if(x->v[2] != 0) return 0; + if(x->v[3] != 0) return 0; + return 1; +} diff --git a/ext/ed25519-amd64-asm/sc25519_lt.s b/ext/ed25519-amd64-asm/sc25519_lt.s new file mode 100644 index 0000000..3ba4317 --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_lt.s @@ -0,0 +1,131 @@ + +# qhasm: int64 xp + +# qhasm: int64 yp + +# qhasm: int64 ret + +# qhasm: input xp + +# qhasm: input yp + +# qhasm: output ret + +# qhasm: int64 t0 + +# qhasm: int64 t1 + +# qhasm: int64 t2 + +# qhasm: int64 t3 + +# qhasm: int64 doof + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_sc25519_lt +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_sc25519_lt +.globl crypto_sign_ed25519_amd64_64_sc25519_lt +_crypto_sign_ed25519_amd64_64_sc25519_lt: +crypto_sign_ed25519_amd64_64_sc25519_lt: +mov %rsp,%r11 +and $31,%r11 +add $0,%r11 +sub %r11,%rsp + +# qhasm: t0 = *(uint64 *)(xp + 0) +# asm 1: movq 0(t0=int64#3 +# asm 2: movq 0(t0=%rdx +movq 0(%rdi),%rdx + +# qhasm: t1 = *(uint64 *)(xp + 8) +# asm 1: movq 8(t1=int64#4 +# asm 2: movq 8(t1=%rcx +movq 8(%rdi),%rcx + +# qhasm: t2 = *(uint64 *)(xp + 16) +# asm 1: movq 16(t2=int64#5 +# asm 2: movq 16(t2=%r8 +movq 16(%rdi),%r8 + +# qhasm: t3 = *(uint64 *)(xp + 24) +# asm 1: movq 24(t3=int64#1 +# asm 2: movq 24(t3=%rdi +movq 24(%rdi),%rdi + +# qhasm: carry? t0 -= *(uint64 *)(yp + 0) +# asm 1: subq 0(ret=int64#1 +# asm 2: mov $0,>ret=%rdi +mov $0,%rdi + +# qhasm: doof = 1 +# asm 1: mov $1,>doof=int64#2 +# asm 2: mov $1,>doof=%rsi +mov $1,%rsi + +# qhasm: ret = doof if carry +# asm 1: cmovc v, y->v); + sc25519_barrett(r, t); +} diff --git a/ext/ed25519-amd64-asm/sc25519_mul_shortsc.c b/ext/ed25519-amd64-asm/sc25519_mul_shortsc.c new file mode 100644 index 0000000..0c67250 --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_mul_shortsc.c @@ -0,0 +1,9 @@ +#include "sc25519.h" + +void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y) +{ + /* XXX: This wants to be faster */ + sc25519 t; + sc25519_from_shortsc(&t, y); + sc25519_mul(r, x, &t); +} diff --git a/ext/ed25519-amd64-asm/sc25519_slide.c b/ext/ed25519-amd64-asm/sc25519_slide.c new file mode 100644 index 0000000..4e52010 --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_slide.c @@ -0,0 +1,49 @@ +#include "sc25519.h" + +void sc25519_slide(signed char r[256], const sc25519 *s, int swindowsize) +{ + int i,j,k,b,m=(1<<(swindowsize-1))-1, soplen=256; + unsigned long long sv0 = s->v[0]; + unsigned long long sv1 = s->v[1]; + unsigned long long sv2 = s->v[2]; + unsigned long long sv3 = s->v[3]; + + /* first put the binary expansion into r */ + for(i=0;i<64;i++) { + r[i] = sv0 & 1; + r[i+64] = sv1 & 1; + r[i+128] = sv2 & 1; + r[i+192] = sv3 & 1; + sv0 >>= 1; + sv1 >>= 1; + sv2 >>= 1; + sv3 >>= 1; + } + + /* Making it sliding window */ + for (j = 0;j < soplen;++j) + { + if (r[j]) { + for (b = 1;b < soplen - j && b <= 6;++b) { + if (r[j] + (r[j + b] << b) <= m) + { + r[j] += r[j + b] << b; r[j + b] = 0; + } + else if (r[j] - (r[j + b] << b) >= -m) + { + r[j] -= r[j + b] << b; + for (k = j + b;k < soplen;++k) + { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } + else if (r[j + b]) + break; + } + } + } +} diff --git a/ext/ed25519-amd64-asm/sc25519_sub_nored.s b/ext/ed25519-amd64-asm/sc25519_sub_nored.s new file mode 100644 index 0000000..a347e7d --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_sub_nored.s @@ -0,0 +1,142 @@ + +# qhasm: int64 rp + +# qhasm: int64 xp + +# qhasm: int64 yp + +# qhasm: input rp + +# qhasm: input xp + +# qhasm: input yp + +# qhasm: int64 r0 + +# qhasm: int64 r1 + +# qhasm: int64 r2 + +# qhasm: int64 r3 + +# qhasm: int64 t0 + +# qhasm: int64 t1 + +# qhasm: int64 t2 + +# qhasm: int64 t3 + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_sc25519_sub_nored +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_sc25519_sub_nored +.globl crypto_sign_ed25519_amd64_64_sc25519_sub_nored +_crypto_sign_ed25519_amd64_64_sc25519_sub_nored: +crypto_sign_ed25519_amd64_64_sc25519_sub_nored: +mov %rsp,%r11 +and $31,%r11 +add $0,%r11 +sub %r11,%rsp + +# qhasm: r0 = *(uint64 *)(xp + 0) +# asm 1: movq 0(r0=int64#4 +# asm 2: movq 0(r0=%rcx +movq 0(%rsi),%rcx + +# qhasm: r1 = *(uint64 *)(xp + 8) +# asm 1: movq 8(r1=int64#5 +# asm 2: movq 8(r1=%r8 +movq 8(%rsi),%r8 + +# qhasm: r2 = *(uint64 *)(xp + 16) +# asm 1: movq 16(r2=int64#6 +# asm 2: movq 16(r2=%r9 +movq 16(%rsi),%r9 + +# qhasm: r3 = *(uint64 *)(xp + 24) +# asm 1: movq 24(r3=int64#2 +# asm 2: movq 24(r3=%rsi +movq 24(%rsi),%rsi + +# qhasm: carry? r0 -= *(uint64 *)(yp + 0) +# asm 1: subq 0(v]; +} diff --git a/ext/ed25519-amd64-asm/sc25519_window4.c b/ext/ed25519-amd64-asm/sc25519_window4.c new file mode 100644 index 0000000..683a1d4 --- /dev/null +++ b/ext/ed25519-amd64-asm/sc25519_window4.c @@ -0,0 +1,27 @@ +#include "sc25519.h" + +void sc25519_window4(signed char r[64], const sc25519 *s) +{ + char carry; + int i; + for(i=0;i<16;i++) + r[i] = (s->v[0] >> (4*i)) & 15; + for(i=0;i<16;i++) + r[i+16] = (s->v[1] >> (4*i)) & 15; + for(i=0;i<16;i++) + r[i+32] = (s->v[2] >> (4*i)) & 15; + for(i=0;i<16;i++) + r[i+48] = (s->v[3] >> (4*i)) & 15; + + /* Making it signed */ + carry = 0; + for(i=0;i<63;i++) + { + r[i] += carry; + r[i+1] += r[i] >> 4; + r[i] &= 15; + carry = r[i] >> 3; + r[i] -= carry << 4; + } + r[63] += carry; +} diff --git a/ext/ed25519-amd64-asm/sign.c b/ext/ed25519-amd64-asm/sign.c new file mode 100644 index 0000000..882ae76 --- /dev/null +++ b/ext/ed25519-amd64-asm/sign.c @@ -0,0 +1,162 @@ +#include +#include +/*#include "crypto_sign.h" +#include "crypto_hash_sha512.h"*/ +#include "ge25519.h" + +/* Original */ +#if 0 +int crypto_sign( + unsigned char *sm,unsigned long long *smlen, + const unsigned char *m,unsigned long long mlen, + const unsigned char *sk + ) +{ + unsigned char pk[32]; + unsigned char az[64]; + unsigned char nonce[64]; + unsigned char hram[64]; + sc25519 sck, scs, scsk; + ge25519 ger; + + memmove(pk,sk + 32,32); + /* pk: 32-byte public key A */ + + crypto_hash_sha512(az,sk,32); + az[0] &= 248; + az[31] &= 127; + az[31] |= 64; + /* az: 32-byte scalar a, 32-byte randomizer z */ + + *smlen = mlen + 64; + memmove(sm + 64,m,mlen); + memmove(sm + 32,az + 32,32); + /* sm: 32-byte uninit, 32-byte z, mlen-byte m */ + + crypto_hash_sha512(nonce, sm+32, mlen+32); + /* nonce: 64-byte H(z,m) */ + + sc25519_from64bytes(&sck, nonce); + ge25519_scalarmult_base(&ger, &sck); + ge25519_pack(sm, &ger); + /* sm: 32-byte R, 32-byte z, mlen-byte m */ + + memmove(sm + 32,pk,32); + /* sm: 32-byte R, 32-byte A, mlen-byte m */ + + crypto_hash_sha512(hram,sm,mlen + 64); + /* hram: 64-byte H(R,A,m) */ + + sc25519_from64bytes(&scs, hram); + sc25519_from32bytes(&scsk, az); + sc25519_mul(&scs, &scs, &scsk); + sc25519_add(&scs, &scs, &sck); + /* scs: S = nonce + H(R,A,m)a */ + + sc25519_to32bytes(sm + 32,&scs); + /* sm: 32-byte R, 32-byte S, mlen-byte m */ + + return 0; +} +#endif + +#if 0 +void C25519::sign(const C25519::Private &myPrivate,const C25519::Public &myPublic,const void *msg,unsigned int len,void *signature) +{ + sc25519 sck, scs, scsk; + ge25519 ger; + unsigned char r[32]; + unsigned char s[32]; + unsigned char extsk[64]; + unsigned char hmg[crypto_hash_sha512_BYTES]; + unsigned char hram[crypto_hash_sha512_BYTES]; + unsigned char *sig = (unsigned char *)signature; + unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg) + + SHA512::hash(digest,msg,len); + + SHA512::hash(extsk,myPrivate.data + 32,32); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; + + for(unsigned int i=0;i<32;i++) + sig[32 + i] = extsk[32 + i]; + for(unsigned int i=0;i<32;i++) + sig[64 + i] = digest[i]; + + SHA512::hash(hmg,sig + 32,64); + + /* Computation of R */ + sc25519_from64bytes(&sck, hmg); + ge25519_scalarmult_base(&ger, &sck); + ge25519_pack(r, &ger); + + /* Computation of s */ + for(unsigned int i=0;i<32;i++) + sig[i] = r[i]; + + get_hram(hram,sig,myPublic.data + 32,sig,96); + + sc25519_from64bytes(&scs, hram); + sc25519_from32bytes(&scsk, extsk); + sc25519_mul(&scs, &scs, &scsk); + + sc25519_add(&scs, &scs, &sck); + + sc25519_to32bytes(s,&scs); /* cat s */ + for(unsigned int i=0;i<32;i++) + sig[32 + i] = s[i]; +} + +void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) +{ + unsigned long long i; + + for (i = 0;i < 32;++i) playground[i] = sm[i]; + for (i = 32;i < 64;++i) playground[i] = pk[i-32]; + for (i = 64;i < smlen;++i) playground[i] = sm[i]; + + //crypto_hash_sha512(hram,playground,smlen); + ZeroTier::SHA512::hash(hram,playground,(unsigned int)smlen); +} +#endif + +extern void ZT_sha512internal(void *digest,const void *data,unsigned int len); + +extern void ed25519_amd64_asm_sign(const unsigned char *sk,const unsigned char *pk,const unsigned char *digest,unsigned char *sig) +{ + unsigned char az[64]; + unsigned char nonce[64]; + unsigned char hram[64]; + sc25519 sck, scs, scsk; + ge25519 ger; + unsigned int i; + + ZT_sha512internal(az,sk,32); + az[0] &= 248; + az[31] &= 127; + az[31] |= 64; + + for(i=0;i<32;i++) + sig[32 + i] = az[32 + i]; + for(i=0;i<32;i++) + sig[64 + i] = digest[i]; + + ZT_sha512internal(nonce,sig + 32,64); + + sc25519_from64bytes(&sck, nonce); + ge25519_scalarmult_base(&ger, &sck); + ge25519_pack(sig, &ger); + + memmove(sig + 32,pk,32); + + ZT_sha512internal(hram,sig,96); + + sc25519_from64bytes(&scs, hram); + sc25519_from32bytes(&scsk, az); + sc25519_mul(&scs, &scs, &scsk); + sc25519_add(&scs, &scs, &sck); + + sc25519_to32bytes(sig + 32,&scs); +} diff --git a/ext/ed25519-amd64-asm/ull4_mul.s b/ext/ed25519-amd64-asm/ull4_mul.s new file mode 100644 index 0000000..9f7b4fa --- /dev/null +++ b/ext/ed25519-amd64-asm/ull4_mul.s @@ -0,0 +1,716 @@ + +# qhasm: int64 rp + +# qhasm: int64 xp + +# qhasm: int64 yp + +# qhasm: input rp + +# qhasm: input xp + +# qhasm: input yp + +# qhasm: int64 r0 + +# qhasm: int64 r1 + +# qhasm: int64 r2 + +# qhasm: int64 r3 + +# qhasm: int64 r4 + +# qhasm: int64 r5 + +# qhasm: int64 r6 + +# qhasm: int64 r7 + +# qhasm: int64 c + +# qhasm: int64 zero + +# qhasm: int64 rax + +# qhasm: int64 rdx + +# qhasm: int64 caller1 + +# qhasm: int64 caller2 + +# qhasm: int64 caller3 + +# qhasm: int64 caller4 + +# qhasm: int64 caller5 + +# qhasm: int64 caller6 + +# qhasm: int64 caller7 + +# qhasm: caller caller1 + +# qhasm: caller caller2 + +# qhasm: caller caller3 + +# qhasm: caller caller4 + +# qhasm: caller caller5 + +# qhasm: caller caller6 + +# qhasm: caller caller7 + +# qhasm: stack64 caller1_stack + +# qhasm: stack64 caller2_stack + +# qhasm: stack64 caller3_stack + +# qhasm: stack64 caller4_stack + +# qhasm: stack64 caller5_stack + +# qhasm: stack64 caller6_stack + +# qhasm: stack64 caller7_stack + +# qhasm: enter crypto_sign_ed25519_amd64_64_ull4_mul +.text +.p2align 5 +.globl _crypto_sign_ed25519_amd64_64_ull4_mul +.globl crypto_sign_ed25519_amd64_64_ull4_mul +_crypto_sign_ed25519_amd64_64_ull4_mul: +crypto_sign_ed25519_amd64_64_ull4_mul: +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp + +# qhasm: caller1_stack = caller1 +# asm 1: movq caller1_stack=stack64#1 +# asm 2: movq caller1_stack=0(%rsp) +movq %r11,0(%rsp) + +# qhasm: caller2_stack = caller2 +# asm 1: movq caller2_stack=stack64#2 +# asm 2: movq caller2_stack=8(%rsp) +movq %r12,8(%rsp) + +# qhasm: caller3_stack = caller3 +# asm 1: movq caller3_stack=stack64#3 +# asm 2: movq caller3_stack=16(%rsp) +movq %r13,16(%rsp) + +# qhasm: caller4_stack = caller4 +# asm 1: movq caller4_stack=stack64#4 +# asm 2: movq caller4_stack=24(%rsp) +movq %r14,24(%rsp) + +# qhasm: caller5_stack = caller5 +# asm 1: movq caller5_stack=stack64#5 +# asm 2: movq caller5_stack=32(%rsp) +movq %r15,32(%rsp) + +# qhasm: caller6_stack = caller6 +# asm 1: movq caller6_stack=stack64#6 +# asm 2: movq caller6_stack=40(%rsp) +movq %rbx,40(%rsp) + +# qhasm: caller7_stack = caller7 +# asm 1: movq caller7_stack=stack64#7 +# asm 2: movq caller7_stack=48(%rsp) +movq %rbp,48(%rsp) + +# qhasm: yp = yp +# asm 1: mov yp=int64#4 +# asm 2: mov yp=%rcx +mov %rdx,%rcx + +# qhasm: r4 = 0 +# asm 1: mov $0,>r4=int64#5 +# asm 2: mov $0,>r4=%r8 +mov $0,%r8 + +# qhasm: r5 = 0 +# asm 1: mov $0,>r5=int64#6 +# asm 2: mov $0,>r5=%r9 +mov $0,%r9 + +# qhasm: r6 = 0 +# asm 1: mov $0,>r6=int64#8 +# asm 2: mov $0,>r6=%r10 +mov $0,%r10 + +# qhasm: r7 = 0 +# asm 1: mov $0,>r7=int64#9 +# asm 2: mov $0,>r7=%r11 +mov $0,%r11 + +# qhasm: zero = 0 +# asm 1: mov $0,>zero=int64#10 +# asm 2: mov $0,>zero=%r12 +mov $0,%r12 + +# qhasm: rax = *(uint64 *)(xp + 0) +# asm 1: movq 0(rax=int64#7 +# asm 2: movq 0(rax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 0) +# asm 1: mulq 0(r0=int64#11 +# asm 2: mov r0=%r13 +mov %rax,%r13 + +# qhasm: c = rdx +# asm 1: mov c=int64#12 +# asm 2: mov c=%r14 +mov %rdx,%r14 + +# qhasm: rax = *(uint64 *)(xp + 0) +# asm 1: movq 0(rax=int64#7 +# asm 2: movq 0(rax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 8) +# asm 1: mulq 8(r1=int64#13 +# asm 2: mov r1=%r15 +mov %rax,%r15 + +# qhasm: carry? r1 += c +# asm 1: add c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 0(rax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 16) +# asm 1: mulq 16(r2=int64#14 +# asm 2: mov r2=%rbx +mov %rax,%rbx + +# qhasm: carry? r2 += c +# asm 1: add c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 0(rax=%rax +movq 0(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 24) +# asm 1: mulq 24(r3=int64#15 +# asm 2: mov r3=%rbp +mov %rax,%rbp + +# qhasm: carry? r3 += c +# asm 1: add rax=int64#7 +# asm 2: movq 8(rax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 0) +# asm 1: mulq 0(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 8(rax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 8) +# asm 1: mulq 8(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 8(rax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 16) +# asm 1: mulq 16(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 8(rax=%rax +movq 8(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 24) +# asm 1: mulq 24(rax=int64#7 +# asm 2: movq 16(rax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 0) +# asm 1: mulq 0(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 16(rax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 8) +# asm 1: mulq 8(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 16(rax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 16) +# asm 1: mulq 16(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 16(rax=%rax +movq 16(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 24) +# asm 1: mulq 24(rax=int64#7 +# asm 2: movq 24(rax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 0) +# asm 1: mulq 0(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 24(rax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 8) +# asm 1: mulq 8(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 24(rax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 16) +# asm 1: mulq 16(c=int64#12 +# asm 2: mov $0,>c=%r14 +mov $0,%r14 + +# qhasm: c += rdx + carry +# asm 1: adc rax=int64#7 +# asm 2: movq 24(rax=%rax +movq 24(%rsi),%rax + +# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 24) +# asm 1: mulq 24(caller1=int64#9 +# asm 2: movq caller1=%r11 +movq 0(%rsp),%r11 + +# qhasm: caller2 = caller2_stack +# asm 1: movq caller2=int64#10 +# asm 2: movq caller2=%r12 +movq 8(%rsp),%r12 + +# qhasm: caller3 = caller3_stack +# asm 1: movq caller3=int64#11 +# asm 2: movq caller3=%r13 +movq 16(%rsp),%r13 + +# qhasm: caller4 = caller4_stack +# asm 1: movq caller4=int64#12 +# asm 2: movq caller4=%r14 +movq 24(%rsp),%r14 + +# qhasm: caller5 = caller5_stack +# asm 1: movq caller5=int64#13 +# asm 2: movq caller5=%r15 +movq 32(%rsp),%r15 + +# qhasm: caller6 = caller6_stack +# asm 1: movq caller6=int64#14 +# asm 2: movq caller6=%rbx +movq 40(%rsp),%rbx + +# qhasm: caller7 = caller7_stack +# asm 1: movq caller7=int64#15 +# asm 2: movq caller7=%rbp +movq 48(%rsp),%rbp + +# qhasm: leave +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret diff --git a/ext/hiredis-0.14.1/.gitignore b/ext/hiredis-0.14.1/.gitignore new file mode 100644 index 0000000..db2ad03 --- /dev/null +++ b/ext/hiredis-0.14.1/.gitignore @@ -0,0 +1,6 @@ +/hiredis-test +/examples/hiredis-example* +/*.o +/*.so +/*.dylib +/*.pc diff --git a/ext/hiredis-0.14.1/.travis.yml b/ext/hiredis-0.14.1/.travis.yml new file mode 100644 index 0000000..faf2ce6 --- /dev/null +++ b/ext/hiredis-0.14.1/.travis.yml @@ -0,0 +1,45 @@ +language: c +sudo: false +compiler: + - gcc + - clang + +os: + - linux + - osx + +branches: + only: + - staging + - trying + - master + +before_script: + - if [ "$TRAVIS_OS_NAME" == "osx" ] ; then brew update; brew install redis; fi + +addons: + apt: + packages: + - libc6-dbg + - libc6-dev + - libc6:i386 + - libc6-dev-i386 + - libc6-dbg:i386 + - gcc-multilib + - valgrind + +env: + - CFLAGS="-Werror" + - PRE="valgrind --track-origins=yes --leak-check=full" + - TARGET="32bit" TARGET_VARS="32bit-vars" CFLAGS="-Werror" + - TARGET="32bit" TARGET_VARS="32bit-vars" PRE="valgrind --track-origins=yes --leak-check=full" + +matrix: + exclude: + - os: osx + env: PRE="valgrind --track-origins=yes --leak-check=full" + + - os: osx + env: TARGET="32bit" TARGET_VARS="32bit-vars" PRE="valgrind --track-origins=yes --leak-check=full" + +script: make $TARGET CFLAGS="$CFLAGS" && make check PRE="$PRE" && make $TARGET_VARS hiredis-example diff --git a/ext/hiredis-0.14.1/CHANGELOG.md b/ext/hiredis-0.14.1/CHANGELOG.md new file mode 100644 index 0000000..f8e5773 --- /dev/null +++ b/ext/hiredis-0.14.1/CHANGELOG.md @@ -0,0 +1,190 @@ +**NOTE: BREAKING CHANGES upgrading from 0.13.x to 0.14.x **: + +* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now + protocol errors. This is consistent with the RESP specification. On 32-bit + platforms, the upper bound is lowered to `SIZE_MAX`. + +* Change `redisReply.len` to `size_t`, as it denotes the the size of a string + + User code should compare this to `size_t` values as well. If it was used to + compare to other values, casting might be necessary or can be removed, if + casting was applied before. + +### 0.14.1 (2020-03-13) + +* Adds safe allocation wrappers (CVE-2020-7105, #747, #752) (Michael Grunder) + +### 0.14.0 (2018-09-25) + +* Make string2ll static to fix conflict with Redis (Tom Lee [c3188b]) +* Use -dynamiclib instead of -shared for OSX (Ryan Schmidt [a65537]) +* Use string2ll from Redis w/added tests (Michael Grunder [7bef04, 60f622]) +* Makefile - OSX compilation fixes (Ryan Schmidt [881fcb, 0e9af8]) +* Remove redundant NULL checks (Justin Brewer [54acc8, 58e6b8]) +* Fix bulk and multi-bulk length truncation (Justin Brewer [109197]) +* Fix SIGSEGV in OpenBSD by checking for NULL before calling freeaddrinfo (Justin Brewer [546d94]) +* Several POSIX compatibility fixes (Justin Brewer [bbeab8, 49bbaa, d1c1b6]) +* Makefile - Compatibility fixes (Dimitri Vorobiev [3238cf, 12a9d1]) +* Makefile - Fix make install on FreeBSD (Zach Shipko [a2ef2b]) +* Makefile - don't assume $(INSTALL) is cp (Igor Gnatenko [725a96]) +* Separate side-effect causing function from assert and small cleanup (amallia [b46413, 3c3234]) +* Don't send negative values to `__redisAsyncCommand` (Frederik Deweerdt [706129]) +* Fix leak if setsockopt fails (Frederik Deweerdt [e21c9c]) +* Fix libevent leak (zfz [515228]) +* Clean up GCC warning (Ichito Nagata [2ec774]) +* Keep track of errno in `__redisSetErrorFromErrno()` as snprintf may use it (Jin Qing [25cd88]) +* Solaris compilation fix (Donald Whyte [41b07d]) +* Reorder linker arguments when building examples (Tustfarm-heart [06eedd]) +* Keep track of subscriptions in case of rapid subscribe/unsubscribe (Hyungjin Kim [073dc8, be76c5, d46999]) +* libuv use after free fix (Paul Scott [cbb956]) +* Properly close socket fd on reconnect attempt (WSL [64d1ec]) +* Skip valgrind in OSX tests (Jan-Erik Rediger [9deb78]) +* Various updates for Travis testing OSX (Ted Nyman [fa3774, 16a459, bc0ea5]) +* Update libevent (Chris Xin [386802]) +* Change sds.h for building in C++ projects (Ali Volkan ATLI [f5b32e]) +* Use proper format specifier in redisFormatSdsCommandArgv (Paulino Huerta, Jan-Erik Rediger [360a06, 8655a6]) +* Better handling of NULL reply in example code (Jan-Erik Rediger [1b8ed3]) +* Prevent overflow when formatting an error (Jan-Erik Rediger [0335cb]) +* Compatibility fix for strerror_r (Tom Lee [bb1747]) +* Properly detect integer parse/overflow errors (Justin Brewer [93421f]) +* Adds CI for Windows and cygwin fixes (owent, [6c53d6, 6c3e40]) +* Catch a buffer overflow when formatting the error message +* Import latest upstream sds. This breaks applications that are linked against the old hiredis v0.13 +* Fix warnings, when compiled with -Wshadow +* Make hiredis compile in Cygwin on Windows, now CI-tested + +**BREAKING CHANGES**: + +* Remove backwards compatibility macro's + +This removes the following old function aliases, use the new name now: + +| Old | New | +| --------------------------- | ---------------------- | +| redisReplyReaderCreate | redisReaderCreate | +| redisReplyReaderCreate | redisReaderCreate | +| redisReplyReaderFree | redisReaderFree | +| redisReplyReaderFeed | redisReaderFeed | +| redisReplyReaderGetReply | redisReaderGetReply | +| redisReplyReaderSetPrivdata | redisReaderSetPrivdata | +| redisReplyReaderGetObject | redisReaderGetObject | +| redisReplyReaderGetError | redisReaderGetError | + +* The `DEBUG` variable in the Makefile was renamed to `DEBUG_FLAGS` + +Previously it broke some builds for people that had `DEBUG` set to some arbitrary value, +due to debugging other software. +By renaming we avoid unintentional name clashes. + +Simply rename `DEBUG` to `DEBUG_FLAGS` in your environment to make it working again. + +### 0.13.3 (2015-09-16) + +* Revert "Clear `REDIS_CONNECTED` flag when connection is closed". +* Make tests pass on FreeBSD (Thanks, Giacomo Olgeni) + + +If the `REDIS_CONNECTED` flag is cleared, +the async onDisconnect callback function will never be called. +This causes problems as the disconnect is never reported back to the user. + +### 0.13.2 (2015-08-25) + +* Prevent crash on pending replies in async code (Thanks, @switch-st) +* Clear `REDIS_CONNECTED` flag when connection is closed (Thanks, Jerry Jacobs) +* Add MacOS X addapter (Thanks, @dizzus) +* Add Qt adapter (Thanks, Pietro Cerutti) +* Add Ivykis adapter (Thanks, Gergely Nagy) + +All adapters are provided as is and are only tested where possible. + +### 0.13.1 (2015-05-03) + +This is a bug fix release. +The new `reconnect` method introduced new struct members, which clashed with pre-defined names in pre-C99 code. +Another commit forced C99 compilation just to make it work, but of course this is not desirable for outside projects. +Other non-C99 code can now use hiredis as usual again. +Sorry for the inconvenience. + +* Fix memory leak in async reply handling (Salvatore Sanfilippo) +* Rename struct member to avoid name clash with pre-c99 code (Alex Balashov, ncopa) + +### 0.13.0 (2015-04-16) + +This release adds a minimal Windows compatibility layer. +The parser, standalone since v0.12.0, can now be compiled on Windows +(and thus used in other client libraries as well) + +* Windows compatibility layer for parser code (tzickel) +* Properly escape data printed to PKGCONF file (Dan Skorupski) +* Fix tests when assert() undefined (Keith Bennett, Matt Stancliff) +* Implement a reconnect method for the client context, this changes the structure of `redisContext` (Aaron Bedra) + +### 0.12.1 (2015-01-26) + +* Fix `make install`: DESTDIR support, install all required files, install PKGCONF in proper location +* Fix `make test` as 32 bit build on 64 bit platform + +### 0.12.0 (2015-01-22) + +* Add optional KeepAlive support + +* Try again on EINTR errors + +* Add libuv adapter + +* Add IPv6 support + +* Remove possibility of multiple close on same fd + +* Add ability to bind source address on connect + +* Add redisConnectFd() and redisFreeKeepFd() + +* Fix getaddrinfo() memory leak + +* Free string if it is unused (fixes memory leak) + +* Improve redisAppendCommandArgv performance 2.5x + +* Add support for SO_REUSEADDR + +* Fix redisvFormatCommand format parsing + +* Add GLib 2.0 adapter + +* Refactor reading code into read.c + +* Fix errno error buffers to not clobber errors + +* Generate pkgconf during build + +* Silence _BSD_SOURCE warnings + +* Improve digit counting for multibulk creation + + +### 0.11.0 + +* Increase the maximum multi-bulk reply depth to 7. + +* Increase the read buffer size from 2k to 16k. + +* Use poll(2) instead of select(2) to support large fds (>= 1024). + +### 0.10.1 + +* Makefile overhaul. Important to check out if you override one or more + variables using environment variables or via arguments to the "make" tool. + +* Issue #45: Fix potential memory leak for a multi bulk reply with 0 elements + being created by the default reply object functions. + +* Issue #43: Don't crash in an asynchronous context when Redis returns an error + reply after the connection has been made (this happens when the maximum + number of connections is reached). + +### 0.10.0 + +* See commit log. + diff --git a/ext/hiredis-0.14.1/COPYING b/ext/hiredis-0.14.1/COPYING new file mode 100644 index 0000000..a5fc973 --- /dev/null +++ b/ext/hiredis-0.14.1/COPYING @@ -0,0 +1,29 @@ +Copyright (c) 2009-2011, Salvatore Sanfilippo +Copyright (c) 2010-2011, Pieter Noordhuis + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of Redis nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ext/hiredis-0.14.1/Makefile b/ext/hiredis-0.14.1/Makefile new file mode 100644 index 0000000..d1f005a --- /dev/null +++ b/ext/hiredis-0.14.1/Makefile @@ -0,0 +1,214 @@ +# Hiredis Makefile +# Copyright (C) 2010-2011 Salvatore Sanfilippo +# Copyright (C) 2010-2011 Pieter Noordhuis +# This file is released under the BSD license, see the COPYING file + +OBJ=net.o hiredis.o sds.o async.o read.o alloc.o +EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib +TESTS=hiredis-test +LIBNAME=libhiredis +PKGCONFNAME=hiredis.pc + +HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}') +HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}') +HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}') +HIREDIS_SONAME=$(shell grep HIREDIS_SONAME hiredis.h | awk '{print $$3}') + +# Installation related variables and target +PREFIX?=/usr/local +INCLUDE_PATH?=include/hiredis +LIBRARY_PATH?=lib +PKGCONF_PATH?=pkgconfig +INSTALL_INCLUDE_PATH= $(DESTDIR)$(PREFIX)/$(INCLUDE_PATH) +INSTALL_LIBRARY_PATH= $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH) +INSTALL_PKGCONF_PATH= $(INSTALL_LIBRARY_PATH)/$(PKGCONF_PATH) + +# redis-server configuration used for testing +REDIS_PORT=56379 +REDIS_SERVER=redis-server +define REDIS_TEST_CONFIG + daemonize yes + pidfile /tmp/hiredis-test-redis.pid + port $(REDIS_PORT) + bind 127.0.0.1 + unixsocket /tmp/hiredis-test-redis.sock +endef +export REDIS_TEST_CONFIG + +# Fallback to gcc when $CC is not in $PATH. +CC:=$(shell sh -c 'type $${CC%% *} >/dev/null 2>/dev/null && echo $(CC) || echo gcc') +CXX:=$(shell sh -c 'type $${CXX%% *} >/dev/null 2>/dev/null && echo $(CXX) || echo g++') +OPTIMIZATION?=-O3 +WARNINGS=-Wall -W -Wstrict-prototypes -Wwrite-strings +DEBUG_FLAGS?= -g -ggdb +REAL_CFLAGS=$(OPTIMIZATION) -fPIC $(CFLAGS) $(WARNINGS) $(DEBUG_FLAGS) +REAL_LDFLAGS=$(LDFLAGS) + +DYLIBSUFFIX=so +STLIBSUFFIX=a +DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME) +DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR) +DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX) +DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS) +STLIBNAME=$(LIBNAME).$(STLIBSUFFIX) +STLIB_MAKE_CMD=ar rcs $(STLIBNAME) + +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') +ifeq ($(uname_S),SunOS) + REAL_LDFLAGS+= -ldl -lnsl -lsocket + DYLIB_MAKE_CMD=$(CC) -G -o $(DYLIBNAME) -h $(DYLIB_MINOR_NAME) $(LDFLAGS) +endif +ifeq ($(uname_S),Darwin) + DYLIBSUFFIX=dylib + DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_SONAME).$(DYLIBSUFFIX) + DYLIB_MAKE_CMD=$(CC) -dynamiclib -Wl,-install_name,$(PREFIX)/$(LIBRARY_PATH)/$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS) +endif + +all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME) + +# Deps (use make dep to generate this) +alloc.o: alloc.c fmacros.h alloc.h +async.o: async.c fmacros.h alloc.h async.h hiredis.h read.h sds.h net.h dict.c dict.h +dict.o: dict.c fmacros.h alloc.h dict.h +hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h alloc.h net.h +net.o: net.c fmacros.h net.h hiredis.h read.h sds.h alloc.h +read.o: read.c fmacros.h read.h sds.h +sds.o: sds.c sds.h sdsalloc.h +test.o: test.c fmacros.h hiredis.h read.h sds.h alloc.h net.h + +$(DYLIBNAME): $(OBJ) + $(DYLIB_MAKE_CMD) $(OBJ) + +$(STLIBNAME): $(OBJ) + $(STLIB_MAKE_CMD) $(OBJ) + +dynamic: $(DYLIBNAME) +static: $(STLIBNAME) + +# Binaries: +hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -levent $(STLIBNAME) + +hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -lev $(STLIBNAME) + +hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(shell pkg-config --cflags --libs glib-2.0) $(STLIBNAME) + +hiredis-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -livykis $(STLIBNAME) + +hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -framework CoreFoundation $(STLIBNAME) + +ifndef AE_DIR +hiredis-example-ae: + @echo "Please specify AE_DIR (e.g. /src)" + @false +else +hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME) +endif + +ifndef LIBUV_DIR +hiredis-example-libuv: + @echo "Please specify LIBUV_DIR (e.g. ../libuv/)" + @false +else +hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread -lrt $(STLIBNAME) +endif + +ifeq ($(and $(QT_MOC),$(QT_INCLUDE_DIR),$(QT_LIBRARY_DIR)),) +hiredis-example-qt: + @echo "Please specify QT_MOC, QT_INCLUDE_DIR AND QT_LIBRARY_DIR" + @false +else +hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME) + $(QT_MOC) adapters/qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ + $(CXX) -x c++ -o qt-adapter-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore + $(QT_MOC) examples/example-qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ + $(CXX) -x c++ -o qt-example-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore + $(CXX) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore -L$(QT_LIBRARY_DIR) qt-adapter-moc.o qt-example-moc.o $< -pthread $(STLIBNAME) -lQtCore +endif + +hiredis-example: examples/example.c $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(STLIBNAME) + +examples: $(EXAMPLES) + +hiredis-test: test.o $(STLIBNAME) + +hiredis-%: %.o $(STLIBNAME) + $(CC) $(REAL_CFLAGS) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME) + +test: hiredis-test + ./hiredis-test + +check: hiredis-test + @echo "$$REDIS_TEST_CONFIG" | $(REDIS_SERVER) - + $(PRE) ./hiredis-test -h 127.0.0.1 -p $(REDIS_PORT) -s /tmp/hiredis-test-redis.sock || \ + ( kill `cat /tmp/hiredis-test-redis.pid` && false ) + kill `cat /tmp/hiredis-test-redis.pid` + +.c.o: + $(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $< + +clean: + rm -rf $(DYLIBNAME) $(STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov + +dep: + $(CC) -MM *.c + +INSTALL?= cp -pPR + +$(PKGCONFNAME): hiredis.h + @echo "Generating $@ for pkgconfig..." + @echo prefix=$(PREFIX) > $@ + @echo exec_prefix=\$${prefix} >> $@ + @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@ + @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ + @echo >> $@ + @echo Name: hiredis >> $@ + @echo Description: Minimalistic C client library for Redis. >> $@ + @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ + @echo Libs: -L\$${libdir} -lhiredis >> $@ + @echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@ + +install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME) + mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH) + $(INSTALL) hiredis.h async.h read.h sds.h alloc.h $(INSTALL_INCLUDE_PATH) + $(INSTALL) adapters/*.h $(INSTALL_INCLUDE_PATH)/adapters + $(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME) + cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME) + $(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH) + mkdir -p $(INSTALL_PKGCONF_PATH) + $(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH) + +32bit: + @echo "" + @echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386" + @echo "" + $(MAKE) CFLAGS="-m32" LDFLAGS="-m32" + +32bit-vars: + $(eval CFLAGS=-m32) + $(eval LDFLAGS=-m32) + +gprof: + $(MAKE) CFLAGS="-pg" LDFLAGS="-pg" + +gcov: + $(MAKE) CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs" + +coverage: gcov + make check + mkdir -p tmp/lcov + lcov -d . -c -o tmp/lcov/hiredis.info + genhtml --legend -o tmp/lcov/report tmp/lcov/hiredis.info + +noopt: + $(MAKE) OPTIMIZATION="" + +.PHONY: all test check clean dep install 32bit 32bit-vars gprof gcov noopt diff --git a/ext/hiredis-0.14.1/README.md b/ext/hiredis-0.14.1/README.md new file mode 100644 index 0000000..50e2e6b --- /dev/null +++ b/ext/hiredis-0.14.1/README.md @@ -0,0 +1,410 @@ +[![Build Status](https://travis-ci.org/redis/hiredis.png)](https://travis-ci.org/redis/hiredis) + +**This Readme reflects the latest changed in the master branch. See [v0.14.1](https://github.com/redis/hiredis/tree/v0.14.1) for the Readme and documentation for the latest release.** + +# HIREDIS + +Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database. + +It is minimalistic because it just adds minimal support for the protocol, but +at the same time it uses a high level printf-alike API in order to make it +much higher level than otherwise suggested by its minimal code base and the +lack of explicit bindings for every Redis command. + +Apart from supporting sending commands and receiving replies, it comes with +a reply parser that is decoupled from the I/O layer. It +is a stream parser designed for easy reusability, which can for instance be used +in higher level language bindings for efficient reply parsing. + +Hiredis only supports the binary-safe Redis protocol, so you can use it with any +Redis version >= 1.2.0. + +The library comes with multiple APIs. There is the +*synchronous API*, the *asynchronous API* and the *reply parsing API*. + +## IMPORTANT: Breaking changes when upgrading from 0.13.x -> 0.14.x + +Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now +protocol errors. This is consistent with the RESP specification. On 32-bit +platforms, the upper bound is lowered to `SIZE_MAX`. + +Change `redisReply.len` to `size_t`, as it denotes the the size of a string + +User code should compare this to `size_t` values as well. If it was used to +compare to other values, casting might be necessary or can be removed, if +casting was applied before. + +For a detailed list of changes please view our [Changelog](CHANGELOG.md). + +## Synchronous API + +To consume the synchronous API, there are only a few function calls that need to be introduced: + +```c +redisContext *redisConnect(const char *ip, int port); +void *redisCommand(redisContext *c, const char *format, ...); +void freeReplyObject(void *reply); +``` + +### Connecting + +The function `redisConnect` is used to create a so-called `redisContext`. The +context is where Hiredis holds state for a connection. The `redisContext` +struct has an integer `err` field that is non-zero when the connection is in +an error state. The field `errstr` will contain a string with a description of +the error. More information on errors can be found in the **Errors** section. +After trying to connect to Redis using `redisConnect` you should +check the `err` field to see if establishing the connection was successful: +```c +redisContext *c = redisConnect("127.0.0.1", 6379); +if (c == NULL || c->err) { + if (c) { + printf("Error: %s\n", c->errstr); + // handle error + } else { + printf("Can't allocate redis context\n"); + } +} +``` + +*Note: A `redisContext` is not thread-safe.* + +### Sending commands + +There are several ways to issue commands to Redis. The first that will be introduced is +`redisCommand`. This function takes a format similar to printf. In the simplest form, +it is used like this: +```c +reply = redisCommand(context, "SET foo bar"); +``` + +The specifier `%s` interpolates a string in the command, and uses `strlen` to +determine the length of the string: +```c +reply = redisCommand(context, "SET foo %s", value); +``` +When you need to pass binary safe strings in a command, the `%b` specifier can be +used. Together with a pointer to the string, it requires a `size_t` length argument +of the string: +```c +reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen); +``` +Internally, Hiredis splits the command in different arguments and will +convert it to the protocol used to communicate with Redis. +One or more spaces separates arguments, so you can use the specifiers +anywhere in an argument: +```c +reply = redisCommand(context, "SET key:%s %s", myid, value); +``` + +### Using replies + +The return value of `redisCommand` holds a reply when the command was +successfully executed. When an error occurs, the return value is `NULL` and +the `err` field in the context will be set (see section on **Errors**). +Once an error is returned the context cannot be reused and you should set up +a new connection. + +The standard replies that `redisCommand` are of the type `redisReply`. The +`type` field in the `redisReply` should be used to test what kind of reply +was received: + +* **`REDIS_REPLY_STATUS`**: + * The command replied with a status reply. The status string can be accessed using `reply->str`. + The length of this string can be accessed using `reply->len`. + +* **`REDIS_REPLY_ERROR`**: + * The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`. + +* **`REDIS_REPLY_INTEGER`**: + * The command replied with an integer. The integer value can be accessed using the + `reply->integer` field of type `long long`. + +* **`REDIS_REPLY_NIL`**: + * The command replied with a **nil** object. There is no data to access. + +* **`REDIS_REPLY_STRING`**: + * A bulk (string) reply. The value of the reply can be accessed using `reply->str`. + The length of this string can be accessed using `reply->len`. + +* **`REDIS_REPLY_ARRAY`**: + * A multi bulk reply. The number of elements in the multi bulk reply is stored in + `reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well + and can be accessed via `reply->element[..index..]`. + Redis may reply with nested arrays but this is fully supported. + +Replies should be freed using the `freeReplyObject()` function. +Note that this function will take care of freeing sub-reply objects +contained in arrays and nested arrays, so there is no need for the user to +free the sub replies (it is actually harmful and will corrupt the memory). + +**Important:** the current version of hiredis (0.10.0) frees replies when the +asynchronous API is used. This means you should not call `freeReplyObject` when +you use this API. The reply is cleaned up by hiredis _after_ the callback +returns. This behavior will probably change in future releases, so make sure to +keep an eye on the changelog when upgrading (see issue #39). + +### Cleaning up + +To disconnect and free the context the following function can be used: +```c +void redisFree(redisContext *c); +``` +This function immediately closes the socket and then frees the allocations done in +creating the context. + +### Sending commands (cont'd) + +Together with `redisCommand`, the function `redisCommandArgv` can be used to issue commands. +It has the following prototype: +```c +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +``` +It takes the number of arguments `argc`, an array of strings `argv` and the lengths of the +arguments `argvlen`. For convenience, `argvlen` may be set to `NULL` and the function will +use `strlen(3)` on every argument to determine its length. Obviously, when any of the arguments +need to be binary safe, the entire array of lengths `argvlen` should be provided. + +The return value has the same semantic as `redisCommand`. + +### Pipelining + +To explain how Hiredis supports pipelining in a blocking connection, there needs to be +understanding of the internal execution flow. + +When any of the functions in the `redisCommand` family is called, Hiredis first formats the +command according to the Redis protocol. The formatted command is then put in the output buffer +of the context. This output buffer is dynamic, so it can hold any number of commands. +After the command is put in the output buffer, `redisGetReply` is called. This function has the +following two execution paths: + +1. The input buffer is non-empty: + * Try to parse a single reply from the input buffer and return it + * If no reply could be parsed, continue at *2* +2. The input buffer is empty: + * Write the **entire** output buffer to the socket + * Read from the socket until a single reply could be parsed + +The function `redisGetReply` is exported as part of the Hiredis API and can be used when a reply +is expected on the socket. To pipeline commands, the only things that needs to be done is +filling up the output buffer. For this cause, two commands can be used that are identical +to the `redisCommand` family, apart from not returning a reply: +```c +void redisAppendCommand(redisContext *c, const char *format, ...); +void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +``` +After calling either function one or more times, `redisGetReply` can be used to receive the +subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_ERR`, where +the latter means an error occurred while reading a reply. Just as with the other commands, +the `err` field in the context can be used to find out what the cause of this error is. + +The following examples shows a simple pipeline (resulting in only a single call to `write(2)` and +a single call to `read(2)`): +```c +redisReply *reply; +redisAppendCommand(context,"SET foo bar"); +redisAppendCommand(context,"GET foo"); +redisGetReply(context,&reply); // reply for SET +freeReplyObject(reply); +redisGetReply(context,&reply); // reply for GET +freeReplyObject(reply); +``` +This API can also be used to implement a blocking subscriber: +```c +reply = redisCommand(context,"SUBSCRIBE foo"); +freeReplyObject(reply); +while(redisGetReply(context,&reply) == REDIS_OK) { + // consume message + freeReplyObject(reply); +} +``` +### Errors + +When a function call is not successful, depending on the function either `NULL` or `REDIS_ERR` is +returned. The `err` field inside the context will be non-zero and set to one of the +following constants: + +* **`REDIS_ERR_IO`**: + There was an I/O error while creating the connection, trying to write + to the socket or read from the socket. If you included `errno.h` in your + application, you can use the global `errno` variable to find out what is + wrong. + +* **`REDIS_ERR_EOF`**: + The server closed the connection which resulted in an empty read. + +* **`REDIS_ERR_PROTOCOL`**: + There was an error while parsing the protocol. + +* **`REDIS_ERR_OTHER`**: + Any other error. Currently, it is only used when a specified hostname to connect + to cannot be resolved. + +In every case, the `errstr` field in the context will be set to hold a string representation +of the error. + +## Asynchronous API + +Hiredis comes with an asynchronous API that works easily with any event library. +Examples are bundled that show using Hiredis with [libev](http://software.schmorp.de/pkg/libev.html) +and [libevent](http://monkey.org/~provos/libevent/). + +### Connecting + +The function `redisAsyncConnect` can be used to establish a non-blocking connection to +Redis. It returns a pointer to the newly created `redisAsyncContext` struct. The `err` field +should be checked after creation to see if there were errors creating the connection. +Because the connection that will be created is non-blocking, the kernel is not able to +instantly return if the specified host and port is able to accept a connection. + +*Note: A `redisAsyncContext` is not thread-safe.* + +```c +redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); +if (c->err) { + printf("Error: %s\n", c->errstr); + // handle error +} +``` + +The asynchronous context can hold a disconnect callback function that is called when the +connection is disconnected (either because of an error or per user request). This function should +have the following prototype: +```c +void(const redisAsyncContext *c, int status); +``` +On a disconnect, the `status` argument is set to `REDIS_OK` when disconnection was initiated by the +user, or `REDIS_ERR` when the disconnection was caused by an error. When it is `REDIS_ERR`, the `err` +field in the context can be accessed to find out the cause of the error. + +The context object is always freed after the disconnect callback fired. When a reconnect is needed, +the disconnect callback is a good point to do so. + +Setting the disconnect callback can only be done once per context. For subsequent calls it will +return `REDIS_ERR`. The function to set the disconnect callback has the following prototype: +```c +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); +``` +### Sending commands and their callbacks + +In an asynchronous context, commands are automatically pipelined due to the nature of an event loop. +Therefore, unlike the synchronous API, there is only a single way to send commands. +Because commands are sent to Redis asynchronously, issuing a command requires a callback function +that is called when the reply is received. Reply callbacks should have the following prototype: +```c +void(redisAsyncContext *c, void *reply, void *privdata); +``` +The `privdata` argument can be used to curry arbitrary data to the callback from the point where +the command is initially queued for execution. + +The functions that can be used to issue commands in an asynchronous context are: +```c +int redisAsyncCommand( + redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, + const char *format, ...); +int redisAsyncCommandArgv( + redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, + int argc, const char **argv, const size_t *argvlen); +``` +Both functions work like their blocking counterparts. The return value is `REDIS_OK` when the command +was successfully added to the output buffer and `REDIS_ERR` otherwise. Example: when the connection +is being disconnected per user-request, no new commands may be added to the output buffer and `REDIS_ERR` is +returned on calls to the `redisAsyncCommand` family. + +If the reply for a command with a `NULL` callback is read, it is immediately freed. When the callback +for a command is non-`NULL`, the memory is freed immediately following the callback: the reply is only +valid for the duration of the callback. + +All pending callbacks are called with a `NULL` reply when the context encountered an error. + +### Disconnecting + +An asynchronous connection can be terminated using: +```c +void redisAsyncDisconnect(redisAsyncContext *ac); +``` +When this function is called, the connection is **not** immediately terminated. Instead, new +commands are no longer accepted and the connection is only terminated when all pending commands +have been written to the socket, their respective replies have been read and their respective +callbacks have been executed. After this, the disconnection callback is executed with the +`REDIS_OK` status and the context object is freed. + +### Hooking it up to event library *X* + +There are a few hooks that need to be set on the context object after it is created. +See the `adapters/` directory for bindings to *libev* and *libevent*. + +## Reply parsing API + +Hiredis comes with a reply parsing API that makes it easy for writing higher +level language bindings. + +The reply parsing API consists of the following functions: +```c +redisReader *redisReaderCreate(void); +void redisReaderFree(redisReader *reader); +int redisReaderFeed(redisReader *reader, const char *buf, size_t len); +int redisReaderGetReply(redisReader *reader, void **reply); +``` +The same set of functions are used internally by hiredis when creating a +normal Redis context, the above API just exposes it to the user for a direct +usage. + +### Usage + +The function `redisReaderCreate` creates a `redisReader` structure that holds a +buffer with unparsed data and state for the protocol parser. + +Incoming data -- most likely from a socket -- can be placed in the internal +buffer of the `redisReader` using `redisReaderFeed`. This function will make a +copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed +when `redisReaderGetReply` is called. This function returns an integer status +and a reply object (as described above) via `void **reply`. The returned status +can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went +wrong (either a protocol error, or an out of memory error). + +The parser limits the level of nesting for multi bulk payloads to 7. If the +multi bulk nesting level is higher than this, the parser returns an error. + +### Customizing replies + +The function `redisReaderGetReply` creates `redisReply` and makes the function +argument `reply` point to the created `redisReply` variable. For instance, if +the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply` +will hold the status as a vanilla C string. However, the functions that are +responsible for creating instances of the `redisReply` can be customized by +setting the `fn` field on the `redisReader` struct. This should be done +immediately after creating the `redisReader`. + +For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c) +uses customized reply object functions to create Ruby objects. + +### Reader max buffer + +Both when using the Reader API directly or when using it indirectly via a +normal Redis context, the redisReader structure uses a buffer in order to +accumulate data from the server. +Usually this buffer is destroyed when it is empty and is larger than 16 +KiB in order to avoid wasting memory in unused buffers + +However when working with very big payloads destroying the buffer may slow +down performances considerably, so it is possible to modify the max size of +an idle buffer changing the value of the `maxbuf` field of the reader structure +to the desired value. The special value of 0 means that there is no maximum +value for an idle buffer, so the buffer will never get freed. + +For instance if you have a normal Redis context you can set the maximum idle +buffer to zero (unlimited) just with: +```c +context->reader->maxbuf = 0; +``` +This should be done only in order to maximize performances when working with +large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again +as soon as possible in order to prevent allocation of useless memory. + +## AUTHORS + +Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and +Pieter Noordhuis (pcnoordhuis at gmail) and is released under the BSD license. +Hiredis is currently maintained by Matt Stancliff (matt at genges dot com) and +Jan-Erik Rediger (janerik at fnordig dot com) diff --git a/ext/hiredis-0.14.1/adapters/ae.h b/ext/hiredis-0.14.1/adapters/ae.h new file mode 100644 index 0000000..0393992 --- /dev/null +++ b/ext/hiredis-0.14.1/adapters/ae.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_AE_H__ +#define __HIREDIS_AE_H__ +#include +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisAeEvents { + redisAsyncContext *context; + aeEventLoop *loop; + int fd; + int reading, writing; +} redisAeEvents; + +static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { + ((void)el); ((void)fd); ((void)mask); + + redisAeEvents *e = (redisAeEvents*)privdata; + redisAsyncHandleRead(e->context); +} + +static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { + ((void)el); ((void)fd); ((void)mask); + + redisAeEvents *e = (redisAeEvents*)privdata; + redisAsyncHandleWrite(e->context); +} + +static void redisAeAddRead(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (!e->reading) { + e->reading = 1; + aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); + } +} + +static void redisAeDelRead(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (e->reading) { + e->reading = 0; + aeDeleteFileEvent(loop,e->fd,AE_READABLE); + } +} + +static void redisAeAddWrite(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (!e->writing) { + e->writing = 1; + aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e); + } +} + +static void redisAeDelWrite(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (e->writing) { + e->writing = 0; + aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); + } +} + +static void redisAeCleanup(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + redisAeDelRead(privdata); + redisAeDelWrite(privdata); + free(e); +} + +static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisAeEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisAeEvents*)hi_malloc(sizeof(*e)); + e->context = ac; + e->loop = loop; + e->fd = c->fd; + e->reading = e->writing = 0; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisAeAddRead; + ac->ev.delRead = redisAeDelRead; + ac->ev.addWrite = redisAeAddWrite; + ac->ev.delWrite = redisAeDelWrite; + ac->ev.cleanup = redisAeCleanup; + ac->ev.data = e; + + return REDIS_OK; +} +#endif diff --git a/ext/hiredis-0.14.1/adapters/glib.h b/ext/hiredis-0.14.1/adapters/glib.h new file mode 100644 index 0000000..e0a6411 --- /dev/null +++ b/ext/hiredis-0.14.1/adapters/glib.h @@ -0,0 +1,153 @@ +#ifndef __HIREDIS_GLIB_H__ +#define __HIREDIS_GLIB_H__ + +#include + +#include "../hiredis.h" +#include "../async.h" + +typedef struct +{ + GSource source; + redisAsyncContext *ac; + GPollFD poll_fd; +} RedisSource; + +static void +redis_source_add_read (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events |= G_IO_IN; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_del_read (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events &= ~G_IO_IN; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_add_write (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events |= G_IO_OUT; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_del_write (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events &= ~G_IO_OUT; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_cleanup (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + + g_return_if_fail(source); + + redis_source_del_read(source); + redis_source_del_write(source); + /* + * It is not our responsibility to remove ourself from the + * current main loop. However, we will remove the GPollFD. + */ + if (source->poll_fd.fd >= 0) { + g_source_remove_poll((GSource *)data, &source->poll_fd); + source->poll_fd.fd = -1; + } +} + +static gboolean +redis_source_prepare (GSource *source, + gint *timeout_) +{ + RedisSource *redis = (RedisSource *)source; + *timeout_ = -1; + return !!(redis->poll_fd.events & redis->poll_fd.revents); +} + +static gboolean +redis_source_check (GSource *source) +{ + RedisSource *redis = (RedisSource *)source; + return !!(redis->poll_fd.events & redis->poll_fd.revents); +} + +static gboolean +redis_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + RedisSource *redis = (RedisSource *)source; + + if ((redis->poll_fd.revents & G_IO_OUT)) { + redisAsyncHandleWrite(redis->ac); + redis->poll_fd.revents &= ~G_IO_OUT; + } + + if ((redis->poll_fd.revents & G_IO_IN)) { + redisAsyncHandleRead(redis->ac); + redis->poll_fd.revents &= ~G_IO_IN; + } + + if (callback) { + return callback(user_data); + } + + return TRUE; +} + +static void +redis_source_finalize (GSource *source) +{ + RedisSource *redis = (RedisSource *)source; + + if (redis->poll_fd.fd >= 0) { + g_source_remove_poll(source, &redis->poll_fd); + redis->poll_fd.fd = -1; + } +} + +static GSource * +redis_source_new (redisAsyncContext *ac) +{ + static GSourceFuncs source_funcs = { + .prepare = redis_source_prepare, + .check = redis_source_check, + .dispatch = redis_source_dispatch, + .finalize = redis_source_finalize, + }; + redisContext *c = &ac->c; + RedisSource *source; + + g_return_val_if_fail(ac != NULL, NULL); + + source = (RedisSource *)g_source_new(&source_funcs, sizeof *source); + source->ac = ac; + source->poll_fd.fd = c->fd; + source->poll_fd.events = 0; + source->poll_fd.revents = 0; + g_source_add_poll((GSource *)source, &source->poll_fd); + + ac->ev.addRead = redis_source_add_read; + ac->ev.delRead = redis_source_del_read; + ac->ev.addWrite = redis_source_add_write; + ac->ev.delWrite = redis_source_del_write; + ac->ev.cleanup = redis_source_cleanup; + ac->ev.data = source; + + return (GSource *)source; +} + +#endif /* __HIREDIS_GLIB_H__ */ diff --git a/ext/hiredis-0.14.1/adapters/ivykis.h b/ext/hiredis-0.14.1/adapters/ivykis.h new file mode 100644 index 0000000..75616ee --- /dev/null +++ b/ext/hiredis-0.14.1/adapters/ivykis.h @@ -0,0 +1,81 @@ +#ifndef __HIREDIS_IVYKIS_H__ +#define __HIREDIS_IVYKIS_H__ +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisIvykisEvents { + redisAsyncContext *context; + struct iv_fd fd; +} redisIvykisEvents; + +static void redisIvykisReadEvent(void *arg) { + redisAsyncContext *context = (redisAsyncContext *)arg; + redisAsyncHandleRead(context); +} + +static void redisIvykisWriteEvent(void *arg) { + redisAsyncContext *context = (redisAsyncContext *)arg; + redisAsyncHandleWrite(context); +} + +static void redisIvykisAddRead(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent); +} + +static void redisIvykisDelRead(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_in(&e->fd, NULL); +} + +static void redisIvykisAddWrite(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent); +} + +static void redisIvykisDelWrite(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_out(&e->fd, NULL); +} + +static void redisIvykisCleanup(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + + iv_fd_unregister(&e->fd); + free(e); +} + +static int redisIvykisAttach(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisIvykisEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisIvykisEvents*)hi_malloc(sizeof(*e)); + e->context = ac; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisIvykisAddRead; + ac->ev.delRead = redisIvykisDelRead; + ac->ev.addWrite = redisIvykisAddWrite; + ac->ev.delWrite = redisIvykisDelWrite; + ac->ev.cleanup = redisIvykisCleanup; + ac->ev.data = e; + + /* Initialize and install read/write events */ + IV_FD_INIT(&e->fd); + e->fd.fd = c->fd; + e->fd.handler_in = redisIvykisReadEvent; + e->fd.handler_out = redisIvykisWriteEvent; + e->fd.handler_err = NULL; + e->fd.cookie = e->context; + + iv_fd_register(&e->fd); + + return REDIS_OK; +} +#endif diff --git a/ext/hiredis-0.14.1/adapters/libev.h b/ext/hiredis-0.14.1/adapters/libev.h new file mode 100644 index 0000000..abad436 --- /dev/null +++ b/ext/hiredis-0.14.1/adapters/libev.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_LIBEV_H__ +#define __HIREDIS_LIBEV_H__ +#include +#include +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisLibevEvents { + redisAsyncContext *context; + struct ev_loop *loop; + int reading, writing; + ev_io rev, wev; +} redisLibevEvents; + +static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { +#if EV_MULTIPLICITY + ((void)loop); +#endif + ((void)revents); + + redisLibevEvents *e = (redisLibevEvents*)watcher->data; + redisAsyncHandleRead(e->context); +} + +static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { +#if EV_MULTIPLICITY + ((void)loop); +#endif + ((void)revents); + + redisLibevEvents *e = (redisLibevEvents*)watcher->data; + redisAsyncHandleWrite(e->context); +} + +static void redisLibevAddRead(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (!e->reading) { + e->reading = 1; + ev_io_start(EV_A_ &e->rev); + } +} + +static void redisLibevDelRead(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (e->reading) { + e->reading = 0; + ev_io_stop(EV_A_ &e->rev); + } +} + +static void redisLibevAddWrite(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (!e->writing) { + e->writing = 1; + ev_io_start(EV_A_ &e->wev); + } +} + +static void redisLibevDelWrite(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (e->writing) { + e->writing = 0; + ev_io_stop(EV_A_ &e->wev); + } +} + +static void redisLibevCleanup(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + redisLibevDelRead(privdata); + redisLibevDelWrite(privdata); + free(e); +} + +static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisLibevEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisLibevEvents*)hi_malloc(sizeof(*e)); + e->context = ac; +#if EV_MULTIPLICITY + e->loop = loop; +#else + e->loop = NULL; +#endif + e->reading = e->writing = 0; + e->rev.data = e; + e->wev.data = e; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisLibevAddRead; + ac->ev.delRead = redisLibevDelRead; + ac->ev.addWrite = redisLibevAddWrite; + ac->ev.delWrite = redisLibevDelWrite; + ac->ev.cleanup = redisLibevCleanup; + ac->ev.data = e; + + /* Initialize read/write events */ + ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); + ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); + return REDIS_OK; +} + +#endif diff --git a/ext/hiredis-0.14.1/adapters/libevent.h b/ext/hiredis-0.14.1/adapters/libevent.h new file mode 100644 index 0000000..f2330d6 --- /dev/null +++ b/ext/hiredis-0.14.1/adapters/libevent.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_LIBEVENT_H__ +#define __HIREDIS_LIBEVENT_H__ +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisLibeventEvents { + redisAsyncContext *context; + struct event *rev, *wev; +} redisLibeventEvents; + +static void redisLibeventReadEvent(int fd, short event, void *arg) { + ((void)fd); ((void)event); + redisLibeventEvents *e = (redisLibeventEvents*)arg; + redisAsyncHandleRead(e->context); +} + +static void redisLibeventWriteEvent(int fd, short event, void *arg) { + ((void)fd); ((void)event); + redisLibeventEvents *e = (redisLibeventEvents*)arg; + redisAsyncHandleWrite(e->context); +} + +static void redisLibeventAddRead(void *privdata) { + redisLibeventEvents *e = (redisLibeventEvents*)privdata; + event_add(e->rev,NULL); +} + +static void redisLibeventDelRead(void *privdata) { + redisLibeventEvents *e = (redisLibeventEvents*)privdata; + event_del(e->rev); +} + +static void redisLibeventAddWrite(void *privdata) { + redisLibeventEvents *e = (redisLibeventEvents*)privdata; + event_add(e->wev,NULL); +} + +static void redisLibeventDelWrite(void *privdata) { + redisLibeventEvents *e = (redisLibeventEvents*)privdata; + event_del(e->wev); +} + +static void redisLibeventCleanup(void *privdata) { + redisLibeventEvents *e = (redisLibeventEvents*)privdata; + event_free(e->rev); + event_free(e->wev); + free(e); +} + +static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) { + redisContext *c = &(ac->c); + redisLibeventEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e)); + e->context = ac; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisLibeventAddRead; + ac->ev.delRead = redisLibeventDelRead; + ac->ev.addWrite = redisLibeventAddWrite; + ac->ev.delWrite = redisLibeventDelWrite; + ac->ev.cleanup = redisLibeventCleanup; + ac->ev.data = e; + + /* Initialize and install read/write events */ + e->rev = event_new(base, c->fd, EV_READ, redisLibeventReadEvent, e); + e->wev = event_new(base, c->fd, EV_WRITE, redisLibeventWriteEvent, e); + event_add(e->rev, NULL); + event_add(e->wev, NULL); + return REDIS_OK; +} +#endif diff --git a/ext/hiredis-0.14.1/adapters/libuv.h b/ext/hiredis-0.14.1/adapters/libuv.h new file mode 100644 index 0000000..ff08c25 --- /dev/null +++ b/ext/hiredis-0.14.1/adapters/libuv.h @@ -0,0 +1,122 @@ +#ifndef __HIREDIS_LIBUV_H__ +#define __HIREDIS_LIBUV_H__ +#include +#include +#include "../hiredis.h" +#include "../async.h" +#include + +typedef struct redisLibuvEvents { + redisAsyncContext* context; + uv_poll_t handle; + int events; +} redisLibuvEvents; + + +static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { + redisLibuvEvents* p = (redisLibuvEvents*)handle->data; + + if (status != 0) { + return; + } + + if (p->context != NULL && (events & UV_READABLE)) { + redisAsyncHandleRead(p->context); + } + if (p->context != NULL && (events & UV_WRITABLE)) { + redisAsyncHandleWrite(p->context); + } +} + + +static void redisLibuvAddRead(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events |= UV_READABLE; + + uv_poll_start(&p->handle, p->events, redisLibuvPoll); +} + + +static void redisLibuvDelRead(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events &= ~UV_READABLE; + + if (p->events) { + uv_poll_start(&p->handle, p->events, redisLibuvPoll); + } else { + uv_poll_stop(&p->handle); + } +} + + +static void redisLibuvAddWrite(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events |= UV_WRITABLE; + + uv_poll_start(&p->handle, p->events, redisLibuvPoll); +} + + +static void redisLibuvDelWrite(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events &= ~UV_WRITABLE; + + if (p->events) { + uv_poll_start(&p->handle, p->events, redisLibuvPoll); + } else { + uv_poll_stop(&p->handle); + } +} + + +static void on_close(uv_handle_t* handle) { + redisLibuvEvents* p = (redisLibuvEvents*)handle->data; + + free(p); +} + + +static void redisLibuvCleanup(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->context = NULL; // indicate that context might no longer exist + uv_close((uv_handle_t*)&p->handle, on_close); +} + + +static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { + redisContext *c = &(ac->c); + + if (ac->ev.data != NULL) { + return REDIS_ERR; + } + + ac->ev.addRead = redisLibuvAddRead; + ac->ev.delRead = redisLibuvDelRead; + ac->ev.addWrite = redisLibuvAddWrite; + ac->ev.delWrite = redisLibuvDelWrite; + ac->ev.cleanup = redisLibuvCleanup; + + redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p)); + + if (!p) { + return REDIS_ERR; + } + + memset(p, 0, sizeof(*p)); + + if (uv_poll_init(loop, &p->handle, c->fd) != 0) { + return REDIS_ERR; + } + + ac->ev.data = p; + p->handle.data = p; + p->context = ac; + + return REDIS_OK; +} +#endif diff --git a/ext/hiredis-0.14.1/adapters/macosx.h b/ext/hiredis-0.14.1/adapters/macosx.h new file mode 100644 index 0000000..72121f6 --- /dev/null +++ b/ext/hiredis-0.14.1/adapters/macosx.h @@ -0,0 +1,114 @@ +// +// Created by Дмитрий Бахвалов on 13.07.15. +// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. +// + +#ifndef __HIREDIS_MACOSX_H__ +#define __HIREDIS_MACOSX_H__ + +#include + +#include "../hiredis.h" +#include "../async.h" + +typedef struct { + redisAsyncContext *context; + CFSocketRef socketRef; + CFRunLoopSourceRef sourceRef; +} RedisRunLoop; + +static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) { + if( redisRunLoop != NULL ) { + if( redisRunLoop->sourceRef != NULL ) { + CFRunLoopSourceInvalidate(redisRunLoop->sourceRef); + CFRelease(redisRunLoop->sourceRef); + } + if( redisRunLoop->socketRef != NULL ) { + CFSocketInvalidate(redisRunLoop->socketRef); + CFRelease(redisRunLoop->socketRef); + } + free(redisRunLoop); + } + return REDIS_ERR; +} + +static void redisMacOSAddRead(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); +} + +static void redisMacOSDelRead(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); +} + +static void redisMacOSAddWrite(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); +} + +static void redisMacOSDelWrite(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); +} + +static void redisMacOSCleanup(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + freeRedisRunLoop(redisRunLoop); +} + +static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) { + redisAsyncContext* context = (redisAsyncContext*) info; + + switch (callbackType) { + case kCFSocketReadCallBack: + redisAsyncHandleRead(context); + break; + + case kCFSocketWriteCallBack: + redisAsyncHandleWrite(context); + break; + + default: + break; + } +} + +static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) { + redisContext *redisCtx = &(redisAsyncCtx->c); + + /* Nothing should be attached when something is already attached */ + if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR; + + RedisRunLoop* redisRunLoop = (RedisRunLoop*) calloc(1, sizeof(RedisRunLoop)); + if( !redisRunLoop ) return REDIS_ERR; + + /* Setup redis stuff */ + redisRunLoop->context = redisAsyncCtx; + + redisAsyncCtx->ev.addRead = redisMacOSAddRead; + redisAsyncCtx->ev.delRead = redisMacOSDelRead; + redisAsyncCtx->ev.addWrite = redisMacOSAddWrite; + redisAsyncCtx->ev.delWrite = redisMacOSDelWrite; + redisAsyncCtx->ev.cleanup = redisMacOSCleanup; + redisAsyncCtx->ev.data = redisRunLoop; + + /* Initialize and install read/write events */ + CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL }; + + redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd, + kCFSocketReadCallBack | kCFSocketWriteCallBack, + redisMacOSAsyncCallback, + &socketCtx); + if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop); + + redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0); + if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop); + + CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode); + + return REDIS_OK; +} + +#endif + diff --git a/ext/hiredis-0.14.1/adapters/qt.h b/ext/hiredis-0.14.1/adapters/qt.h new file mode 100644 index 0000000..5cc02e6 --- /dev/null +++ b/ext/hiredis-0.14.1/adapters/qt.h @@ -0,0 +1,135 @@ +/*- + * Copyright (C) 2014 Pietro Cerutti + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __HIREDIS_QT_H__ +#define __HIREDIS_QT_H__ +#include +#include "../async.h" + +static void RedisQtAddRead(void *); +static void RedisQtDelRead(void *); +static void RedisQtAddWrite(void *); +static void RedisQtDelWrite(void *); +static void RedisQtCleanup(void *); + +class RedisQtAdapter : public QObject { + + Q_OBJECT + + friend + void RedisQtAddRead(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->addRead(); + } + + friend + void RedisQtDelRead(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->delRead(); + } + + friend + void RedisQtAddWrite(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->addWrite(); + } + + friend + void RedisQtDelWrite(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->delWrite(); + } + + friend + void RedisQtCleanup(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->cleanup(); + } + + public: + RedisQtAdapter(QObject * parent = 0) + : QObject(parent), m_ctx(0), m_read(0), m_write(0) { } + + ~RedisQtAdapter() { + if (m_ctx != 0) { + m_ctx->ev.data = NULL; + } + } + + int setContext(redisAsyncContext * ac) { + if (ac->ev.data != NULL) { + return REDIS_ERR; + } + m_ctx = ac; + m_ctx->ev.data = this; + m_ctx->ev.addRead = RedisQtAddRead; + m_ctx->ev.delRead = RedisQtDelRead; + m_ctx->ev.addWrite = RedisQtAddWrite; + m_ctx->ev.delWrite = RedisQtDelWrite; + m_ctx->ev.cleanup = RedisQtCleanup; + return REDIS_OK; + } + + private: + void addRead() { + if (m_read) return; + m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0); + connect(m_read, SIGNAL(activated(int)), this, SLOT(read())); + } + + void delRead() { + if (!m_read) return; + delete m_read; + m_read = 0; + } + + void addWrite() { + if (m_write) return; + m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0); + connect(m_write, SIGNAL(activated(int)), this, SLOT(write())); + } + + void delWrite() { + if (!m_write) return; + delete m_write; + m_write = 0; + } + + void cleanup() { + delRead(); + delWrite(); + } + + private slots: + void read() { redisAsyncHandleRead(m_ctx); } + void write() { redisAsyncHandleWrite(m_ctx); } + + private: + redisAsyncContext * m_ctx; + QSocketNotifier * m_read; + QSocketNotifier * m_write; +}; + +#endif /* !__HIREDIS_QT_H__ */ diff --git a/ext/hiredis-0.14.1/alloc.c b/ext/hiredis-0.14.1/alloc.c new file mode 100644 index 0000000..55c3020 --- /dev/null +++ b/ext/hiredis-0.14.1/alloc.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include "alloc.h" +#include + +void *hi_malloc(size_t size) { + void *ptr = malloc(size); + if (ptr == NULL) + HIREDIS_OOM_HANDLER; + + return ptr; +} + +void *hi_calloc(size_t nmemb, size_t size) { + void *ptr = calloc(nmemb, size); + if (ptr == NULL) + HIREDIS_OOM_HANDLER; + + return ptr; +} + +void *hi_realloc(void *ptr, size_t size) { + void *newptr = realloc(ptr, size); + if (newptr == NULL) + HIREDIS_OOM_HANDLER; + + return newptr; +} + +char *hi_strdup(const char *str) { + char *newstr = strdup(str); + if (newstr == NULL) + HIREDIS_OOM_HANDLER; + + return newstr; +} diff --git a/ext/hiredis-0.14.1/alloc.h b/ext/hiredis-0.14.1/alloc.h new file mode 100644 index 0000000..2c9b04e --- /dev/null +++ b/ext/hiredis-0.14.1/alloc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HIREDIS_ALLOC_H +#define HIREDIS_ALLOC_H + +#include /* for size_t */ + +#ifndef HIREDIS_OOM_HANDLER +#define HIREDIS_OOM_HANDLER abort() +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void *hi_malloc(size_t size); +void *hi_calloc(size_t nmemb, size_t size); +void *hi_realloc(void *ptr, size_t size); +char *hi_strdup(const char *str); + +#ifdef __cplusplus +} +#endif + +#endif /* HIREDIS_ALLOC_H */ diff --git a/ext/hiredis-0.14.1/appveyor.yml b/ext/hiredis-0.14.1/appveyor.yml new file mode 100644 index 0000000..819efbd --- /dev/null +++ b/ext/hiredis-0.14.1/appveyor.yml @@ -0,0 +1,23 @@ +# Appveyor configuration file for CI build of hiredis on Windows (under Cygwin) +environment: + matrix: + - CYG_BASH: C:\cygwin64\bin\bash + CC: gcc + - CYG_BASH: C:\cygwin\bin\bash + CC: gcc + TARGET: 32bit + TARGET_VARS: 32bit-vars + +clone_depth: 1 + +# Attempt to ensure we don't try to convert line endings to Win32 CRLF as this will cause build to fail +init: + - git config --global core.autocrlf input + +# Install needed build dependencies +install: + - '%CYG_BASH% -lc "cygcheck -dc cygwin"' + +build_script: + - 'echo building...' + - '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0 + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include "alloc.h" +#include +#include +#include +#include +#include +#include +#include "async.h" +#include "net.h" +#include "dict.c" +#include "sds.h" + +#define _EL_ADD_READ(ctx) do { \ + if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \ + } while(0) +#define _EL_DEL_READ(ctx) do { \ + if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \ + } while(0) +#define _EL_ADD_WRITE(ctx) do { \ + if ((ctx)->ev.addWrite) (ctx)->ev.addWrite((ctx)->ev.data); \ + } while(0) +#define _EL_DEL_WRITE(ctx) do { \ + if ((ctx)->ev.delWrite) (ctx)->ev.delWrite((ctx)->ev.data); \ + } while(0) +#define _EL_CLEANUP(ctx) do { \ + if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \ + } while(0); + +/* Forward declaration of function in hiredis.c */ +int __redisAppendCommand(redisContext *c, const char *cmd, size_t len); + +/* Functions managing dictionary of callbacks for pub/sub. */ +static unsigned int callbackHash(const void *key) { + return dictGenHashFunction((const unsigned char *)key, + sdslen((const sds)key)); +} + +static void *callbackValDup(void *privdata, const void *src) { + ((void) privdata); + redisCallback *dup = hi_malloc(sizeof(*dup)); + memcpy(dup,src,sizeof(*dup)); + return dup; +} + +static int callbackKeyCompare(void *privdata, const void *key1, const void *key2) { + int l1, l2; + ((void) privdata); + + l1 = sdslen((const sds)key1); + l2 = sdslen((const sds)key2); + if (l1 != l2) return 0; + return memcmp(key1,key2,l1) == 0; +} + +static void callbackKeyDestructor(void *privdata, void *key) { + ((void) privdata); + sdsfree((sds)key); +} + +static void callbackValDestructor(void *privdata, void *val) { + ((void) privdata); + free(val); +} + +static dictType callbackDict = { + callbackHash, + NULL, + callbackValDup, + callbackKeyCompare, + callbackKeyDestructor, + callbackValDestructor +}; + +static redisAsyncContext *redisAsyncInitialize(redisContext *c) { + redisAsyncContext *ac; + + ac = realloc(c,sizeof(redisAsyncContext)); + if (ac == NULL) + return NULL; + + c = &(ac->c); + + /* The regular connect functions will always set the flag REDIS_CONNECTED. + * For the async API, we want to wait until the first write event is + * received up before setting this flag, so reset it here. */ + c->flags &= ~REDIS_CONNECTED; + + ac->err = 0; + ac->errstr = NULL; + ac->data = NULL; + + ac->ev.data = NULL; + ac->ev.addRead = NULL; + ac->ev.delRead = NULL; + ac->ev.addWrite = NULL; + ac->ev.delWrite = NULL; + ac->ev.cleanup = NULL; + + ac->onConnect = NULL; + ac->onDisconnect = NULL; + + ac->replies.head = NULL; + ac->replies.tail = NULL; + ac->sub.invalid.head = NULL; + ac->sub.invalid.tail = NULL; + ac->sub.channels = dictCreate(&callbackDict,NULL); + ac->sub.patterns = dictCreate(&callbackDict,NULL); + return ac; +} + +/* We want the error field to be accessible directly instead of requiring + * an indirection to the redisContext struct. */ +static void __redisAsyncCopyError(redisAsyncContext *ac) { + if (!ac) + return; + + redisContext *c = &(ac->c); + ac->err = c->err; + ac->errstr = c->errstr; +} + +redisAsyncContext *redisAsyncConnect(const char *ip, int port) { + redisContext *c; + redisAsyncContext *ac; + + c = redisConnectNonBlock(ip,port); + if (c == NULL) + return NULL; + + ac = redisAsyncInitialize(c); + if (ac == NULL) { + redisFree(c); + return NULL; + } + + __redisAsyncCopyError(ac); + return ac; +} + +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, + const char *source_addr) { + redisContext *c = redisConnectBindNonBlock(ip,port,source_addr); + redisAsyncContext *ac = redisAsyncInitialize(c); + __redisAsyncCopyError(ac); + return ac; +} + +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr) { + redisContext *c = redisConnectBindNonBlockWithReuse(ip,port,source_addr); + redisAsyncContext *ac = redisAsyncInitialize(c); + __redisAsyncCopyError(ac); + return ac; +} + +redisAsyncContext *redisAsyncConnectUnix(const char *path) { + redisContext *c; + redisAsyncContext *ac; + + c = redisConnectUnixNonBlock(path); + if (c == NULL) + return NULL; + + ac = redisAsyncInitialize(c); + if (ac == NULL) { + redisFree(c); + return NULL; + } + + __redisAsyncCopyError(ac); + return ac; +} + +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) { + if (ac->onConnect == NULL) { + ac->onConnect = fn; + + /* The common way to detect an established connection is to wait for + * the first write event to be fired. This assumes the related event + * library functions are already set. */ + _EL_ADD_WRITE(ac); + return REDIS_OK; + } + return REDIS_ERR; +} + +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) { + if (ac->onDisconnect == NULL) { + ac->onDisconnect = fn; + return REDIS_OK; + } + return REDIS_ERR; +} + +/* Helper functions to push/shift callbacks */ +static int __redisPushCallback(redisCallbackList *list, redisCallback *source) { + redisCallback *cb; + + /* Copy callback from stack to heap */ + cb = malloc(sizeof(*cb)); + if (cb == NULL) + return REDIS_ERR_OOM; + + if (source != NULL) { + memcpy(cb,source,sizeof(*cb)); + cb->next = NULL; + } + + /* Store callback in list */ + if (list->head == NULL) + list->head = cb; + if (list->tail != NULL) + list->tail->next = cb; + list->tail = cb; + return REDIS_OK; +} + +static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) { + redisCallback *cb = list->head; + if (cb != NULL) { + list->head = cb->next; + if (cb == list->tail) + list->tail = NULL; + + /* Copy callback from heap to stack */ + if (target != NULL) + memcpy(target,cb,sizeof(*cb)); + free(cb); + return REDIS_OK; + } + return REDIS_ERR; +} + +static void __redisRunCallback(redisAsyncContext *ac, redisCallback *cb, redisReply *reply) { + redisContext *c = &(ac->c); + if (cb->fn != NULL) { + c->flags |= REDIS_IN_CALLBACK; + cb->fn(ac,reply,cb->privdata); + c->flags &= ~REDIS_IN_CALLBACK; + } +} + +/* Helper function to free the context. */ +static void __redisAsyncFree(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisCallback cb; + dictIterator *it; + dictEntry *de; + + /* Execute pending callbacks with NULL reply. */ + while (__redisShiftCallback(&ac->replies,&cb) == REDIS_OK) + __redisRunCallback(ac,&cb,NULL); + + /* Execute callbacks for invalid commands */ + while (__redisShiftCallback(&ac->sub.invalid,&cb) == REDIS_OK) + __redisRunCallback(ac,&cb,NULL); + + /* Run subscription callbacks callbacks with NULL reply */ + it = dictGetIterator(ac->sub.channels); + while ((de = dictNext(it)) != NULL) + __redisRunCallback(ac,dictGetEntryVal(de),NULL); + dictReleaseIterator(it); + dictRelease(ac->sub.channels); + + it = dictGetIterator(ac->sub.patterns); + while ((de = dictNext(it)) != NULL) + __redisRunCallback(ac,dictGetEntryVal(de),NULL); + dictReleaseIterator(it); + dictRelease(ac->sub.patterns); + + /* Signal event lib to clean up */ + _EL_CLEANUP(ac); + + /* Execute disconnect callback. When redisAsyncFree() initiated destroying + * this context, the status will always be REDIS_OK. */ + if (ac->onDisconnect && (c->flags & REDIS_CONNECTED)) { + if (c->flags & REDIS_FREEING) { + ac->onDisconnect(ac,REDIS_OK); + } else { + ac->onDisconnect(ac,(ac->err == 0) ? REDIS_OK : REDIS_ERR); + } + } + + /* Cleanup self */ + redisFree(c); +} + +/* Free the async context. When this function is called from a callback, + * control needs to be returned to redisProcessCallbacks() before actual + * free'ing. To do so, a flag is set on the context which is picked up by + * redisProcessCallbacks(). Otherwise, the context is immediately free'd. */ +void redisAsyncFree(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + c->flags |= REDIS_FREEING; + if (!(c->flags & REDIS_IN_CALLBACK)) + __redisAsyncFree(ac); +} + +/* Helper function to make the disconnect happen and clean up. */ +static void __redisAsyncDisconnect(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + /* Make sure error is accessible if there is any */ + __redisAsyncCopyError(ac); + + if (ac->err == 0) { + /* For clean disconnects, there should be no pending callbacks. */ + int ret = __redisShiftCallback(&ac->replies,NULL); + assert(ret == REDIS_ERR); + } else { + /* Disconnection is caused by an error, make sure that pending + * callbacks cannot call new commands. */ + c->flags |= REDIS_DISCONNECTING; + } + + /* For non-clean disconnects, __redisAsyncFree() will execute pending + * callbacks with a NULL-reply. */ + __redisAsyncFree(ac); +} + +/* Tries to do a clean disconnect from Redis, meaning it stops new commands + * from being issued, but tries to flush the output buffer and execute + * callbacks for all remaining replies. When this function is called from a + * callback, there might be more replies and we can safely defer disconnecting + * to redisProcessCallbacks(). Otherwise, we can only disconnect immediately + * when there are no pending callbacks. */ +void redisAsyncDisconnect(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + c->flags |= REDIS_DISCONNECTING; + if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL) + __redisAsyncDisconnect(ac); +} + +static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, redisCallback *dstcb) { + redisContext *c = &(ac->c); + dict *callbacks; + redisCallback *cb; + dictEntry *de; + int pvariant; + char *stype; + sds sname; + + /* Custom reply functions are not supported for pub/sub. This will fail + * very hard when they are used... */ + if (reply->type == REDIS_REPLY_ARRAY) { + assert(reply->elements >= 2); + assert(reply->element[0]->type == REDIS_REPLY_STRING); + stype = reply->element[0]->str; + pvariant = (tolower(stype[0]) == 'p') ? 1 : 0; + + if (pvariant) + callbacks = ac->sub.patterns; + else + callbacks = ac->sub.channels; + + /* Locate the right callback */ + assert(reply->element[1]->type == REDIS_REPLY_STRING); + sname = sdsnewlen(reply->element[1]->str,reply->element[1]->len); + de = dictFind(callbacks,sname); + if (de != NULL) { + cb = dictGetEntryVal(de); + + /* If this is an subscribe reply decrease pending counter. */ + if (strcasecmp(stype+pvariant,"subscribe") == 0) { + cb->pending_subs -= 1; + } + + memcpy(dstcb,cb,sizeof(*dstcb)); + + /* If this is an unsubscribe message, remove it. */ + if (strcasecmp(stype+pvariant,"unsubscribe") == 0) { + if (cb->pending_subs == 0) + dictDelete(callbacks,sname); + + /* If this was the last unsubscribe message, revert to + * non-subscribe mode. */ + assert(reply->element[2]->type == REDIS_REPLY_INTEGER); + + /* Unset subscribed flag only when no pipelined pending subscribe. */ + if (reply->element[2]->integer == 0 + && dictSize(ac->sub.channels) == 0 + && dictSize(ac->sub.patterns) == 0) + c->flags &= ~REDIS_SUBSCRIBED; + } + } + sdsfree(sname); + } else { + /* Shift callback for invalid commands. */ + __redisShiftCallback(&ac->sub.invalid,dstcb); + } + return REDIS_OK; +} + +void redisProcessCallbacks(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisCallback cb = {NULL, NULL, 0, NULL}; + void *reply = NULL; + int status; + + while((status = redisGetReply(c,&reply)) == REDIS_OK) { + if (reply == NULL) { + /* When the connection is being disconnected and there are + * no more replies, this is the cue to really disconnect. */ + if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0 + && ac->replies.head == NULL) { + __redisAsyncDisconnect(ac); + return; + } + + /* If monitor mode, repush callback */ + if(c->flags & REDIS_MONITORING) { + __redisPushCallback(&ac->replies,&cb); + } + + /* When the connection is not being disconnected, simply stop + * trying to get replies and wait for the next loop tick. */ + break; + } + + /* Even if the context is subscribed, pending regular callbacks will + * get a reply before pub/sub messages arrive. */ + if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) { + /* + * A spontaneous reply in a not-subscribed context can be the error + * reply that is sent when a new connection exceeds the maximum + * number of allowed connections on the server side. + * + * This is seen as an error instead of a regular reply because the + * server closes the connection after sending it. + * + * To prevent the error from being overwritten by an EOF error the + * connection is closed here. See issue #43. + * + * Another possibility is that the server is loading its dataset. + * In this case we also want to close the connection, and have the + * user wait until the server is ready to take our request. + */ + if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) { + c->err = REDIS_ERR_OTHER; + snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str); + c->reader->fn->freeObject(reply); + __redisAsyncDisconnect(ac); + return; + } + /* No more regular callbacks and no errors, the context *must* be subscribed or monitoring. */ + assert((c->flags & REDIS_SUBSCRIBED || c->flags & REDIS_MONITORING)); + if(c->flags & REDIS_SUBSCRIBED) + __redisGetSubscribeCallback(ac,reply,&cb); + } + + if (cb.fn != NULL) { + __redisRunCallback(ac,&cb,reply); + c->reader->fn->freeObject(reply); + + /* Proceed with free'ing when redisAsyncFree() was called. */ + if (c->flags & REDIS_FREEING) { + __redisAsyncFree(ac); + return; + } + } else { + /* No callback for this reply. This can either be a NULL callback, + * or there were no callbacks to begin with. Either way, don't + * abort with an error, but simply ignore it because the client + * doesn't know what the server will spit out over the wire. */ + c->reader->fn->freeObject(reply); + } + } + + /* Disconnect when there was an error reading the reply */ + if (status != REDIS_OK) + __redisAsyncDisconnect(ac); +} + +/* Internal helper function to detect socket status the first time a read or + * write event fires. When connecting was not successful, the connect callback + * is called with a REDIS_ERR status and the context is free'd. */ +static int __redisAsyncHandleConnect(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + if (redisCheckSocketError(c) == REDIS_ERR) { + /* Try again later when connect(2) is still in progress. */ + if (errno == EINPROGRESS) + return REDIS_OK; + + if (ac->onConnect) ac->onConnect(ac,REDIS_ERR); + __redisAsyncDisconnect(ac); + return REDIS_ERR; + } + + /* Mark context as connected. */ + c->flags |= REDIS_CONNECTED; + if (ac->onConnect) ac->onConnect(ac,REDIS_OK); + return REDIS_OK; +} + +/* This function should be called when the socket is readable. + * It processes all replies that can be read and executes their callbacks. + */ +void redisAsyncHandleRead(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + if (!(c->flags & REDIS_CONNECTED)) { + /* Abort connect was not successful. */ + if (__redisAsyncHandleConnect(ac) != REDIS_OK) + return; + /* Try again later when the context is still not connected. */ + if (!(c->flags & REDIS_CONNECTED)) + return; + } + + if (redisBufferRead(c) == REDIS_ERR) { + __redisAsyncDisconnect(ac); + } else { + /* Always re-schedule reads */ + _EL_ADD_READ(ac); + redisProcessCallbacks(ac); + } +} + +void redisAsyncHandleWrite(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + int done = 0; + + if (!(c->flags & REDIS_CONNECTED)) { + /* Abort connect was not successful. */ + if (__redisAsyncHandleConnect(ac) != REDIS_OK) + return; + /* Try again later when the context is still not connected. */ + if (!(c->flags & REDIS_CONNECTED)) + return; + } + + if (redisBufferWrite(c,&done) == REDIS_ERR) { + __redisAsyncDisconnect(ac); + } else { + /* Continue writing when not done, stop writing otherwise */ + if (!done) + _EL_ADD_WRITE(ac); + else + _EL_DEL_WRITE(ac); + + /* Always schedule reads after writes */ + _EL_ADD_READ(ac); + } +} + +/* Sets a pointer to the first argument and its length starting at p. Returns + * the number of bytes to skip to get to the following argument. */ +static const char *nextArgument(const char *start, const char **str, size_t *len) { + const char *p = start; + if (p[0] != '$') { + p = strchr(p,'$'); + if (p == NULL) return NULL; + } + + *len = (int)strtol(p+1,NULL,10); + p = strchr(p,'\r'); + assert(p); + *str = p+2; + return p+2+(*len)+2; +} + +/* Helper function for the redisAsyncCommand* family of functions. Writes a + * formatted command to the output buffer and registers the provided callback + * function with the context. */ +static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { + redisContext *c = &(ac->c); + redisCallback cb; + struct dict *cbdict; + dictEntry *de; + redisCallback *existcb; + int pvariant, hasnext; + const char *cstr, *astr; + size_t clen, alen; + const char *p; + sds sname; + int ret; + + /* Don't accept new commands when the connection is about to be closed. */ + if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR; + + /* Setup callback */ + cb.fn = fn; + cb.privdata = privdata; + cb.pending_subs = 1; + + /* Find out which command will be appended. */ + p = nextArgument(cmd,&cstr,&clen); + assert(p != NULL); + hasnext = (p[0] == '$'); + pvariant = (tolower(cstr[0]) == 'p') ? 1 : 0; + cstr += pvariant; + clen -= pvariant; + + if (hasnext && strncasecmp(cstr,"subscribe\r\n",11) == 0) { + c->flags |= REDIS_SUBSCRIBED; + + /* Add every channel/pattern to the list of subscription callbacks. */ + while ((p = nextArgument(p,&astr,&alen)) != NULL) { + sname = sdsnewlen(astr,alen); + if (pvariant) + cbdict = ac->sub.patterns; + else + cbdict = ac->sub.channels; + + de = dictFind(cbdict,sname); + + if (de != NULL) { + existcb = dictGetEntryVal(de); + cb.pending_subs = existcb->pending_subs + 1; + } + + ret = dictReplace(cbdict,sname,&cb); + + if (ret == 0) sdsfree(sname); + } + } else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) { + /* It is only useful to call (P)UNSUBSCRIBE when the context is + * subscribed to one or more channels or patterns. */ + if (!(c->flags & REDIS_SUBSCRIBED)) return REDIS_ERR; + + /* (P)UNSUBSCRIBE does not have its own response: every channel or + * pattern that is unsubscribed will receive a message. This means we + * should not append a callback function for this command. */ + } else if(strncasecmp(cstr,"monitor\r\n",9) == 0) { + /* Set monitor flag and push callback */ + c->flags |= REDIS_MONITORING; + __redisPushCallback(&ac->replies,&cb); + } else { + if (c->flags & REDIS_SUBSCRIBED) + /* This will likely result in an error reply, but it needs to be + * received and passed to the callback. */ + __redisPushCallback(&ac->sub.invalid,&cb); + else + __redisPushCallback(&ac->replies,&cb); + } + + __redisAppendCommand(c,cmd,len); + + /* Always schedule a write when the write buffer is non-empty */ + _EL_ADD_WRITE(ac); + + return REDIS_OK; +} + +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap) { + char *cmd; + int len; + int status; + len = redisvFormatCommand(&cmd,format,ap); + + /* We don't want to pass -1 or -2 to future functions as a length. */ + if (len < 0) + return REDIS_ERR; + + status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + free(cmd); + return status; +} + +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...) { + va_list ap; + int status; + va_start(ap,format); + status = redisvAsyncCommand(ac,fn,privdata,format,ap); + va_end(ap); + return status; +} + +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) { + sds cmd; + int len; + int status; + len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); + if (len < 0) + return REDIS_ERR; + status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + sdsfree(cmd); + return status; +} + +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { + int status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + return status; +} diff --git a/ext/hiredis-0.14.1/async.h b/ext/hiredis-0.14.1/async.h new file mode 100644 index 0000000..e69d840 --- /dev/null +++ b/ext/hiredis-0.14.1/async.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_ASYNC_H +#define __HIREDIS_ASYNC_H +#include "hiredis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ +struct dict; /* dictionary header is included in async.c */ + +/* Reply callback prototype and container */ +typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); +typedef struct redisCallback { + struct redisCallback *next; /* simple singly linked list */ + redisCallbackFn *fn; + int pending_subs; + void *privdata; +} redisCallback; + +/* List of callbacks for either regular replies or pub/sub */ +typedef struct redisCallbackList { + redisCallback *head, *tail; +} redisCallbackList; + +/* Connection callback prototypes */ +typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); +typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); + +/* Context for an async connection to Redis */ +typedef struct redisAsyncContext { + /* Hold the regular context, so it can be realloc'ed. */ + redisContext c; + + /* Setup error flags so they can be used directly. */ + int err; + char *errstr; + + /* Not used by hiredis */ + void *data; + + /* Event library data and hooks */ + struct { + void *data; + + /* Hooks that are called when the library expects to start + * reading/writing. These functions should be idempotent. */ + void (*addRead)(void *privdata); + void (*delRead)(void *privdata); + void (*addWrite)(void *privdata); + void (*delWrite)(void *privdata); + void (*cleanup)(void *privdata); + } ev; + + /* Called when either the connection is terminated due to an error or per + * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ + redisDisconnectCallback *onDisconnect; + + /* Called when the first write event was received. */ + redisConnectCallback *onConnect; + + /* Regular command callbacks */ + redisCallbackList replies; + + /* Subscription callbacks */ + struct { + redisCallbackList invalid; + struct dict *channels; + struct dict *patterns; + } sub; +} redisAsyncContext; + +/* Functions that proxy to hiredis */ +redisAsyncContext *redisAsyncConnect(const char *ip, int port); +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr); +redisAsyncContext *redisAsyncConnectUnix(const char *path); +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); +void redisAsyncDisconnect(redisAsyncContext *ac); +void redisAsyncFree(redisAsyncContext *ac); + +/* Handle read/write events */ +void redisAsyncHandleRead(redisAsyncContext *ac); +void redisAsyncHandleWrite(redisAsyncContext *ac); + +/* Command functions for an async context. Write the command to the + * output buffer and register the provided callback. */ +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-0.14.1/dict.c b/ext/hiredis-0.14.1/dict.c new file mode 100644 index 0000000..29cdc19 --- /dev/null +++ b/ext/hiredis-0.14.1/dict.c @@ -0,0 +1,339 @@ +/* Hash table implementation. + * + * This file implements in memory hash tables with insert/del/replace/find/ + * get-random-element operations. Hash tables will auto resize if needed + * tables of power of two in size are used, collisions are handled by + * chaining. See the source code for more information... :) + * + * Copyright (c) 2006-2010, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include "alloc.h" +#include +#include +#include +#include "dict.h" + +/* -------------------------- private prototypes ---------------------------- */ + +static int _dictExpandIfNeeded(dict *ht); +static unsigned long _dictNextPower(unsigned long size); +static int _dictKeyIndex(dict *ht, const void *key); +static int _dictInit(dict *ht, dictType *type, void *privDataPtr); + +/* -------------------------- hash functions -------------------------------- */ + +/* Generic hash function (a popular one from Bernstein). + * I tested a few and this was the best. */ +static unsigned int dictGenHashFunction(const unsigned char *buf, int len) { + unsigned int hash = 5381; + + while (len--) + hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */ + return hash; +} + +/* ----------------------------- API implementation ------------------------- */ + +/* Reset an hashtable already initialized with ht_init(). + * NOTE: This function should only called by ht_destroy(). */ +static void _dictReset(dict *ht) { + ht->table = NULL; + ht->size = 0; + ht->sizemask = 0; + ht->used = 0; +} + +/* Create a new hash table */ +static dict *dictCreate(dictType *type, void *privDataPtr) { + dict *ht = hi_malloc(sizeof(*ht)); + _dictInit(ht,type,privDataPtr); + return ht; +} + +/* Initialize the hash table */ +static int _dictInit(dict *ht, dictType *type, void *privDataPtr) { + _dictReset(ht); + ht->type = type; + ht->privdata = privDataPtr; + return DICT_OK; +} + +/* Expand or create the hashtable */ +static int dictExpand(dict *ht, unsigned long size) { + dict n; /* the new hashtable */ + unsigned long realsize = _dictNextPower(size), i; + + /* the size is invalid if it is smaller than the number of + * elements already inside the hashtable */ + if (ht->used > size) + return DICT_ERR; + + _dictInit(&n, ht->type, ht->privdata); + n.size = realsize; + n.sizemask = realsize-1; + n.table = calloc(realsize,sizeof(dictEntry*)); + + /* Copy all the elements from the old to the new table: + * note that if the old hash table is empty ht->size is zero, + * so dictExpand just creates an hash table. */ + n.used = ht->used; + for (i = 0; i < ht->size && ht->used > 0; i++) { + dictEntry *he, *nextHe; + + if (ht->table[i] == NULL) continue; + + /* For each hash entry on this slot... */ + he = ht->table[i]; + while(he) { + unsigned int h; + + nextHe = he->next; + /* Get the new element index */ + h = dictHashKey(ht, he->key) & n.sizemask; + he->next = n.table[h]; + n.table[h] = he; + ht->used--; + /* Pass to the next element */ + he = nextHe; + } + } + assert(ht->used == 0); + free(ht->table); + + /* Remap the new hashtable in the old */ + *ht = n; + return DICT_OK; +} + +/* Add an element to the target hash table */ +static int dictAdd(dict *ht, void *key, void *val) { + int index; + dictEntry *entry; + + /* Get the index of the new element, or -1 if + * the element already exists. */ + if ((index = _dictKeyIndex(ht, key)) == -1) + return DICT_ERR; + + /* Allocates the memory and stores key */ + entry = hi_malloc(sizeof(*entry)); + entry->next = ht->table[index]; + ht->table[index] = entry; + + /* Set the hash entry fields. */ + dictSetHashKey(ht, entry, key); + dictSetHashVal(ht, entry, val); + ht->used++; + return DICT_OK; +} + +/* Add an element, discarding the old if the key already exists. + * Return 1 if the key was added from scratch, 0 if there was already an + * element with such key and dictReplace() just performed a value update + * operation. */ +static int dictReplace(dict *ht, void *key, void *val) { + dictEntry *entry, auxentry; + + /* Try to add the element. If the key + * does not exists dictAdd will succeed. */ + if (dictAdd(ht, key, val) == DICT_OK) + return 1; + /* It already exists, get the entry */ + entry = dictFind(ht, key); + /* Free the old value and set the new one */ + /* Set the new value and free the old one. Note that it is important + * to do that in this order, as the value may just be exactly the same + * as the previous one. In this context, think to reference counting, + * you want to increment (set), and then decrement (free), and not the + * reverse. */ + auxentry = *entry; + dictSetHashVal(ht, entry, val); + dictFreeEntryVal(ht, &auxentry); + return 0; +} + +/* Search and remove an element */ +static int dictDelete(dict *ht, const void *key) { + unsigned int h; + dictEntry *de, *prevde; + + if (ht->size == 0) + return DICT_ERR; + h = dictHashKey(ht, key) & ht->sizemask; + de = ht->table[h]; + + prevde = NULL; + while(de) { + if (dictCompareHashKeys(ht,key,de->key)) { + /* Unlink the element from the list */ + if (prevde) + prevde->next = de->next; + else + ht->table[h] = de->next; + + dictFreeEntryKey(ht,de); + dictFreeEntryVal(ht,de); + free(de); + ht->used--; + return DICT_OK; + } + prevde = de; + de = de->next; + } + return DICT_ERR; /* not found */ +} + +/* Destroy an entire hash table */ +static int _dictClear(dict *ht) { + unsigned long i; + + /* Free all the elements */ + for (i = 0; i < ht->size && ht->used > 0; i++) { + dictEntry *he, *nextHe; + + if ((he = ht->table[i]) == NULL) continue; + while(he) { + nextHe = he->next; + dictFreeEntryKey(ht, he); + dictFreeEntryVal(ht, he); + free(he); + ht->used--; + he = nextHe; + } + } + /* Free the table and the allocated cache structure */ + free(ht->table); + /* Re-initialize the table */ + _dictReset(ht); + return DICT_OK; /* never fails */ +} + +/* Clear & Release the hash table */ +static void dictRelease(dict *ht) { + _dictClear(ht); + free(ht); +} + +static dictEntry *dictFind(dict *ht, const void *key) { + dictEntry *he; + unsigned int h; + + if (ht->size == 0) return NULL; + h = dictHashKey(ht, key) & ht->sizemask; + he = ht->table[h]; + while(he) { + if (dictCompareHashKeys(ht, key, he->key)) + return he; + he = he->next; + } + return NULL; +} + +static dictIterator *dictGetIterator(dict *ht) { + dictIterator *iter = hi_malloc(sizeof(*iter)); + + iter->ht = ht; + iter->index = -1; + iter->entry = NULL; + iter->nextEntry = NULL; + return iter; +} + +static dictEntry *dictNext(dictIterator *iter) { + while (1) { + if (iter->entry == NULL) { + iter->index++; + if (iter->index >= + (signed)iter->ht->size) break; + iter->entry = iter->ht->table[iter->index]; + } else { + iter->entry = iter->nextEntry; + } + if (iter->entry) { + /* We need to save the 'next' here, the iterator user + * may delete the entry we are returning. */ + iter->nextEntry = iter->entry->next; + return iter->entry; + } + } + return NULL; +} + +static void dictReleaseIterator(dictIterator *iter) { + free(iter); +} + +/* ------------------------- private functions ------------------------------ */ + +/* Expand the hash table if needed */ +static int _dictExpandIfNeeded(dict *ht) { + /* If the hash table is empty expand it to the initial size, + * if the table is "full" dobule its size. */ + if (ht->size == 0) + return dictExpand(ht, DICT_HT_INITIAL_SIZE); + if (ht->used == ht->size) + return dictExpand(ht, ht->size*2); + return DICT_OK; +} + +/* Our hash table capability is a power of two */ +static unsigned long _dictNextPower(unsigned long size) { + unsigned long i = DICT_HT_INITIAL_SIZE; + + if (size >= LONG_MAX) return LONG_MAX; + while(1) { + if (i >= size) + return i; + i *= 2; + } +} + +/* Returns the index of a free slot that can be populated with + * an hash entry for the given 'key'. + * If the key already exists, -1 is returned. */ +static int _dictKeyIndex(dict *ht, const void *key) { + unsigned int h; + dictEntry *he; + + /* Expand the hashtable if needed */ + if (_dictExpandIfNeeded(ht) == DICT_ERR) + return -1; + /* Compute the key hash value */ + h = dictHashKey(ht, key) & ht->sizemask; + /* Search if this slot does not already contain the given key */ + he = ht->table[h]; + while(he) { + if (dictCompareHashKeys(ht, key, he->key)) + return -1; + he = he->next; + } + return h; +} + diff --git a/ext/hiredis-0.14.1/dict.h b/ext/hiredis-0.14.1/dict.h new file mode 100644 index 0000000..95fcd28 --- /dev/null +++ b/ext/hiredis-0.14.1/dict.h @@ -0,0 +1,126 @@ +/* Hash table implementation. + * + * This file implements in memory hash tables with insert/del/replace/find/ + * get-random-element operations. Hash tables will auto resize if needed + * tables of power of two in size are used, collisions are handled by + * chaining. See the source code for more information... :) + * + * Copyright (c) 2006-2010, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DICT_H +#define __DICT_H + +#define DICT_OK 0 +#define DICT_ERR 1 + +/* Unused arguments generate annoying warnings... */ +#define DICT_NOTUSED(V) ((void) V) + +typedef struct dictEntry { + void *key; + void *val; + struct dictEntry *next; +} dictEntry; + +typedef struct dictType { + unsigned int (*hashFunction)(const void *key); + void *(*keyDup)(void *privdata, const void *key); + void *(*valDup)(void *privdata, const void *obj); + int (*keyCompare)(void *privdata, const void *key1, const void *key2); + void (*keyDestructor)(void *privdata, void *key); + void (*valDestructor)(void *privdata, void *obj); +} dictType; + +typedef struct dict { + dictEntry **table; + dictType *type; + unsigned long size; + unsigned long sizemask; + unsigned long used; + void *privdata; +} dict; + +typedef struct dictIterator { + dict *ht; + int index; + dictEntry *entry, *nextEntry; +} dictIterator; + +/* This is the initial size of every hash table */ +#define DICT_HT_INITIAL_SIZE 4 + +/* ------------------------------- Macros ------------------------------------*/ +#define dictFreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->val) + +#define dictSetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ + else \ + entry->val = (_val_); \ +} while(0) + +#define dictFreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define dictSetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ + else \ + entry->key = (_key_); \ +} while(0) + +#define dictCompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ + (key1) == (key2)) + +#define dictHashKey(ht, key) (ht)->type->hashFunction(key) + +#define dictGetEntryKey(he) ((he)->key) +#define dictGetEntryVal(he) ((he)->val) +#define dictSlots(ht) ((ht)->size) +#define dictSize(ht) ((ht)->used) + +/* API */ +static unsigned int dictGenHashFunction(const unsigned char *buf, int len); +static dict *dictCreate(dictType *type, void *privDataPtr); +static int dictExpand(dict *ht, unsigned long size); +static int dictAdd(dict *ht, void *key, void *val); +static int dictReplace(dict *ht, void *key, void *val); +static int dictDelete(dict *ht, const void *key); +static void dictRelease(dict *ht); +static dictEntry * dictFind(dict *ht, const void *key); +static dictIterator *dictGetIterator(dict *ht); +static dictEntry *dictNext(dictIterator *iter); +static void dictReleaseIterator(dictIterator *iter); + +#endif /* __DICT_H */ diff --git a/ext/hiredis-0.14.1/examples/example-ae.c b/ext/hiredis-0.14.1/examples/example-ae.c new file mode 100644 index 0000000..8efa730 --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-ae.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include + +#include +#include +#include + +/* Put event loop in the global scope, so it can be explicitly stopped */ +static aeEventLoop *loop; + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + aeStop(loop); + return; + } + + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + aeStop(loop); + return; + } + + printf("Disconnected...\n"); + aeStop(loop); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + loop = aeCreateEventLoop(64); + redisAeAttach(loop, c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + aeMain(loop); + return 0; +} + diff --git a/ext/hiredis-0.14.1/examples/example-glib.c b/ext/hiredis-0.14.1/examples/example-glib.c new file mode 100644 index 0000000..d6e10f8 --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-glib.c @@ -0,0 +1,73 @@ +#include + +#include +#include +#include + +static GMainLoop *mainloop; + +static void +connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, + int status) +{ + if (status != REDIS_OK) { + g_printerr("Failed to connect: %s\n", ac->errstr); + g_main_loop_quit(mainloop); + } else { + g_printerr("Connected...\n"); + } +} + +static void +disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, + int status) +{ + if (status != REDIS_OK) { + g_error("Failed to disconnect: %s", ac->errstr); + } else { + g_printerr("Disconnected...\n"); + g_main_loop_quit(mainloop); + } +} + +static void +command_cb(redisAsyncContext *ac, + gpointer r, + gpointer user_data G_GNUC_UNUSED) +{ + redisReply *reply = r; + + if (reply) { + g_print("REPLY: %s\n", reply->str); + } + + redisAsyncDisconnect(ac); +} + +gint +main (gint argc G_GNUC_UNUSED, + gchar *argv[] G_GNUC_UNUSED) +{ + redisAsyncContext *ac; + GMainContext *context = NULL; + GSource *source; + + ac = redisAsyncConnect("127.0.0.1", 6379); + if (ac->err) { + g_printerr("%s\n", ac->errstr); + exit(EXIT_FAILURE); + } + + source = redis_source_new(ac); + mainloop = g_main_loop_new(context, FALSE); + g_source_attach(source, context); + + redisAsyncSetConnectCallback(ac, connect_cb); + redisAsyncSetDisconnectCallback(ac, disconnect_cb); + redisAsyncCommand(ac, command_cb, NULL, "SET key 1234"); + redisAsyncCommand(ac, command_cb, NULL, "GET key"); + + g_main_loop_run(mainloop); + + return EXIT_SUCCESS; +} diff --git a/ext/hiredis-0.14.1/examples/example-ivykis.c b/ext/hiredis-0.14.1/examples/example-ivykis.c new file mode 100644 index 0000000..67affce --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-ivykis.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + iv_init(); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisIvykisAttach(c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + + iv_main(); + + iv_deinit(); + + return 0; +} diff --git a/ext/hiredis-0.14.1/examples/example-libev.c b/ext/hiredis-0.14.1/examples/example-libev.c new file mode 100644 index 0000000..cc8b166 --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-libev.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibevAttach(EV_DEFAULT_ c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + ev_loop(EV_DEFAULT_ 0); + return 0; +} diff --git a/ext/hiredis-0.14.1/examples/example-libevent.c b/ext/hiredis-0.14.1/examples/example-libevent.c new file mode 100644 index 0000000..d333c22 --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-libevent.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + struct event_base *base = event_base_new(); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibeventAttach(c,base); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + event_base_dispatch(base); + return 0; +} diff --git a/ext/hiredis-0.14.1/examples/example-libuv.c b/ext/hiredis-0.14.1/examples/example-libuv.c new file mode 100644 index 0000000..a5462d4 --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-libuv.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + uv_loop_t* loop = uv_default_loop(); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibuvAttach(c,loop); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} diff --git a/ext/hiredis-0.14.1/examples/example-macosx.c b/ext/hiredis-0.14.1/examples/example-macosx.c new file mode 100644 index 0000000..bc84ed5 --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-macosx.c @@ -0,0 +1,66 @@ +// +// Created by Дмитрий Бахвалов on 13.07.15. +// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. +// + +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + CFRunLoopStop(CFRunLoopGetCurrent()); + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + CFRunLoopRef loop = CFRunLoopGetCurrent(); + if( !loop ) { + printf("Error: Cannot get current run loop\n"); + return 1; + } + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisMacOSAttach(c, loop); + + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + + CFRunLoopRun(); + + return 0; +} + diff --git a/ext/hiredis-0.14.1/examples/example-qt.cpp b/ext/hiredis-0.14.1/examples/example-qt.cpp new file mode 100644 index 0000000..f524c3f --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-qt.cpp @@ -0,0 +1,46 @@ +#include +using namespace std; + +#include +#include + +#include "example-qt.h" + +void getCallback(redisAsyncContext *, void * r, void * privdata) { + + redisReply * reply = static_cast(r); + ExampleQt * ex = static_cast(privdata); + if (reply == nullptr || ex == nullptr) return; + + cout << "key: " << reply->str << endl; + + ex->finish(); +} + +void ExampleQt::run() { + + m_ctx = redisAsyncConnect("localhost", 6379); + + if (m_ctx->err) { + cerr << "Error: " << m_ctx->errstr << endl; + redisAsyncFree(m_ctx); + emit finished(); + } + + m_adapter.setContext(m_ctx); + + redisAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value); + redisAsyncCommand(m_ctx, getCallback, this, "GET key"); +} + +int main (int argc, char **argv) { + + QCoreApplication app(argc, argv); + + ExampleQt example(argv[argc-1]); + + QObject::connect(&example, SIGNAL(finished()), &app, SLOT(quit())); + QTimer::singleShot(0, &example, SLOT(run())); + + return app.exec(); +} diff --git a/ext/hiredis-0.14.1/examples/example-qt.h b/ext/hiredis-0.14.1/examples/example-qt.h new file mode 100644 index 0000000..374f476 --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example-qt.h @@ -0,0 +1,32 @@ +#ifndef __HIREDIS_EXAMPLE_QT_H +#define __HIREDIS_EXAMPLE_QT_H + +#include + +class ExampleQt : public QObject { + + Q_OBJECT + + public: + ExampleQt(const char * value, QObject * parent = 0) + : QObject(parent), m_value(value) {} + + signals: + void finished(); + + public slots: + void run(); + + private: + void finish() { emit finished(); } + + private: + const char * m_value; + redisAsyncContext * m_ctx; + RedisQtAdapter m_adapter; + + friend + void getCallback(redisAsyncContext *, void *, void *); +}; + +#endif /* !__HIREDIS_EXAMPLE_QT_H */ diff --git a/ext/hiredis-0.14.1/examples/example.c b/ext/hiredis-0.14.1/examples/example.c new file mode 100644 index 0000000..4d494c5 --- /dev/null +++ b/ext/hiredis-0.14.1/examples/example.c @@ -0,0 +1,78 @@ +#include +#include +#include + +#include + +int main(int argc, char **argv) { + unsigned int j; + redisContext *c; + redisReply *reply; + const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; + int port = (argc > 2) ? atoi(argv[2]) : 6379; + + struct timeval timeout = { 1, 500000 }; // 1.5 seconds + c = redisConnectWithTimeout(hostname, port, timeout); + if (c == NULL || c->err) { + if (c) { + printf("Connection error: %s\n", c->errstr); + redisFree(c); + } else { + printf("Connection error: can't allocate redis context\n"); + } + exit(1); + } + + /* PING server */ + reply = redisCommand(c,"PING"); + printf("PING: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key */ + reply = redisCommand(c,"SET %s %s", "foo", "hello world"); + printf("SET: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key using binary safe API */ + reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); + printf("SET (binary API): %s\n", reply->str); + freeReplyObject(reply); + + /* Try a GET and two INCR */ + reply = redisCommand(c,"GET foo"); + printf("GET foo: %s\n", reply->str); + freeReplyObject(reply); + + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + /* again ... */ + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + + /* Create a list of numbers, from 0 to 9 */ + reply = redisCommand(c,"DEL mylist"); + freeReplyObject(reply); + for (j = 0; j < 10; j++) { + char buf[64]; + + snprintf(buf,64,"%u",j); + reply = redisCommand(c,"LPUSH mylist element-%s", buf); + freeReplyObject(reply); + } + + /* Let's check what we have inside the list */ + reply = redisCommand(c,"LRANGE mylist 0 -1"); + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + printf("%u) %s\n", j, reply->element[j]->str); + } + } + freeReplyObject(reply); + + /* Disconnects and frees the context */ + redisFree(c); + + return 0; +} diff --git a/ext/hiredis-0.14.1/fmacros.h b/ext/hiredis-0.14.1/fmacros.h new file mode 100644 index 0000000..3227faa --- /dev/null +++ b/ext/hiredis-0.14.1/fmacros.h @@ -0,0 +1,12 @@ +#ifndef __HIREDIS_FMACRO_H +#define __HIREDIS_FMACRO_H + +#define _XOPEN_SOURCE 600 +#define _POSIX_C_SOURCE 200112L + +#if defined(__APPLE__) && defined(__MACH__) +/* Enable TCP_KEEPALIVE */ +#define _DARWIN_C_SOURCE +#endif + +#endif diff --git a/ext/hiredis-0.14.1/hiredis.c b/ext/hiredis-0.14.1/hiredis.c new file mode 100644 index 0000000..98f43c9 --- /dev/null +++ b/ext/hiredis-0.14.1/hiredis.c @@ -0,0 +1,1006 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include +#include +#include +#include +#include +#include + +#include "hiredis.h" +#include "net.h" +#include "sds.h" + +static redisReply *createReplyObject(int type); +static void *createStringObject(const redisReadTask *task, char *str, size_t len); +static void *createArrayObject(const redisReadTask *task, int elements); +static void *createIntegerObject(const redisReadTask *task, long long value); +static void *createNilObject(const redisReadTask *task); + +/* Default set of functions to build the reply. Keep in mind that such a + * function returning NULL is interpreted as OOM. */ +static redisReplyObjectFunctions defaultFunctions = { + createStringObject, + createArrayObject, + createIntegerObject, + createNilObject, + freeReplyObject +}; + +/* Create a reply object */ +static redisReply *createReplyObject(int type) { + redisReply *r = calloc(1,sizeof(*r)); + + if (r == NULL) + return NULL; + + r->type = type; + return r; +} + +/* Free a reply object */ +void freeReplyObject(void *reply) { + redisReply *r = reply; + size_t j; + + if (r == NULL) + return; + + switch(r->type) { + case REDIS_REPLY_INTEGER: + break; /* Nothing to free */ + case REDIS_REPLY_ARRAY: + if (r->element != NULL) { + for (j = 0; j < r->elements; j++) + freeReplyObject(r->element[j]); + free(r->element); + } + break; + case REDIS_REPLY_ERROR: + case REDIS_REPLY_STATUS: + case REDIS_REPLY_STRING: + free(r->str); + break; + } + free(r); +} + +static void *createStringObject(const redisReadTask *task, char *str, size_t len) { + redisReply *r, *parent; + char *buf; + + r = createReplyObject(task->type); + if (r == NULL) + return NULL; + + buf = malloc(len+1); + if (buf == NULL) { + freeReplyObject(r); + return NULL; + } + + assert(task->type == REDIS_REPLY_ERROR || + task->type == REDIS_REPLY_STATUS || + task->type == REDIS_REPLY_STRING); + + /* Copy string value */ + memcpy(buf,str,len); + buf[len] = '\0'; + r->str = buf; + r->len = len; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY); + parent->element[task->idx] = r; + } + return r; +} + +static void *createArrayObject(const redisReadTask *task, int elements) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_ARRAY); + if (r == NULL) + return NULL; + + if (elements > 0) { + r->element = calloc(elements,sizeof(redisReply*)); + if (r->element == NULL) { + freeReplyObject(r); + return NULL; + } + } + + r->elements = elements; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY); + parent->element[task->idx] = r; + } + return r; +} + +static void *createIntegerObject(const redisReadTask *task, long long value) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_INTEGER); + if (r == NULL) + return NULL; + + r->integer = value; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY); + parent->element[task->idx] = r; + } + return r; +} + +static void *createNilObject(const redisReadTask *task) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_NIL); + if (r == NULL) + return NULL; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY); + parent->element[task->idx] = r; + } + return r; +} + +/* Return the number of digits of 'v' when converted to string in radix 10. + * Implementation borrowed from link in redis/src/util.c:string2ll(). */ +static uint32_t countDigits(uint64_t v) { + uint32_t result = 1; + for (;;) { + if (v < 10) return result; + if (v < 100) return result + 1; + if (v < 1000) return result + 2; + if (v < 10000) return result + 3; + v /= 10000U; + result += 4; + } +} + +/* Helper that calculates the bulk length given a certain string length. */ +static size_t bulklen(size_t len) { + return 1+countDigits(len)+2+len+2; +} + +int redisvFormatCommand(char **target, const char *format, va_list ap) { + const char *c = format; + char *cmd = NULL; /* final command */ + int pos; /* position in final command */ + sds curarg, newarg; /* current argument */ + int touched = 0; /* was the current argument touched? */ + char **curargv = NULL, **newargv = NULL; + int argc = 0; + int totlen = 0; + int error_type = 0; /* 0 = no error; -1 = memory error; -2 = format error */ + int j; + + /* Abort if there is not target to set */ + if (target == NULL) + return -1; + + /* Build the command string accordingly to protocol */ + curarg = sdsempty(); + if (curarg == NULL) + return -1; + + while(*c != '\0') { + if (*c != '%' || c[1] == '\0') { + if (*c == ' ') { + if (touched) { + newargv = realloc(curargv,sizeof(char*)*(argc+1)); + if (newargv == NULL) goto memory_err; + curargv = newargv; + curargv[argc++] = curarg; + totlen += bulklen(sdslen(curarg)); + + /* curarg is put in argv so it can be overwritten. */ + curarg = sdsempty(); + if (curarg == NULL) goto memory_err; + touched = 0; + } + } else { + newarg = sdscatlen(curarg,c,1); + if (newarg == NULL) goto memory_err; + curarg = newarg; + touched = 1; + } + } else { + char *arg; + size_t size; + + /* Set newarg so it can be checked even if it is not touched. */ + newarg = curarg; + + switch(c[1]) { + case 's': + arg = va_arg(ap,char*); + size = strlen(arg); + if (size > 0) + newarg = sdscatlen(curarg,arg,size); + break; + case 'b': + arg = va_arg(ap,char*); + size = va_arg(ap,size_t); + if (size > 0) + newarg = sdscatlen(curarg,arg,size); + break; + case '%': + newarg = sdscat(curarg,"%"); + break; + default: + /* Try to detect printf format */ + { + static const char intfmts[] = "diouxX"; + static const char flags[] = "#0-+ "; + char _format[16]; + const char *_p = c+1; + size_t _l = 0; + va_list _cpy; + + /* Flags */ + while (*_p != '\0' && strchr(flags,*_p) != NULL) _p++; + + /* Field width */ + while (*_p != '\0' && isdigit(*_p)) _p++; + + /* Precision */ + if (*_p == '.') { + _p++; + while (*_p != '\0' && isdigit(*_p)) _p++; + } + + /* Copy va_list before consuming with va_arg */ + va_copy(_cpy,ap); + + /* Integer conversion (without modifiers) */ + if (strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); + goto fmt_valid; + } + + /* Double conversion (without modifiers) */ + if (strchr("eEfFgGaA",*_p) != NULL) { + va_arg(ap,double); + goto fmt_valid; + } + + /* Size: char */ + if (_p[0] == 'h' && _p[1] == 'h') { + _p += 2; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); /* char gets promoted to int */ + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: short */ + if (_p[0] == 'h') { + _p += 1; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); /* short gets promoted to int */ + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: long long */ + if (_p[0] == 'l' && _p[1] == 'l') { + _p += 2; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,long long); + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: long */ + if (_p[0] == 'l') { + _p += 1; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,long); + goto fmt_valid; + } + goto fmt_invalid; + } + + fmt_invalid: + va_end(_cpy); + goto format_err; + + fmt_valid: + _l = (_p+1)-c; + if (_l < sizeof(_format)-2) { + memcpy(_format,c,_l); + _format[_l] = '\0'; + newarg = sdscatvprintf(curarg,_format,_cpy); + + /* Update current position (note: outer blocks + * increment c twice so compensate here) */ + c = _p-1; + } + + va_end(_cpy); + break; + } + } + + if (newarg == NULL) goto memory_err; + curarg = newarg; + + touched = 1; + c++; + } + c++; + } + + /* Add the last argument if needed */ + if (touched) { + newargv = realloc(curargv,sizeof(char*)*(argc+1)); + if (newargv == NULL) goto memory_err; + curargv = newargv; + curargv[argc++] = curarg; + totlen += bulklen(sdslen(curarg)); + } else { + sdsfree(curarg); + } + + /* Clear curarg because it was put in curargv or was free'd. */ + curarg = NULL; + + /* Add bytes needed to hold multi bulk count */ + totlen += 1+countDigits(argc)+2; + + /* Build the command at protocol level */ + cmd = malloc(totlen+1); + if (cmd == NULL) goto memory_err; + + pos = sprintf(cmd,"*%d\r\n",argc); + for (j = 0; j < argc; j++) { + pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j])); + memcpy(cmd+pos,curargv[j],sdslen(curargv[j])); + pos += sdslen(curargv[j]); + sdsfree(curargv[j]); + cmd[pos++] = '\r'; + cmd[pos++] = '\n'; + } + assert(pos == totlen); + cmd[pos] = '\0'; + + free(curargv); + *target = cmd; + return totlen; + +format_err: + error_type = -2; + goto cleanup; + +memory_err: + error_type = -1; + goto cleanup; + +cleanup: + if (curargv) { + while(argc--) + sdsfree(curargv[argc]); + free(curargv); + } + + sdsfree(curarg); + free(cmd); + + return error_type; +} + +/* Format a command according to the Redis protocol. This function + * takes a format similar to printf: + * + * %s represents a C null terminated string you want to interpolate + * %b represents a binary safe string + * + * When using %b you need to provide both the pointer to the string + * and the length in bytes as a size_t. Examples: + * + * len = redisFormatCommand(target, "GET %s", mykey); + * len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen); + */ +int redisFormatCommand(char **target, const char *format, ...) { + va_list ap; + int len; + va_start(ap,format); + len = redisvFormatCommand(target,format,ap); + va_end(ap); + + /* The API says "-1" means bad result, but we now also return "-2" in some + * cases. Force the return value to always be -1. */ + if (len < 0) + len = -1; + + return len; +} + +/* Format a command according to the Redis protocol using an sds string and + * sdscatfmt for the processing of arguments. This function takes the + * number of arguments, an array with arguments and an array with their + * lengths. If the latter is set to NULL, strlen will be used to compute the + * argument lengths. + */ +int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv, + const size_t *argvlen) +{ + sds cmd; + unsigned long long totlen; + int j; + size_t len; + + /* Abort on a NULL target */ + if (target == NULL) + return -1; + + /* Calculate our total size */ + totlen = 1+countDigits(argc)+2; + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + totlen += bulklen(len); + } + + /* Use an SDS string for command construction */ + cmd = sdsempty(); + if (cmd == NULL) + return -1; + + /* We already know how much storage we need */ + cmd = sdsMakeRoomFor(cmd, totlen); + if (cmd == NULL) + return -1; + + /* Construct command */ + cmd = sdscatfmt(cmd, "*%i\r\n", argc); + for (j=0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + cmd = sdscatfmt(cmd, "$%u\r\n", len); + cmd = sdscatlen(cmd, argv[j], len); + cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1); + } + + assert(sdslen(cmd)==totlen); + + *target = cmd; + return totlen; +} + +void redisFreeSdsCommand(sds cmd) { + sdsfree(cmd); +} + +/* Format a command according to the Redis protocol. This function takes the + * number of arguments, an array with arguments and an array with their + * lengths. If the latter is set to NULL, strlen will be used to compute the + * argument lengths. + */ +int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) { + char *cmd = NULL; /* final command */ + int pos; /* position in final command */ + size_t len; + int totlen, j; + + /* Abort on a NULL target */ + if (target == NULL) + return -1; + + /* Calculate number of bytes needed for the command */ + totlen = 1+countDigits(argc)+2; + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + totlen += bulklen(len); + } + + /* Build the command at protocol level */ + cmd = malloc(totlen+1); + if (cmd == NULL) + return -1; + + pos = sprintf(cmd,"*%d\r\n",argc); + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + pos += sprintf(cmd+pos,"$%zu\r\n",len); + memcpy(cmd+pos,argv[j],len); + pos += len; + cmd[pos++] = '\r'; + cmd[pos++] = '\n'; + } + assert(pos == totlen); + cmd[pos] = '\0'; + + *target = cmd; + return totlen; +} + +void redisFreeCommand(char *cmd) { + free(cmd); +} + +void __redisSetError(redisContext *c, int type, const char *str) { + size_t len; + + c->err = type; + if (str != NULL) { + len = strlen(str); + len = len < (sizeof(c->errstr)-1) ? len : (sizeof(c->errstr)-1); + memcpy(c->errstr,str,len); + c->errstr[len] = '\0'; + } else { + /* Only REDIS_ERR_IO may lack a description! */ + assert(type == REDIS_ERR_IO); + strerror_r(errno, c->errstr, sizeof(c->errstr)); + } +} + +redisReader *redisReaderCreate(void) { + return redisReaderCreateWithFunctions(&defaultFunctions); +} + +static redisContext *redisContextInit(void) { + redisContext *c; + + c = calloc(1,sizeof(redisContext)); + if (c == NULL) + return NULL; + + c->obuf = sdsempty(); + c->reader = redisReaderCreate(); + + if (c->obuf == NULL || c->reader == NULL) { + redisFree(c); + return NULL; + } + + return c; +} + +void redisFree(redisContext *c) { + if (c == NULL) + return; + if (c->fd > 0) + close(c->fd); + sdsfree(c->obuf); + redisReaderFree(c->reader); + free(c->tcp.host); + free(c->tcp.source_addr); + free(c->unix_sock.path); + free(c->timeout); + free(c); +} + +int redisFreeKeepFd(redisContext *c) { + int fd = c->fd; + c->fd = -1; + redisFree(c); + return fd; +} + +int redisReconnect(redisContext *c) { + c->err = 0; + memset(c->errstr, '\0', strlen(c->errstr)); + + if (c->fd > 0) { + close(c->fd); + } + + sdsfree(c->obuf); + redisReaderFree(c->reader); + + c->obuf = sdsempty(); + c->reader = redisReaderCreate(); + + if (c->connection_type == REDIS_CONN_TCP) { + return redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port, + c->timeout, c->tcp.source_addr); + } else if (c->connection_type == REDIS_CONN_UNIX) { + return redisContextConnectUnix(c, c->unix_sock.path, c->timeout); + } else { + /* Something bad happened here and shouldn't have. There isn't + enough information in the context to reconnect. */ + __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect"); + } + + return REDIS_ERR; +} + +/* Connect to a Redis instance. On error the field error in the returned + * context will be set to the return value of the error function. + * When no set of reply functions is given, the default set will be used. */ +redisContext *redisConnect(const char *ip, int port) { + redisContext *c; + + c = redisContextInit(); + if (c == NULL) + return NULL; + + c->flags |= REDIS_BLOCK; + redisContextConnectTcp(c,ip,port,NULL); + return c; +} + +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) { + redisContext *c; + + c = redisContextInit(); + if (c == NULL) + return NULL; + + c->flags |= REDIS_BLOCK; + redisContextConnectTcp(c,ip,port,&tv); + return c; +} + +redisContext *redisConnectNonBlock(const char *ip, int port) { + redisContext *c; + + c = redisContextInit(); + if (c == NULL) + return NULL; + + c->flags &= ~REDIS_BLOCK; + redisContextConnectTcp(c,ip,port,NULL); + return c; +} + +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr) { + redisContext *c = redisContextInit(); + if (c == NULL) + return NULL; + c->flags &= ~REDIS_BLOCK; + redisContextConnectBindTcp(c,ip,port,NULL,source_addr); + return c; +} + +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr) { + redisContext *c = redisContextInit(); + if (c == NULL) + return NULL; + c->flags &= ~REDIS_BLOCK; + c->flags |= REDIS_REUSEADDR; + redisContextConnectBindTcp(c,ip,port,NULL,source_addr); + return c; +} + +redisContext *redisConnectUnix(const char *path) { + redisContext *c; + + c = redisContextInit(); + if (c == NULL) + return NULL; + + c->flags |= REDIS_BLOCK; + redisContextConnectUnix(c,path,NULL); + return c; +} + +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) { + redisContext *c; + + c = redisContextInit(); + if (c == NULL) + return NULL; + + c->flags |= REDIS_BLOCK; + redisContextConnectUnix(c,path,&tv); + return c; +} + +redisContext *redisConnectUnixNonBlock(const char *path) { + redisContext *c; + + c = redisContextInit(); + if (c == NULL) + return NULL; + + c->flags &= ~REDIS_BLOCK; + redisContextConnectUnix(c,path,NULL); + return c; +} + +redisContext *redisConnectFd(int fd) { + redisContext *c; + + c = redisContextInit(); + if (c == NULL) + return NULL; + + c->fd = fd; + c->flags |= REDIS_BLOCK | REDIS_CONNECTED; + return c; +} + +/* Set read/write timeout on a blocking socket. */ +int redisSetTimeout(redisContext *c, const struct timeval tv) { + if (c->flags & REDIS_BLOCK) + return redisContextSetTimeout(c,tv); + return REDIS_ERR; +} + +/* Enable connection KeepAlive. */ +int redisEnableKeepAlive(redisContext *c) { + if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK) + return REDIS_ERR; + return REDIS_OK; +} + +/* Use this function to handle a read event on the descriptor. It will try + * and read some bytes from the socket and feed them to the reply parser. + * + * After this function is called, you may use redisContextReadReply to + * see if there is a reply available. */ +int redisBufferRead(redisContext *c) { + char buf[1024*16]; + int nread; + + /* Return early when the context has seen an error. */ + if (c->err) + return REDIS_ERR; + + nread = read(c->fd,buf,sizeof(buf)); + if (nread == -1) { + if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { + /* Try again later */ + } else { + __redisSetError(c,REDIS_ERR_IO,NULL); + return REDIS_ERR; + } + } else if (nread == 0) { + __redisSetError(c,REDIS_ERR_EOF,"Server closed the connection"); + return REDIS_ERR; + } else { + if (redisReaderFeed(c->reader,buf,nread) != REDIS_OK) { + __redisSetError(c,c->reader->err,c->reader->errstr); + return REDIS_ERR; + } + } + return REDIS_OK; +} + +/* Write the output buffer to the socket. + * + * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was + * successfully written to the socket. When the buffer is empty after the + * write operation, "done" is set to 1 (if given). + * + * Returns REDIS_ERR if an error occurred trying to write and sets + * c->errstr to hold the appropriate error string. + */ +int redisBufferWrite(redisContext *c, int *done) { + int nwritten; + + /* Return early when the context has seen an error. */ + if (c->err) + return REDIS_ERR; + + if (sdslen(c->obuf) > 0) { + nwritten = write(c->fd,c->obuf,sdslen(c->obuf)); + if (nwritten == -1) { + if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { + /* Try again later */ + } else { + __redisSetError(c,REDIS_ERR_IO,NULL); + return REDIS_ERR; + } + } else if (nwritten > 0) { + if (nwritten == (signed)sdslen(c->obuf)) { + sdsfree(c->obuf); + c->obuf = sdsempty(); + } else { + sdsrange(c->obuf,nwritten,-1); + } + } + } + if (done != NULL) *done = (sdslen(c->obuf) == 0); + return REDIS_OK; +} + +/* Internal helper function to try and get a reply from the reader, + * or set an error in the context otherwise. */ +int redisGetReplyFromReader(redisContext *c, void **reply) { + if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) { + __redisSetError(c,c->reader->err,c->reader->errstr); + return REDIS_ERR; + } + return REDIS_OK; +} + +int redisGetReply(redisContext *c, void **reply) { + int wdone = 0; + void *aux = NULL; + + /* Try to read pending replies */ + if (redisGetReplyFromReader(c,&aux) == REDIS_ERR) + return REDIS_ERR; + + /* For the blocking context, flush output buffer and read reply */ + if (aux == NULL && c->flags & REDIS_BLOCK) { + /* Write until done */ + do { + if (redisBufferWrite(c,&wdone) == REDIS_ERR) + return REDIS_ERR; + } while (!wdone); + + /* Read until there is a reply */ + do { + if (redisBufferRead(c) == REDIS_ERR) + return REDIS_ERR; + if (redisGetReplyFromReader(c,&aux) == REDIS_ERR) + return REDIS_ERR; + } while (aux == NULL); + } + + /* Set reply object */ + if (reply != NULL) *reply = aux; + return REDIS_OK; +} + + +/* Helper function for the redisAppendCommand* family of functions. + * + * Write a formatted command to the output buffer. When this family + * is used, you need to call redisGetReply yourself to retrieve + * the reply (or replies in pub/sub). + */ +int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) { + sds newbuf; + + newbuf = sdscatlen(c->obuf,cmd,len); + if (newbuf == NULL) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } + + c->obuf = newbuf; + return REDIS_OK; +} + +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) { + + if (__redisAppendCommand(c, cmd, len) != REDIS_OK) { + return REDIS_ERR; + } + + return REDIS_OK; +} + +int redisvAppendCommand(redisContext *c, const char *format, va_list ap) { + char *cmd; + int len; + + len = redisvFormatCommand(&cmd,format,ap); + if (len == -1) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } else if (len == -2) { + __redisSetError(c,REDIS_ERR_OTHER,"Invalid format string"); + return REDIS_ERR; + } + + if (__redisAppendCommand(c,cmd,len) != REDIS_OK) { + free(cmd); + return REDIS_ERR; + } + + free(cmd); + return REDIS_OK; +} + +int redisAppendCommand(redisContext *c, const char *format, ...) { + va_list ap; + int ret; + + va_start(ap,format); + ret = redisvAppendCommand(c,format,ap); + va_end(ap); + return ret; +} + +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { + sds cmd; + int len; + + len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); + if (len == -1) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } + + if (__redisAppendCommand(c,cmd,len) != REDIS_OK) { + sdsfree(cmd); + return REDIS_ERR; + } + + sdsfree(cmd); + return REDIS_OK; +} + +/* Helper function for the redisCommand* family of functions. + * + * Write a formatted command to the output buffer. If the given context is + * blocking, immediately read the reply into the "reply" pointer. When the + * context is non-blocking, the "reply" pointer will not be used and the + * command is simply appended to the write buffer. + * + * Returns the reply when a reply was successfully retrieved. Returns NULL + * otherwise. When NULL is returned in a blocking context, the error field + * in the context will be set. + */ +static void *__redisBlockForReply(redisContext *c) { + void *reply; + + if (c->flags & REDIS_BLOCK) { + if (redisGetReply(c,&reply) != REDIS_OK) + return NULL; + return reply; + } + return NULL; +} + +void *redisvCommand(redisContext *c, const char *format, va_list ap) { + if (redisvAppendCommand(c,format,ap) != REDIS_OK) + return NULL; + return __redisBlockForReply(c); +} + +void *redisCommand(redisContext *c, const char *format, ...) { + va_list ap; + va_start(ap,format); + void *reply = redisvCommand(c,format,ap); + va_end(ap); + return reply; +} + +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { + if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK) + return NULL; + return __redisBlockForReply(c); +} diff --git a/ext/hiredis-0.14.1/hiredis.h b/ext/hiredis-0.14.1/hiredis.h new file mode 100644 index 0000000..d945bf2 --- /dev/null +++ b/ext/hiredis-0.14.1/hiredis.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_H +#define __HIREDIS_H +#include "read.h" +#include /* for va_list */ +#include /* for struct timeval */ +#include /* uintXX_t, etc */ +#include "sds.h" /* for sds */ +#include "alloc.h" /* for allocation wrappers */ + +#define HIREDIS_MAJOR 0 +#define HIREDIS_MINOR 14 +#define HIREDIS_PATCH 1 +#define HIREDIS_SONAME 0.14 + +/* Connection type can be blocking or non-blocking and is set in the + * least significant bit of the flags field in redisContext. */ +#define REDIS_BLOCK 0x1 + +/* Connection may be disconnected before being free'd. The second bit + * in the flags field is set when the context is connected. */ +#define REDIS_CONNECTED 0x2 + +/* The async API might try to disconnect cleanly and flush the output + * buffer and read all subsequent replies before disconnecting. + * This flag means no new commands can come in and the connection + * should be terminated once all replies have been read. */ +#define REDIS_DISCONNECTING 0x4 + +/* Flag specific to the async API which means that the context should be clean + * up as soon as possible. */ +#define REDIS_FREEING 0x8 + +/* Flag that is set when an async callback is executed. */ +#define REDIS_IN_CALLBACK 0x10 + +/* Flag that is set when the async context has one or more subscriptions. */ +#define REDIS_SUBSCRIBED 0x20 + +/* Flag that is set when monitor mode is active */ +#define REDIS_MONITORING 0x40 + +/* Flag that is set when we should set SO_REUSEADDR before calling bind() */ +#define REDIS_REUSEADDR 0x80 + +#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ + +/* number of times we retry to connect in the case of EADDRNOTAVAIL and + * SO_REUSEADDR is being used. */ +#define REDIS_CONNECT_RETRIES 10 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the reply object returned by redisCommand() */ +typedef struct redisReply { + int type; /* REDIS_REPLY_* */ + long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ + size_t len; /* Length of string */ + char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ + size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ + struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ +} redisReply; + +redisReader *redisReaderCreate(void); + +/* Function to free the reply objects hiredis returns by default. */ +void freeReplyObject(void *reply); + +/* Functions to format a command according to the protocol. */ +int redisvFormatCommand(char **target, const char *format, va_list ap); +int redisFormatCommand(char **target, const char *format, ...); +int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); +int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); +void redisFreeCommand(char *cmd); +void redisFreeSdsCommand(sds cmd); + +enum redisConnectionType { + REDIS_CONN_TCP, + REDIS_CONN_UNIX +}; + +/* Context for a connection to Redis */ +typedef struct redisContext { + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + int fd; + int flags; + char *obuf; /* Write buffer */ + redisReader *reader; /* Protocol reader */ + + enum redisConnectionType connection_type; + struct timeval *timeout; + + struct { + char *host; + char *source_addr; + int port; + } tcp; + + struct { + char *path; + } unix_sock; + +} redisContext; + +redisContext *redisConnect(const char *ip, int port); +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); +redisContext *redisConnectNonBlock(const char *ip, int port); +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectUnix(const char *path); +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); +redisContext *redisConnectUnixNonBlock(const char *path); +redisContext *redisConnectFd(int fd); + +/** + * Reconnect the given context using the saved information. + * + * This re-uses the exact same connect options as in the initial connection. + * host, ip (or path), timeout and bind address are reused, + * flags are used unmodified from the existing context. + * + * Returns REDIS_OK on successful connect or REDIS_ERR otherwise. + */ +int redisReconnect(redisContext *c); + +int redisSetTimeout(redisContext *c, const struct timeval tv); +int redisEnableKeepAlive(redisContext *c); +void redisFree(redisContext *c); +int redisFreeKeepFd(redisContext *c); +int redisBufferRead(redisContext *c); +int redisBufferWrite(redisContext *c, int *done); + +/* In a blocking context, this function first checks if there are unconsumed + * replies to return and returns one if so. Otherwise, it flushes the output + * buffer to the socket and reads until it has a reply. In a non-blocking + * context, it will return unconsumed replies until there are no more. */ +int redisGetReply(redisContext *c, void **reply); +int redisGetReplyFromReader(redisContext *c, void **reply); + +/* Write a formatted command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); + +/* Write a command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisvAppendCommand(redisContext *c, const char *format, va_list ap); +int redisAppendCommand(redisContext *c, const char *format, ...); +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +/* Issue a command to Redis. In a blocking context, it is identical to calling + * redisAppendCommand, followed by redisGetReply. The function will return + * NULL if there was an error in performing the request, otherwise it will + * return the reply. In a non-blocking context, it is identical to calling + * only redisAppendCommand and will always return NULL. */ +void *redisvCommand(redisContext *c, const char *format, va_list ap); +void *redisCommand(redisContext *c, const char *format, ...); +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-0.14.1/include/hiredis/alloc.h b/ext/hiredis-0.14.1/include/hiredis/alloc.h new file mode 100644 index 0000000..2c9b04e --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/alloc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HIREDIS_ALLOC_H +#define HIREDIS_ALLOC_H + +#include /* for size_t */ + +#ifndef HIREDIS_OOM_HANDLER +#define HIREDIS_OOM_HANDLER abort() +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void *hi_malloc(size_t size); +void *hi_calloc(size_t nmemb, size_t size); +void *hi_realloc(void *ptr, size_t size); +char *hi_strdup(const char *str); + +#ifdef __cplusplus +} +#endif + +#endif /* HIREDIS_ALLOC_H */ diff --git a/ext/hiredis-0.14.1/include/hiredis/async.h b/ext/hiredis-0.14.1/include/hiredis/async.h new file mode 100644 index 0000000..e69d840 --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/async.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_ASYNC_H +#define __HIREDIS_ASYNC_H +#include "hiredis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ +struct dict; /* dictionary header is included in async.c */ + +/* Reply callback prototype and container */ +typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); +typedef struct redisCallback { + struct redisCallback *next; /* simple singly linked list */ + redisCallbackFn *fn; + int pending_subs; + void *privdata; +} redisCallback; + +/* List of callbacks for either regular replies or pub/sub */ +typedef struct redisCallbackList { + redisCallback *head, *tail; +} redisCallbackList; + +/* Connection callback prototypes */ +typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); +typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); + +/* Context for an async connection to Redis */ +typedef struct redisAsyncContext { + /* Hold the regular context, so it can be realloc'ed. */ + redisContext c; + + /* Setup error flags so they can be used directly. */ + int err; + char *errstr; + + /* Not used by hiredis */ + void *data; + + /* Event library data and hooks */ + struct { + void *data; + + /* Hooks that are called when the library expects to start + * reading/writing. These functions should be idempotent. */ + void (*addRead)(void *privdata); + void (*delRead)(void *privdata); + void (*addWrite)(void *privdata); + void (*delWrite)(void *privdata); + void (*cleanup)(void *privdata); + } ev; + + /* Called when either the connection is terminated due to an error or per + * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ + redisDisconnectCallback *onDisconnect; + + /* Called when the first write event was received. */ + redisConnectCallback *onConnect; + + /* Regular command callbacks */ + redisCallbackList replies; + + /* Subscription callbacks */ + struct { + redisCallbackList invalid; + struct dict *channels; + struct dict *patterns; + } sub; +} redisAsyncContext; + +/* Functions that proxy to hiredis */ +redisAsyncContext *redisAsyncConnect(const char *ip, int port); +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr); +redisAsyncContext *redisAsyncConnectUnix(const char *path); +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); +void redisAsyncDisconnect(redisAsyncContext *ac); +void redisAsyncFree(redisAsyncContext *ac); + +/* Handle read/write events */ +void redisAsyncHandleRead(redisAsyncContext *ac); +void redisAsyncHandleWrite(redisAsyncContext *ac); + +/* Command functions for an async context. Write the command to the + * output buffer and register the provided callback. */ +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-0.14.1/include/hiredis/dict.h b/ext/hiredis-0.14.1/include/hiredis/dict.h new file mode 100644 index 0000000..95fcd28 --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/dict.h @@ -0,0 +1,126 @@ +/* Hash table implementation. + * + * This file implements in memory hash tables with insert/del/replace/find/ + * get-random-element operations. Hash tables will auto resize if needed + * tables of power of two in size are used, collisions are handled by + * chaining. See the source code for more information... :) + * + * Copyright (c) 2006-2010, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DICT_H +#define __DICT_H + +#define DICT_OK 0 +#define DICT_ERR 1 + +/* Unused arguments generate annoying warnings... */ +#define DICT_NOTUSED(V) ((void) V) + +typedef struct dictEntry { + void *key; + void *val; + struct dictEntry *next; +} dictEntry; + +typedef struct dictType { + unsigned int (*hashFunction)(const void *key); + void *(*keyDup)(void *privdata, const void *key); + void *(*valDup)(void *privdata, const void *obj); + int (*keyCompare)(void *privdata, const void *key1, const void *key2); + void (*keyDestructor)(void *privdata, void *key); + void (*valDestructor)(void *privdata, void *obj); +} dictType; + +typedef struct dict { + dictEntry **table; + dictType *type; + unsigned long size; + unsigned long sizemask; + unsigned long used; + void *privdata; +} dict; + +typedef struct dictIterator { + dict *ht; + int index; + dictEntry *entry, *nextEntry; +} dictIterator; + +/* This is the initial size of every hash table */ +#define DICT_HT_INITIAL_SIZE 4 + +/* ------------------------------- Macros ------------------------------------*/ +#define dictFreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->val) + +#define dictSetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ + else \ + entry->val = (_val_); \ +} while(0) + +#define dictFreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define dictSetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ + else \ + entry->key = (_key_); \ +} while(0) + +#define dictCompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ + (key1) == (key2)) + +#define dictHashKey(ht, key) (ht)->type->hashFunction(key) + +#define dictGetEntryKey(he) ((he)->key) +#define dictGetEntryVal(he) ((he)->val) +#define dictSlots(ht) ((ht)->size) +#define dictSize(ht) ((ht)->used) + +/* API */ +static unsigned int dictGenHashFunction(const unsigned char *buf, int len); +static dict *dictCreate(dictType *type, void *privDataPtr); +static int dictExpand(dict *ht, unsigned long size); +static int dictAdd(dict *ht, void *key, void *val); +static int dictReplace(dict *ht, void *key, void *val); +static int dictDelete(dict *ht, const void *key); +static void dictRelease(dict *ht); +static dictEntry * dictFind(dict *ht, const void *key); +static dictIterator *dictGetIterator(dict *ht); +static dictEntry *dictNext(dictIterator *iter); +static void dictReleaseIterator(dictIterator *iter); + +#endif /* __DICT_H */ diff --git a/ext/hiredis-0.14.1/include/hiredis/fmacros.h b/ext/hiredis-0.14.1/include/hiredis/fmacros.h new file mode 100644 index 0000000..3227faa --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/fmacros.h @@ -0,0 +1,12 @@ +#ifndef __HIREDIS_FMACRO_H +#define __HIREDIS_FMACRO_H + +#define _XOPEN_SOURCE 600 +#define _POSIX_C_SOURCE 200112L + +#if defined(__APPLE__) && defined(__MACH__) +/* Enable TCP_KEEPALIVE */ +#define _DARWIN_C_SOURCE +#endif + +#endif diff --git a/ext/hiredis-0.14.1/include/hiredis/hiredis.h b/ext/hiredis-0.14.1/include/hiredis/hiredis.h new file mode 100644 index 0000000..d945bf2 --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/hiredis.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_H +#define __HIREDIS_H +#include "read.h" +#include /* for va_list */ +#include /* for struct timeval */ +#include /* uintXX_t, etc */ +#include "sds.h" /* for sds */ +#include "alloc.h" /* for allocation wrappers */ + +#define HIREDIS_MAJOR 0 +#define HIREDIS_MINOR 14 +#define HIREDIS_PATCH 1 +#define HIREDIS_SONAME 0.14 + +/* Connection type can be blocking or non-blocking and is set in the + * least significant bit of the flags field in redisContext. */ +#define REDIS_BLOCK 0x1 + +/* Connection may be disconnected before being free'd. The second bit + * in the flags field is set when the context is connected. */ +#define REDIS_CONNECTED 0x2 + +/* The async API might try to disconnect cleanly and flush the output + * buffer and read all subsequent replies before disconnecting. + * This flag means no new commands can come in and the connection + * should be terminated once all replies have been read. */ +#define REDIS_DISCONNECTING 0x4 + +/* Flag specific to the async API which means that the context should be clean + * up as soon as possible. */ +#define REDIS_FREEING 0x8 + +/* Flag that is set when an async callback is executed. */ +#define REDIS_IN_CALLBACK 0x10 + +/* Flag that is set when the async context has one or more subscriptions. */ +#define REDIS_SUBSCRIBED 0x20 + +/* Flag that is set when monitor mode is active */ +#define REDIS_MONITORING 0x40 + +/* Flag that is set when we should set SO_REUSEADDR before calling bind() */ +#define REDIS_REUSEADDR 0x80 + +#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ + +/* number of times we retry to connect in the case of EADDRNOTAVAIL and + * SO_REUSEADDR is being used. */ +#define REDIS_CONNECT_RETRIES 10 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the reply object returned by redisCommand() */ +typedef struct redisReply { + int type; /* REDIS_REPLY_* */ + long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ + size_t len; /* Length of string */ + char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ + size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ + struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ +} redisReply; + +redisReader *redisReaderCreate(void); + +/* Function to free the reply objects hiredis returns by default. */ +void freeReplyObject(void *reply); + +/* Functions to format a command according to the protocol. */ +int redisvFormatCommand(char **target, const char *format, va_list ap); +int redisFormatCommand(char **target, const char *format, ...); +int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); +int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); +void redisFreeCommand(char *cmd); +void redisFreeSdsCommand(sds cmd); + +enum redisConnectionType { + REDIS_CONN_TCP, + REDIS_CONN_UNIX +}; + +/* Context for a connection to Redis */ +typedef struct redisContext { + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + int fd; + int flags; + char *obuf; /* Write buffer */ + redisReader *reader; /* Protocol reader */ + + enum redisConnectionType connection_type; + struct timeval *timeout; + + struct { + char *host; + char *source_addr; + int port; + } tcp; + + struct { + char *path; + } unix_sock; + +} redisContext; + +redisContext *redisConnect(const char *ip, int port); +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); +redisContext *redisConnectNonBlock(const char *ip, int port); +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectUnix(const char *path); +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); +redisContext *redisConnectUnixNonBlock(const char *path); +redisContext *redisConnectFd(int fd); + +/** + * Reconnect the given context using the saved information. + * + * This re-uses the exact same connect options as in the initial connection. + * host, ip (or path), timeout and bind address are reused, + * flags are used unmodified from the existing context. + * + * Returns REDIS_OK on successful connect or REDIS_ERR otherwise. + */ +int redisReconnect(redisContext *c); + +int redisSetTimeout(redisContext *c, const struct timeval tv); +int redisEnableKeepAlive(redisContext *c); +void redisFree(redisContext *c); +int redisFreeKeepFd(redisContext *c); +int redisBufferRead(redisContext *c); +int redisBufferWrite(redisContext *c, int *done); + +/* In a blocking context, this function first checks if there are unconsumed + * replies to return and returns one if so. Otherwise, it flushes the output + * buffer to the socket and reads until it has a reply. In a non-blocking + * context, it will return unconsumed replies until there are no more. */ +int redisGetReply(redisContext *c, void **reply); +int redisGetReplyFromReader(redisContext *c, void **reply); + +/* Write a formatted command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); + +/* Write a command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisvAppendCommand(redisContext *c, const char *format, va_list ap); +int redisAppendCommand(redisContext *c, const char *format, ...); +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +/* Issue a command to Redis. In a blocking context, it is identical to calling + * redisAppendCommand, followed by redisGetReply. The function will return + * NULL if there was an error in performing the request, otherwise it will + * return the reply. In a non-blocking context, it is identical to calling + * only redisAppendCommand and will always return NULL. */ +void *redisvCommand(redisContext *c, const char *format, va_list ap); +void *redisCommand(redisContext *c, const char *format, ...); +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-0.14.1/include/hiredis/net.h b/ext/hiredis-0.14.1/include/hiredis/net.h new file mode 100644 index 0000000..d9dc362 --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/net.h @@ -0,0 +1,49 @@ +/* Extracted from anet.c to work properly with Hiredis error reporting. + * + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __NET_H +#define __NET_H + +#include "hiredis.h" + +int redisCheckSocketError(redisContext *c); +int redisContextSetTimeout(redisContext *c, const struct timeval tv); +int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); +int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr); +int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); +int redisKeepAlive(redisContext *c, int interval); + +#endif diff --git a/ext/hiredis-0.14.1/include/hiredis/read.h b/ext/hiredis-0.14.1/include/hiredis/read.h new file mode 100644 index 0000000..2988aa4 --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/read.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __HIREDIS_READ_H +#define __HIREDIS_READ_H +#include /* for size_t */ + +#define REDIS_ERR -1 +#define REDIS_OK 0 + +/* When an error occurs, the err flag in a context is set to hold the type of + * error that occurred. REDIS_ERR_IO means there was an I/O error and you + * should use the "errno" variable to find out what is wrong. + * For other values, the "errstr" field will hold a description. */ +#define REDIS_ERR_IO 1 /* Error in read or write */ +#define REDIS_ERR_EOF 3 /* End of file */ +#define REDIS_ERR_PROTOCOL 4 /* Protocol error */ +#define REDIS_ERR_OOM 5 /* Out of memory */ +#define REDIS_ERR_OTHER 2 /* Everything else... */ + +#define REDIS_REPLY_STRING 1 +#define REDIS_REPLY_ARRAY 2 +#define REDIS_REPLY_INTEGER 3 +#define REDIS_REPLY_NIL 4 +#define REDIS_REPLY_STATUS 5 +#define REDIS_REPLY_ERROR 6 + +#define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct redisReadTask { + int type; + int elements; /* number of elements in multibulk container */ + int idx; /* index in parent (array) object */ + void *obj; /* holds user-generated value for a read task */ + struct redisReadTask *parent; /* parent task */ + void *privdata; /* user-settable arbitrary field */ +} redisReadTask; + +typedef struct redisReplyObjectFunctions { + void *(*createString)(const redisReadTask*, char*, size_t); + void *(*createArray)(const redisReadTask*, int); + void *(*createInteger)(const redisReadTask*, long long); + void *(*createNil)(const redisReadTask*); + void (*freeObject)(void*); +} redisReplyObjectFunctions; + +typedef struct redisReader { + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + + char *buf; /* Read buffer */ + size_t pos; /* Buffer cursor */ + size_t len; /* Buffer length */ + size_t maxbuf; /* Max length of unused buffer */ + + redisReadTask rstack[9]; + int ridx; /* Index of current read task */ + void *reply; /* Temporary reply pointer */ + + redisReplyObjectFunctions *fn; + void *privdata; +} redisReader; + +/* Public API for the protocol parser. */ +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); +void redisReaderFree(redisReader *r); +int redisReaderFeed(redisReader *r, const char *buf, size_t len); +int redisReaderGetReply(redisReader *r, void **reply); + +#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) +#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) +#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-0.14.1/include/hiredis/sds.h b/ext/hiredis-0.14.1/include/hiredis/sds.h new file mode 100644 index 0000000..13be75a --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/sds.h @@ -0,0 +1,273 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SDS_H +#define __SDS_H + +#define SDS_MAX_PREALLOC (1024*1024) + +#include +#include +#include + +typedef char *sds; + +/* Note: sdshdr5 is never used, we just access the flags byte directly. + * However is here to document the layout of type 5 SDS strings. */ +struct __attribute__ ((__packed__)) sdshdr5 { + unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr8 { + uint8_t len; /* used */ + uint8_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr16 { + uint16_t len; /* used */ + uint16_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr32 { + uint32_t len; /* used */ + uint32_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr64 { + uint64_t len; /* used */ + uint64_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; + +#define SDS_TYPE_5 0 +#define SDS_TYPE_8 1 +#define SDS_TYPE_16 2 +#define SDS_TYPE_32 3 +#define SDS_TYPE_64 4 +#define SDS_TYPE_MASK 7 +#define SDS_TYPE_BITS 3 +#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))); +#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)))) +#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) + +static inline size_t sdslen(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->len; + case SDS_TYPE_16: + return SDS_HDR(16,s)->len; + case SDS_TYPE_32: + return SDS_HDR(32,s)->len; + case SDS_TYPE_64: + return SDS_HDR(64,s)->len; + } + return 0; +} + +static inline size_t sdsavail(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + return 0; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + return sh->alloc - sh->len; + } + } + return 0; +} + +static inline void sdssetlen(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len = newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len = newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len = newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len = newlen; + break; + } +} + +static inline void sdsinclen(sds s, size_t inc) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char newlen = SDS_TYPE_5_LEN(flags)+inc; + *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len += inc; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len += inc; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len += inc; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len += inc; + break; + } +} + +/* sdsalloc() = sdsavail() + sdslen() */ +static inline size_t sdsalloc(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->alloc; + case SDS_TYPE_16: + return SDS_HDR(16,s)->alloc; + case SDS_TYPE_32: + return SDS_HDR(32,s)->alloc; + case SDS_TYPE_64: + return SDS_HDR(64,s)->alloc; + } + return 0; +} + +static inline void sdssetalloc(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + /* Nothing to do, this type has no total allocation info. */ + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->alloc = newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->alloc = newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->alloc = newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->alloc = newlen; + break; + } +} + +sds sdsnewlen(const void *init, size_t initlen); +sds sdsnew(const char *init); +sds sdsempty(void); +sds sdsdup(const sds s); +void sdsfree(sds s); +sds sdsgrowzero(sds s, size_t len); +sds sdscatlen(sds s, const void *t, size_t len); +sds sdscat(sds s, const char *t); +sds sdscatsds(sds s, const sds t); +sds sdscpylen(sds s, const char *t, size_t len); +sds sdscpy(sds s, const char *t); + +sds sdscatvprintf(sds s, const char *fmt, va_list ap); +#ifdef __GNUC__ +sds sdscatprintf(sds s, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +#else +sds sdscatprintf(sds s, const char *fmt, ...); +#endif + +sds sdscatfmt(sds s, char const *fmt, ...); +sds sdstrim(sds s, const char *cset); +void sdsrange(sds s, int start, int end); +void sdsupdatelen(sds s); +void sdsclear(sds s); +int sdscmp(const sds s1, const sds s2); +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count); +void sdsfreesplitres(sds *tokens, int count); +void sdstolower(sds s); +void sdstoupper(sds s); +sds sdsfromlonglong(long long value); +sds sdscatrepr(sds s, const char *p, size_t len); +sds *sdssplitargs(const char *line, int *argc); +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); +sds sdsjoin(char **argv, int argc, char *sep); +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen); + +/* Low level functions exposed to the user API */ +sds sdsMakeRoomFor(sds s, size_t addlen); +void sdsIncrLen(sds s, int incr); +sds sdsRemoveFreeSpace(sds s); +size_t sdsAllocSize(sds s); +void *sdsAllocPtr(sds s); + +/* Export the allocator used by SDS to the program using SDS. + * Sometimes the program SDS is linked to, may use a different set of + * allocators, but may want to allocate or free things that SDS will + * respectively free or allocate. */ +void *sds_malloc(size_t size); +void *sds_realloc(void *ptr, size_t size); +void sds_free(void *ptr); + +#ifdef REDIS_TEST +int sdsTest(int argc, char *argv[]); +#endif + +#endif diff --git a/ext/hiredis-0.14.1/include/hiredis/sdsalloc.h b/ext/hiredis-0.14.1/include/hiredis/sdsalloc.h new file mode 100644 index 0000000..f43023c --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/sdsalloc.h @@ -0,0 +1,42 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* SDS allocator selection. + * + * This file is used in order to change the SDS allocator at compile time. + * Just define the following defines to what you want to use. Also add + * the include of your alternate allocator if needed (not needed in order + * to use the default libc allocator). */ + +#define s_malloc malloc +#define s_realloc realloc +#define s_free free diff --git a/ext/hiredis-0.14.1/include/hiredis/win32.h b/ext/hiredis-0.14.1/include/hiredis/win32.h new file mode 100644 index 0000000..1a27c18 --- /dev/null +++ b/ext/hiredis-0.14.1/include/hiredis/win32.h @@ -0,0 +1,42 @@ +#ifndef _WIN32_HELPER_INCLUDE +#define _WIN32_HELPER_INCLUDE +#ifdef _MSC_VER + +#ifndef inline +#define inline __inline +#endif + +#ifndef va_copy +#define va_copy(d,s) ((d) = (s)) +#endif + +#ifndef snprintf +#define snprintf c99_snprintf + +__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +__inline int c99_snprintf(char* str, size_t size, const char* format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} +#endif + +#endif +#endif \ No newline at end of file diff --git a/ext/hiredis-0.14.1/lib/centos8/libhiredis.a b/ext/hiredis-0.14.1/lib/centos8/libhiredis.a new file mode 100644 index 0000000000000000000000000000000000000000..0b9638798529747795a78056068d5a6a980a4f02 GIT binary patch literal 485314 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 z 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

    B>x$J_T}eE{sEGII`MyuLWKRr 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 literal 0 HcmV?d00001 diff --git a/ext/hiredis-0.14.1/net.c b/ext/hiredis-0.14.1/net.c new file mode 100644 index 0000000..d71bbcd --- /dev/null +++ b/ext/hiredis-0.14.1/net.c @@ -0,0 +1,477 @@ +/* Extracted from anet.c to work properly with Hiredis error reporting. + * + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "net.h" +#include "sds.h" + +/* Defined in hiredis.c */ +void __redisSetError(redisContext *c, int type, const char *str); + +static void redisContextCloseFd(redisContext *c) { + if (c && c->fd >= 0) { + close(c->fd); + c->fd = -1; + } +} + +static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) { + int errorno = errno; /* snprintf() may change errno */ + char buf[128] = { 0 }; + size_t len = 0; + + if (prefix != NULL) + len = snprintf(buf,sizeof(buf),"%s: ",prefix); + strerror_r(errorno, (char *)(buf + len), sizeof(buf) - len); + __redisSetError(c,type,buf); +} + +static int redisSetReuseAddr(redisContext *c) { + int on = 1; + if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisContextCloseFd(c); + return REDIS_ERR; + } + return REDIS_OK; +} + +static int redisCreateSocket(redisContext *c, int type) { + int s; + if ((s = socket(type, SOCK_STREAM, 0)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + return REDIS_ERR; + } + c->fd = s; + if (type == AF_INET) { + if (redisSetReuseAddr(c) == REDIS_ERR) { + return REDIS_ERR; + } + } + return REDIS_OK; +} + +static int redisSetBlocking(redisContext *c, int blocking) { + int flags; + + /* Set the socket nonblocking. + * Note that fcntl(2) for F_GETFL and F_SETFL can't be + * interrupted by a signal. */ + if ((flags = fcntl(c->fd, F_GETFL)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); + redisContextCloseFd(c); + return REDIS_ERR; + } + + if (blocking) + flags &= ~O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (fcntl(c->fd, F_SETFL, flags) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); + redisContextCloseFd(c); + return REDIS_ERR; + } + return REDIS_OK; +} + +int redisKeepAlive(redisContext *c, int interval) { + int val = 1; + int fd = c->fd; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){ + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = interval; + +#if defined(__APPLE__) && defined(__MACH__) + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } +#else +#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = interval/3; + if (val == 0) val = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = 3; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } +#endif +#endif + + return REDIS_OK; +} + +static int redisSetTcpNoDelay(redisContext *c) { + int yes = 1; + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); + redisContextCloseFd(c); + return REDIS_ERR; + } + return REDIS_OK; +} + +#define __MAX_MSEC (((LONG_MAX) - 999) / 1000) + +static int redisContextTimeoutMsec(redisContext *c, long *result) +{ + const struct timeval *timeout = c->timeout; + long msec = -1; + + /* Only use timeout when not NULL. */ + if (timeout != NULL) { + if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { + *result = msec; + return REDIS_ERR; + } + + msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000); + + if (msec < 0 || msec > INT_MAX) { + msec = INT_MAX; + } + } + + *result = msec; + return REDIS_OK; +} + +static int redisContextWaitReady(redisContext *c, long msec) { + struct pollfd wfd[1]; + + wfd[0].fd = c->fd; + wfd[0].events = POLLOUT; + + if (errno == EINPROGRESS) { + int res; + + if ((res = poll(wfd, 1, msec)) == -1) { + __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); + redisContextCloseFd(c); + return REDIS_ERR; + } else if (res == 0) { + errno = ETIMEDOUT; + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisContextCloseFd(c); + return REDIS_ERR; + } + + if (redisCheckSocketError(c) != REDIS_OK) + return REDIS_ERR; + + return REDIS_OK; + } + + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisContextCloseFd(c); + return REDIS_ERR; +} + +int redisCheckSocketError(redisContext *c) { + int err = 0; + socklen_t errlen = sizeof(err); + + if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)"); + return REDIS_ERR; + } + + if (err) { + errno = err; + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + return REDIS_ERR; + } + + return REDIS_OK; +} + +int redisContextSetTimeout(redisContext *c, const struct timeval tv) { + if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)"); + return REDIS_ERR; + } + if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)"); + return REDIS_ERR; + } + return REDIS_OK; +} + +static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr) { + int s, rv, n; + char _port[6]; /* strlen("65535"); */ + struct addrinfo hints, *servinfo, *bservinfo, *p, *b; + int blocking = (c->flags & REDIS_BLOCK); + int reuseaddr = (c->flags & REDIS_REUSEADDR); + int reuses = 0; + long timeout_msec = -1; + + servinfo = NULL; + c->connection_type = REDIS_CONN_TCP; + c->tcp.port = port; + + /* We need to take possession of the passed parameters + * to make them reusable for a reconnect. + * We also carefully check we don't free data we already own, + * as in the case of the reconnect method. + * + * This is a bit ugly, but atleast it works and doesn't leak memory. + **/ + if (c->tcp.host != addr) { + free(c->tcp.host); + + c->tcp.host = hi_strdup(addr); + } + + if (timeout) { + if (c->timeout != timeout) { + if (c->timeout == NULL) + c->timeout = hi_malloc(sizeof(struct timeval)); + + memcpy(c->timeout, timeout, sizeof(struct timeval)); + } + } else { + free(c->timeout); + c->timeout = NULL; + } + + if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) { + __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified"); + goto error; + } + + if (source_addr == NULL) { + free(c->tcp.source_addr); + c->tcp.source_addr = NULL; + } else if (c->tcp.source_addr != source_addr) { + free(c->tcp.source_addr); + c->tcp.source_addr = hi_strdup(source_addr); + } + + snprintf(_port, 6, "%d", port); + memset(&hints,0,sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + /* Try with IPv6 if no IPv4 address was found. We do it in this order since + * in a Redis client you can't afford to test if you have IPv6 connectivity + * as this would add latency to every connect. Otherwise a more sensible + * route could be: Use IPv6 if both addresses are available and there is IPv6 + * connectivity. */ + if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) { + hints.ai_family = AF_INET6; + if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { + __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); + return REDIS_ERR; + } + } + for (p = servinfo; p != NULL; p = p->ai_next) { +addrretry: + if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) + continue; + + c->fd = s; + if (redisSetBlocking(c,0) != REDIS_OK) + goto error; + if (c->tcp.source_addr) { + int bound = 0; + /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ + if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + + if (reuseaddr) { + n = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n, + sizeof(n)) < 0) { + freeaddrinfo(bservinfo); + goto error; + } + } + + for (b = bservinfo; b != NULL; b = b->ai_next) { + if (bind(s,b->ai_addr,b->ai_addrlen) != -1) { + bound = 1; + break; + } + } + freeaddrinfo(bservinfo); + if (!bound) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + } + if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { + if (errno == EHOSTUNREACH) { + redisContextCloseFd(c); + continue; + } else if (errno == EINPROGRESS && !blocking) { + /* This is ok. */ + } else if (errno == EADDRNOTAVAIL && reuseaddr) { + if (++reuses >= REDIS_CONNECT_RETRIES) { + goto error; + } else { + redisContextCloseFd(c); + goto addrretry; + } + } else { + if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) + goto error; + } + } + if (blocking && redisSetBlocking(c,1) != REDIS_OK) + goto error; + if (redisSetTcpNoDelay(c) != REDIS_OK) + goto error; + + c->flags |= REDIS_CONNECTED; + rv = REDIS_OK; + goto end; + } + if (p == NULL) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + +error: + rv = REDIS_ERR; +end: + if(servinfo) { + freeaddrinfo(servinfo); + } + + return rv; // Need to return REDIS_OK if alright +} + +int redisContextConnectTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout) { + return _redisContextConnectTcp(c, addr, port, timeout, NULL); +} + +int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr) { + return _redisContextConnectTcp(c, addr, port, timeout, source_addr); +} + +int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) { + int blocking = (c->flags & REDIS_BLOCK); + struct sockaddr_un sa; + long timeout_msec = -1; + + if (redisCreateSocket(c,AF_UNIX) < 0) + return REDIS_ERR; + if (redisSetBlocking(c,0) != REDIS_OK) + return REDIS_ERR; + + c->connection_type = REDIS_CONN_UNIX; + if (c->unix_sock.path != path) + c->unix_sock.path = hi_strdup(path); + + if (timeout) { + if (c->timeout != timeout) { + if (c->timeout == NULL) + c->timeout = hi_malloc(sizeof(struct timeval)); + + memcpy(c->timeout, timeout, sizeof(struct timeval)); + } + } else { + free(c->timeout); + c->timeout = NULL; + } + + if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK) + return REDIS_ERR; + + sa.sun_family = AF_UNIX; + strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1); + if (connect(c->fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) { + if (errno == EINPROGRESS && !blocking) { + /* This is ok. */ + } else { + if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) + return REDIS_ERR; + } + } + + /* Reset socket to be blocking after connect(2). */ + if (blocking && redisSetBlocking(c,1) != REDIS_OK) + return REDIS_ERR; + + c->flags |= REDIS_CONNECTED; + return REDIS_OK; +} diff --git a/ext/hiredis-0.14.1/net.h b/ext/hiredis-0.14.1/net.h new file mode 100644 index 0000000..d9dc362 --- /dev/null +++ b/ext/hiredis-0.14.1/net.h @@ -0,0 +1,49 @@ +/* Extracted from anet.c to work properly with Hiredis error reporting. + * + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __NET_H +#define __NET_H + +#include "hiredis.h" + +int redisCheckSocketError(redisContext *c); +int redisContextSetTimeout(redisContext *c, const struct timeval tv); +int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); +int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr); +int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); +int redisKeepAlive(redisContext *c, int interval); + +#endif diff --git a/ext/hiredis-0.14.1/read.c b/ext/hiredis-0.14.1/read.c new file mode 100644 index 0000000..cc21267 --- /dev/null +++ b/ext/hiredis-0.14.1/read.c @@ -0,0 +1,598 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "fmacros.h" +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include +#include +#include + +#include "read.h" +#include "sds.h" + +static void __redisReaderSetError(redisReader *r, int type, const char *str) { + size_t len; + + if (r->reply != NULL && r->fn && r->fn->freeObject) { + r->fn->freeObject(r->reply); + r->reply = NULL; + } + + /* Clear input buffer on errors. */ + sdsfree(r->buf); + r->buf = NULL; + r->pos = r->len = 0; + + /* Reset task stack. */ + r->ridx = -1; + + /* Set error. */ + r->err = type; + len = strlen(str); + len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1); + memcpy(r->errstr,str,len); + r->errstr[len] = '\0'; +} + +static size_t chrtos(char *buf, size_t size, char byte) { + size_t len = 0; + + switch(byte) { + case '\\': + case '"': + len = snprintf(buf,size,"\"\\%c\"",byte); + break; + case '\n': len = snprintf(buf,size,"\"\\n\""); break; + case '\r': len = snprintf(buf,size,"\"\\r\""); break; + case '\t': len = snprintf(buf,size,"\"\\t\""); break; + case '\a': len = snprintf(buf,size,"\"\\a\""); break; + case '\b': len = snprintf(buf,size,"\"\\b\""); break; + default: + if (isprint(byte)) + len = snprintf(buf,size,"\"%c\"",byte); + else + len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte); + break; + } + + return len; +} + +static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) { + char cbuf[8], sbuf[128]; + + chrtos(cbuf,sizeof(cbuf),byte); + snprintf(sbuf,sizeof(sbuf), + "Protocol error, got %s as reply type byte", cbuf); + __redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf); +} + +static void __redisReaderSetErrorOOM(redisReader *r) { + __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory"); +} + +static char *readBytes(redisReader *r, unsigned int bytes) { + char *p; + if (r->len-r->pos >= bytes) { + p = r->buf+r->pos; + r->pos += bytes; + return p; + } + return NULL; +} + +/* Find pointer to \r\n. */ +static char *seekNewline(char *s, size_t len) { + int pos = 0; + int _len = len-1; + + /* Position should be < len-1 because the character at "pos" should be + * followed by a \n. Note that strchr cannot be used because it doesn't + * allow to search a limited length and the buffer that is being searched + * might not have a trailing NULL character. */ + while (pos < _len) { + while(pos < _len && s[pos] != '\r') pos++; + if (pos==_len) { + /* Not found. */ + return NULL; + } else { + if (s[pos+1] == '\n') { + /* Found. */ + return s+pos; + } else { + /* Continue searching. */ + pos++; + } + } + } + return NULL; +} + +/* Convert a string into a long long. Returns REDIS_OK if the string could be + * parsed into a (non-overflowing) long long, REDIS_ERR otherwise. The value + * will be set to the parsed value when appropriate. + * + * Note that this function demands that the string strictly represents + * a long long: no spaces or other characters before or after the string + * representing the number are accepted, nor zeroes at the start if not + * for the string "0" representing the zero number. + * + * Because of its strictness, it is safe to use this function to check if + * you can convert a string into a long long, and obtain back the string + * from the number without any loss in the string representation. */ +static int string2ll(const char *s, size_t slen, long long *value) { + const char *p = s; + size_t plen = 0; + int negative = 0; + unsigned long long v; + + if (plen == slen) + return REDIS_ERR; + + /* Special case: first and only digit is 0. */ + if (slen == 1 && p[0] == '0') { + if (value != NULL) *value = 0; + return REDIS_OK; + } + + if (p[0] == '-') { + negative = 1; + p++; plen++; + + /* Abort on only a negative sign. */ + if (plen == slen) + return REDIS_ERR; + } + + /* First digit should be 1-9, otherwise the string should just be 0. */ + if (p[0] >= '1' && p[0] <= '9') { + v = p[0]-'0'; + p++; plen++; + } else if (p[0] == '0' && slen == 1) { + *value = 0; + return REDIS_OK; + } else { + return REDIS_ERR; + } + + while (plen < slen && p[0] >= '0' && p[0] <= '9') { + if (v > (ULLONG_MAX / 10)) /* Overflow. */ + return REDIS_ERR; + v *= 10; + + if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */ + return REDIS_ERR; + v += p[0]-'0'; + + p++; plen++; + } + + /* Return if not all bytes were used. */ + if (plen < slen) + return REDIS_ERR; + + if (negative) { + if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */ + return REDIS_ERR; + if (value != NULL) *value = -v; + } else { + if (v > LLONG_MAX) /* Overflow. */ + return REDIS_ERR; + if (value != NULL) *value = v; + } + return REDIS_OK; +} + +static char *readLine(redisReader *r, int *_len) { + char *p, *s; + int len; + + p = r->buf+r->pos; + s = seekNewline(p,(r->len-r->pos)); + if (s != NULL) { + len = s-(r->buf+r->pos); + r->pos += len+2; /* skip \r\n */ + if (_len) *_len = len; + return p; + } + return NULL; +} + +static void moveToNextTask(redisReader *r) { + redisReadTask *cur, *prv; + while (r->ridx >= 0) { + /* Return a.s.a.p. when the stack is now empty. */ + if (r->ridx == 0) { + r->ridx--; + return; + } + + cur = &(r->rstack[r->ridx]); + prv = &(r->rstack[r->ridx-1]); + assert(prv->type == REDIS_REPLY_ARRAY); + if (cur->idx == prv->elements-1) { + r->ridx--; + } else { + /* Reset the type because the next item can be anything */ + assert(cur->idx < prv->elements); + cur->type = -1; + cur->elements = -1; + cur->idx++; + return; + } + } +} + +static int processLineItem(redisReader *r) { + redisReadTask *cur = &(r->rstack[r->ridx]); + void *obj; + char *p; + int len; + + if ((p = readLine(r,&len)) != NULL) { + if (cur->type == REDIS_REPLY_INTEGER) { + if (r->fn && r->fn->createInteger) { + long long v; + if (string2ll(p, len, &v) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad integer value"); + return REDIS_ERR; + } + obj = r->fn->createInteger(cur,v); + } else { + obj = (void*)REDIS_REPLY_INTEGER; + } + } else { + /* Type will be error or status. */ + if (r->fn && r->fn->createString) + obj = r->fn->createString(cur,p,len); + else + obj = (void*)(size_t)(cur->type); + } + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + /* Set reply if this is the root object. */ + if (r->ridx == 0) r->reply = obj; + moveToNextTask(r); + return REDIS_OK; + } + + return REDIS_ERR; +} + +static int processBulkItem(redisReader *r) { + redisReadTask *cur = &(r->rstack[r->ridx]); + void *obj = NULL; + char *p, *s; + long long len; + unsigned long bytelen; + int success = 0; + + p = r->buf+r->pos; + s = seekNewline(p,r->len-r->pos); + if (s != NULL) { + p = r->buf+r->pos; + bytelen = s-(r->buf+r->pos)+2; /* include \r\n */ + + if (string2ll(p, bytelen - 2, &len) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad bulk string length"); + return REDIS_ERR; + } + + if (len < -1 || (LLONG_MAX > SIZE_MAX && len > (long long)SIZE_MAX)) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bulk string length out of range"); + return REDIS_ERR; + } + + if (len == -1) { + /* The nil object can always be created. */ + if (r->fn && r->fn->createNil) + obj = r->fn->createNil(cur); + else + obj = (void*)REDIS_REPLY_NIL; + success = 1; + } else { + /* Only continue when the buffer contains the entire bulk item. */ + bytelen += len+2; /* include \r\n */ + if (r->pos+bytelen <= r->len) { + if (r->fn && r->fn->createString) + obj = r->fn->createString(cur,s+2,len); + else + obj = (void*)REDIS_REPLY_STRING; + success = 1; + } + } + + /* Proceed when obj was created. */ + if (success) { + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + r->pos += bytelen; + + /* Set reply if this is the root object. */ + if (r->ridx == 0) r->reply = obj; + moveToNextTask(r); + return REDIS_OK; + } + } + + return REDIS_ERR; +} + +static int processMultiBulkItem(redisReader *r) { + redisReadTask *cur = &(r->rstack[r->ridx]); + void *obj; + char *p; + long long elements; + int root = 0, len; + + /* Set error for nested multi bulks with depth > 7 */ + if (r->ridx == 8) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "No support for nested multi bulk replies with depth > 7"); + return REDIS_ERR; + } + + if ((p = readLine(r,&len)) != NULL) { + if (string2ll(p, len, &elements) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad multi-bulk length"); + return REDIS_ERR; + } + + root = (r->ridx == 0); + + if (elements < -1 || elements > INT_MAX) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Multi-bulk length out of range"); + return REDIS_ERR; + } + + if (elements == -1) { + if (r->fn && r->fn->createNil) + obj = r->fn->createNil(cur); + else + obj = (void*)REDIS_REPLY_NIL; + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + moveToNextTask(r); + } else { + if (r->fn && r->fn->createArray) + obj = r->fn->createArray(cur,elements); + else + obj = (void*)REDIS_REPLY_ARRAY; + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + /* Modify task stack when there are more than 0 elements. */ + if (elements > 0) { + cur->elements = elements; + cur->obj = obj; + r->ridx++; + r->rstack[r->ridx].type = -1; + r->rstack[r->ridx].elements = -1; + r->rstack[r->ridx].idx = 0; + r->rstack[r->ridx].obj = NULL; + r->rstack[r->ridx].parent = cur; + r->rstack[r->ridx].privdata = r->privdata; + } else { + moveToNextTask(r); + } + } + + /* Set reply if this is the root object. */ + if (root) r->reply = obj; + return REDIS_OK; + } + + return REDIS_ERR; +} + +static int processItem(redisReader *r) { + redisReadTask *cur = &(r->rstack[r->ridx]); + char *p; + + /* check if we need to read type */ + if (cur->type < 0) { + if ((p = readBytes(r,1)) != NULL) { + switch (p[0]) { + case '-': + cur->type = REDIS_REPLY_ERROR; + break; + case '+': + cur->type = REDIS_REPLY_STATUS; + break; + case ':': + cur->type = REDIS_REPLY_INTEGER; + break; + case '$': + cur->type = REDIS_REPLY_STRING; + break; + case '*': + cur->type = REDIS_REPLY_ARRAY; + break; + default: + __redisReaderSetErrorProtocolByte(r,*p); + return REDIS_ERR; + } + } else { + /* could not consume 1 byte */ + return REDIS_ERR; + } + } + + /* process typed item */ + switch(cur->type) { + case REDIS_REPLY_ERROR: + case REDIS_REPLY_STATUS: + case REDIS_REPLY_INTEGER: + return processLineItem(r); + case REDIS_REPLY_STRING: + return processBulkItem(r); + case REDIS_REPLY_ARRAY: + return processMultiBulkItem(r); + default: + assert(NULL); + return REDIS_ERR; /* Avoid warning. */ + } +} + +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) { + redisReader *r; + + r = calloc(1,sizeof(redisReader)); + if (r == NULL) + return NULL; + + r->fn = fn; + r->buf = sdsempty(); + r->maxbuf = REDIS_READER_MAX_BUF; + if (r->buf == NULL) { + free(r); + return NULL; + } + + r->ridx = -1; + return r; +} + +void redisReaderFree(redisReader *r) { + if (r == NULL) + return; + if (r->reply != NULL && r->fn && r->fn->freeObject) + r->fn->freeObject(r->reply); + sdsfree(r->buf); + free(r); +} + +int redisReaderFeed(redisReader *r, const char *buf, size_t len) { + sds newbuf; + + /* Return early when this reader is in an erroneous state. */ + if (r->err) + return REDIS_ERR; + + /* Copy the provided buffer. */ + if (buf != NULL && len >= 1) { + /* Destroy internal buffer when it is empty and is quite large. */ + if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) { + sdsfree(r->buf); + r->buf = sdsempty(); + r->pos = 0; + + /* r->buf should not be NULL since we just free'd a larger one. */ + assert(r->buf != NULL); + } + + newbuf = sdscatlen(r->buf,buf,len); + if (newbuf == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + r->buf = newbuf; + r->len = sdslen(r->buf); + } + + return REDIS_OK; +} + +int redisReaderGetReply(redisReader *r, void **reply) { + /* Default target pointer to NULL. */ + if (reply != NULL) + *reply = NULL; + + /* Return early when this reader is in an erroneous state. */ + if (r->err) + return REDIS_ERR; + + /* When the buffer is empty, there will never be a reply. */ + if (r->len == 0) + return REDIS_OK; + + /* Set first item to process when the stack is empty. */ + if (r->ridx == -1) { + r->rstack[0].type = -1; + r->rstack[0].elements = -1; + r->rstack[0].idx = -1; + r->rstack[0].obj = NULL; + r->rstack[0].parent = NULL; + r->rstack[0].privdata = r->privdata; + r->ridx = 0; + } + + /* Process items in reply. */ + while (r->ridx >= 0) + if (processItem(r) != REDIS_OK) + break; + + /* Return ASAP when an error occurred. */ + if (r->err) + return REDIS_ERR; + + /* Discard part of the buffer when we've consumed at least 1k, to avoid + * doing unnecessary calls to memmove() in sds.c. */ + if (r->pos >= 1024) { + sdsrange(r->buf,r->pos,-1); + r->pos = 0; + r->len = sdslen(r->buf); + } + + /* Emit a reply when there is one. */ + if (r->ridx == -1) { + if (reply != NULL) + *reply = r->reply; + r->reply = NULL; + } + return REDIS_OK; +} diff --git a/ext/hiredis-0.14.1/read.h b/ext/hiredis-0.14.1/read.h new file mode 100644 index 0000000..2988aa4 --- /dev/null +++ b/ext/hiredis-0.14.1/read.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __HIREDIS_READ_H +#define __HIREDIS_READ_H +#include /* for size_t */ + +#define REDIS_ERR -1 +#define REDIS_OK 0 + +/* When an error occurs, the err flag in a context is set to hold the type of + * error that occurred. REDIS_ERR_IO means there was an I/O error and you + * should use the "errno" variable to find out what is wrong. + * For other values, the "errstr" field will hold a description. */ +#define REDIS_ERR_IO 1 /* Error in read or write */ +#define REDIS_ERR_EOF 3 /* End of file */ +#define REDIS_ERR_PROTOCOL 4 /* Protocol error */ +#define REDIS_ERR_OOM 5 /* Out of memory */ +#define REDIS_ERR_OTHER 2 /* Everything else... */ + +#define REDIS_REPLY_STRING 1 +#define REDIS_REPLY_ARRAY 2 +#define REDIS_REPLY_INTEGER 3 +#define REDIS_REPLY_NIL 4 +#define REDIS_REPLY_STATUS 5 +#define REDIS_REPLY_ERROR 6 + +#define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct redisReadTask { + int type; + int elements; /* number of elements in multibulk container */ + int idx; /* index in parent (array) object */ + void *obj; /* holds user-generated value for a read task */ + struct redisReadTask *parent; /* parent task */ + void *privdata; /* user-settable arbitrary field */ +} redisReadTask; + +typedef struct redisReplyObjectFunctions { + void *(*createString)(const redisReadTask*, char*, size_t); + void *(*createArray)(const redisReadTask*, int); + void *(*createInteger)(const redisReadTask*, long long); + void *(*createNil)(const redisReadTask*); + void (*freeObject)(void*); +} redisReplyObjectFunctions; + +typedef struct redisReader { + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + + char *buf; /* Read buffer */ + size_t pos; /* Buffer cursor */ + size_t len; /* Buffer length */ + size_t maxbuf; /* Max length of unused buffer */ + + redisReadTask rstack[9]; + int ridx; /* Index of current read task */ + void *reply; /* Temporary reply pointer */ + + redisReplyObjectFunctions *fn; + void *privdata; +} redisReader; + +/* Public API for the protocol parser. */ +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); +void redisReaderFree(redisReader *r); +int redisReaderFeed(redisReader *r, const char *buf, size_t len); +int redisReaderGetReply(redisReader *r, void **reply); + +#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) +#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) +#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-0.14.1/sds.c b/ext/hiredis-0.14.1/sds.c new file mode 100644 index 0000000..923ffd8 --- /dev/null +++ b/ext/hiredis-0.14.1/sds.c @@ -0,0 +1,1272 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include "sds.h" +#include "sdsalloc.h" + +static inline int sdsHdrSize(char type) { + switch(type&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return sizeof(struct sdshdr5); + case SDS_TYPE_8: + return sizeof(struct sdshdr8); + case SDS_TYPE_16: + return sizeof(struct sdshdr16); + case SDS_TYPE_32: + return sizeof(struct sdshdr32); + case SDS_TYPE_64: + return sizeof(struct sdshdr64); + } + return 0; +} + +static inline char sdsReqType(size_t string_size) { + if (string_size < 32) + return SDS_TYPE_5; + if (string_size < 0xff) + return SDS_TYPE_8; + if (string_size < 0xffff) + return SDS_TYPE_16; + if (string_size < 0xffffffff) + return SDS_TYPE_32; + return SDS_TYPE_64; +} + +/* Create a new sds string with the content specified by the 'init' pointer + * and 'initlen'. + * If NULL is used for 'init' the string is initialized with zero bytes. + * + * The string is always null-termined (all the sds strings are, always) so + * even if you create an sds string with: + * + * mystring = sdsnewlen("abc",3); + * + * You can print the string with printf() as there is an implicit \0 at the + * end of the string. However the string is binary safe and can contain + * \0 characters in the middle, as the length is stored in the sds header. */ +sds sdsnewlen(const void *init, size_t initlen) { + void *sh; + sds s; + char type = sdsReqType(initlen); + /* Empty strings are usually created in order to append. Use type 8 + * since type 5 is not good at this. */ + if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8; + int hdrlen = sdsHdrSize(type); + unsigned char *fp; /* flags pointer. */ + + sh = s_malloc(hdrlen+initlen+1); + if (sh == NULL) return NULL; + if (!init) + memset(sh, 0, hdrlen+initlen+1); + s = (char*)sh+hdrlen; + fp = ((unsigned char*)s)-1; + switch(type) { + case SDS_TYPE_5: { + *fp = type | (initlen << SDS_TYPE_BITS); + break; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + } + if (initlen && init) + memcpy(s, init, initlen); + s[initlen] = '\0'; + return s; +} + +/* Create an empty (zero length) sds string. Even in this case the string + * always has an implicit null term. */ +sds sdsempty(void) { + return sdsnewlen("",0); +} + +/* Create a new sds string starting from a null terminated C string. */ +sds sdsnew(const char *init) { + size_t initlen = (init == NULL) ? 0 : strlen(init); + return sdsnewlen(init, initlen); +} + +/* Duplicate an sds string. */ +sds sdsdup(const sds s) { + return sdsnewlen(s, sdslen(s)); +} + +/* Free an sds string. No operation is performed if 's' is NULL. */ +void sdsfree(sds s) { + if (s == NULL) return; + s_free((char*)s-sdsHdrSize(s[-1])); +} + +/* Set the sds string length to the length as obtained with strlen(), so + * considering as content only up to the first null term character. + * + * This function is useful when the sds string is hacked manually in some + * way, like in the following example: + * + * s = sdsnew("foobar"); + * s[2] = '\0'; + * sdsupdatelen(s); + * printf("%d\n", sdslen(s)); + * + * The output will be "2", but if we comment out the call to sdsupdatelen() + * the output will be "6" as the string was modified but the logical length + * remains 6 bytes. */ +void sdsupdatelen(sds s) { + int reallen = strlen(s); + sdssetlen(s, reallen); +} + +/* Modify an sds string in-place to make it empty (zero length). + * However all the existing buffer is not discarded but set as free space + * so that next append operations will not require allocations up to the + * number of bytes previously available. */ +void sdsclear(sds s) { + sdssetlen(s, 0); + s[0] = '\0'; +} + +/* Enlarge the free space at the end of the sds string so that the caller + * is sure that after calling this function can overwrite up to addlen + * bytes after the end of the string, plus one more byte for nul term. + * + * Note: this does not change the *length* of the sds string as returned + * by sdslen(), but only the free buffer space we have. */ +sds sdsMakeRoomFor(sds s, size_t addlen) { + void *sh, *newsh; + size_t avail = sdsavail(s); + size_t len, newlen; + char type, oldtype = s[-1] & SDS_TYPE_MASK; + int hdrlen; + + /* Return ASAP if there is enough space left. */ + if (avail >= addlen) return s; + + len = sdslen(s); + sh = (char*)s-sdsHdrSize(oldtype); + newlen = (len+addlen); + if (newlen < SDS_MAX_PREALLOC) + newlen *= 2; + else + newlen += SDS_MAX_PREALLOC; + + type = sdsReqType(newlen); + + /* Don't use type 5: the user is appending to the string and type 5 is + * not able to remember empty space, so sdsMakeRoomFor() must be called + * at every appending operation. */ + if (type == SDS_TYPE_5) type = SDS_TYPE_8; + + hdrlen = sdsHdrSize(type); + if (oldtype==type) { + newsh = s_realloc(sh, hdrlen+newlen+1); + if (newsh == NULL) return NULL; + s = (char*)newsh+hdrlen; + } else { + /* Since the header size changes, need to move the string forward, + * and can't use realloc */ + newsh = s_malloc(hdrlen+newlen+1); + if (newsh == NULL) return NULL; + memcpy((char*)newsh+hdrlen, s, len+1); + s_free(sh); + s = (char*)newsh+hdrlen; + s[-1] = type; + sdssetlen(s, len); + } + sdssetalloc(s, newlen); + return s; +} + +/* Reallocate the sds string so that it has no free space at the end. The + * contained string remains not altered, but next concatenation operations + * will require a reallocation. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdsRemoveFreeSpace(sds s) { + void *sh, *newsh; + char type, oldtype = s[-1] & SDS_TYPE_MASK; + int hdrlen; + size_t len = sdslen(s); + sh = (char*)s-sdsHdrSize(oldtype); + + type = sdsReqType(len); + hdrlen = sdsHdrSize(type); + if (oldtype==type) { + newsh = s_realloc(sh, hdrlen+len+1); + if (newsh == NULL) return NULL; + s = (char*)newsh+hdrlen; + } else { + newsh = s_malloc(hdrlen+len+1); + if (newsh == NULL) return NULL; + memcpy((char*)newsh+hdrlen, s, len+1); + s_free(sh); + s = (char*)newsh+hdrlen; + s[-1] = type; + sdssetlen(s, len); + } + sdssetalloc(s, len); + return s; +} + +/* Return the total size of the allocation of the specifed sds string, + * including: + * 1) The sds header before the pointer. + * 2) The string. + * 3) The free buffer at the end if any. + * 4) The implicit null term. + */ +size_t sdsAllocSize(sds s) { + size_t alloc = sdsalloc(s); + return sdsHdrSize(s[-1])+alloc+1; +} + +/* Return the pointer of the actual SDS allocation (normally SDS strings + * are referenced by the start of the string buffer). */ +void *sdsAllocPtr(sds s) { + return (void*) (s-sdsHdrSize(s[-1])); +} + +/* Increment the sds length and decrements the left free space at the + * end of the string according to 'incr'. Also set the null term + * in the new end of the string. + * + * This function is used in order to fix the string length after the + * user calls sdsMakeRoomFor(), writes something after the end of + * the current string, and finally needs to set the new length. + * + * Note: it is possible to use a negative increment in order to + * right-trim the string. + * + * Usage example: + * + * Using sdsIncrLen() and sdsMakeRoomFor() it is possible to mount the + * following schema, to cat bytes coming from the kernel to the end of an + * sds string without copying into an intermediate buffer: + * + * oldlen = sdslen(s); + * s = sdsMakeRoomFor(s, BUFFER_SIZE); + * nread = read(fd, s+oldlen, BUFFER_SIZE); + * ... check for nread <= 0 and handle it ... + * sdsIncrLen(s, nread); + */ +void sdsIncrLen(sds s, int incr) { + unsigned char flags = s[-1]; + size_t len; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char oldlen = SDS_TYPE_5_LEN(flags); + assert((incr > 0 && oldlen+incr < 32) || (incr < 0 && oldlen >= (unsigned int)(-incr))); + *fp = SDS_TYPE_5 | ((oldlen+incr) << SDS_TYPE_BITS); + len = oldlen+incr; + break; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + assert((incr >= 0 && sh->alloc-sh->len >= (unsigned int)incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + assert((incr >= 0 && sh->alloc-sh->len >= (uint64_t)incr) || (incr < 0 && sh->len >= (uint64_t)(-incr))); + len = (sh->len += incr); + break; + } + default: len = 0; /* Just to avoid compilation warnings. */ + } + s[len] = '\0'; +} + +/* Grow the sds to have the specified length. Bytes that were not part of + * the original length of the sds will be set to zero. + * + * if the specified length is smaller than the current length, no operation + * is performed. */ +sds sdsgrowzero(sds s, size_t len) { + size_t curlen = sdslen(s); + + if (len <= curlen) return s; + s = sdsMakeRoomFor(s,len-curlen); + if (s == NULL) return NULL; + + /* Make sure added region doesn't contain garbage */ + memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */ + sdssetlen(s, len); + return s; +} + +/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the + * end of the specified sds string 's'. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatlen(sds s, const void *t, size_t len) { + size_t curlen = sdslen(s); + + s = sdsMakeRoomFor(s,len); + if (s == NULL) return NULL; + memcpy(s+curlen, t, len); + sdssetlen(s, curlen+len); + s[curlen+len] = '\0'; + return s; +} + +/* Append the specified null termianted C string to the sds string 's'. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscat(sds s, const char *t) { + return sdscatlen(s, t, strlen(t)); +} + +/* Append the specified sds 't' to the existing sds 's'. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatsds(sds s, const sds t) { + return sdscatlen(s, t, sdslen(t)); +} + +/* Destructively modify the sds string 's' to hold the specified binary + * safe string pointed by 't' of length 'len' bytes. */ +sds sdscpylen(sds s, const char *t, size_t len) { + if (sdsalloc(s) < len) { + s = sdsMakeRoomFor(s,len-sdslen(s)); + if (s == NULL) return NULL; + } + memcpy(s, t, len); + s[len] = '\0'; + sdssetlen(s, len); + return s; +} + +/* Like sdscpylen() but 't' must be a null-termined string so that the length + * of the string is obtained with strlen(). */ +sds sdscpy(sds s, const char *t) { + return sdscpylen(s, t, strlen(t)); +} + +/* Helper for sdscatlonglong() doing the actual number -> string + * conversion. 's' must point to a string with room for at least + * SDS_LLSTR_SIZE bytes. + * + * The function returns the length of the null-terminated string + * representation stored at 's'. */ +#define SDS_LLSTR_SIZE 21 +int sdsll2str(char *s, long long value) { + char *p, aux; + unsigned long long v; + size_t l; + + /* Generate the string representation, this method produces + * an reversed string. */ + v = (value < 0) ? -value : value; + p = s; + do { + *p++ = '0'+(v%10); + v /= 10; + } while(v); + if (value < 0) *p++ = '-'; + + /* Compute length and add null term. */ + l = p-s; + *p = '\0'; + + /* Reverse the string. */ + p--; + while(s < p) { + aux = *s; + *s = *p; + *p = aux; + s++; + p--; + } + return l; +} + +/* Identical sdsll2str(), but for unsigned long long type. */ +int sdsull2str(char *s, unsigned long long v) { + char *p, aux; + size_t l; + + /* Generate the string representation, this method produces + * an reversed string. */ + p = s; + do { + *p++ = '0'+(v%10); + v /= 10; + } while(v); + + /* Compute length and add null term. */ + l = p-s; + *p = '\0'; + + /* Reverse the string. */ + p--; + while(s < p) { + aux = *s; + *s = *p; + *p = aux; + s++; + p--; + } + return l; +} + +/* Create an sds string from a long long value. It is much faster than: + * + * sdscatprintf(sdsempty(),"%lld\n", value); + */ +sds sdsfromlonglong(long long value) { + char buf[SDS_LLSTR_SIZE]; + int len = sdsll2str(buf,value); + + return sdsnewlen(buf,len); +} + +/* Like sdscatprintf() but gets va_list instead of being variadic. */ +sds sdscatvprintf(sds s, const char *fmt, va_list ap) { + va_list cpy; + char staticbuf[1024], *buf = staticbuf, *t; + size_t buflen = strlen(fmt)*2; + + /* We try to start using a static buffer for speed. + * If not possible we revert to heap allocation. */ + if (buflen > sizeof(staticbuf)) { + buf = s_malloc(buflen); + if (buf == NULL) return NULL; + } else { + buflen = sizeof(staticbuf); + } + + /* Try with buffers two times bigger every time we fail to + * fit the string in the current buffer size. */ + while(1) { + buf[buflen-2] = '\0'; + va_copy(cpy,ap); + vsnprintf(buf, buflen, fmt, cpy); + va_end(cpy); + if (buf[buflen-2] != '\0') { + if (buf != staticbuf) s_free(buf); + buflen *= 2; + buf = s_malloc(buflen); + if (buf == NULL) return NULL; + continue; + } + break; + } + + /* Finally concat the obtained string to the SDS string and return it. */ + t = sdscat(s, buf); + if (buf != staticbuf) s_free(buf); + return t; +} + +/* Append to the sds string 's' a string obtained using printf-alike format + * specifier. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. + * + * Example: + * + * s = sdsnew("Sum is: "); + * s = sdscatprintf(s,"%d+%d = %d",a,b,a+b). + * + * Often you need to create a string from scratch with the printf-alike + * format. When this is the need, just use sdsempty() as the target string: + * + * s = sdscatprintf(sdsempty(), "... your format ...", args); + */ +sds sdscatprintf(sds s, const char *fmt, ...) { + va_list ap; + char *t; + va_start(ap, fmt); + t = sdscatvprintf(s,fmt,ap); + va_end(ap); + return t; +} + +/* This function is similar to sdscatprintf, but much faster as it does + * not rely on sprintf() family functions implemented by the libc that + * are often very slow. Moreover directly handling the sds string as + * new data is concatenated provides a performance improvement. + * + * However this function only handles an incompatible subset of printf-alike + * format specifiers: + * + * %s - C String + * %S - SDS string + * %i - signed int + * %I - 64 bit signed integer (long long, int64_t) + * %u - unsigned int + * %U - 64 bit unsigned integer (unsigned long long, uint64_t) + * %% - Verbatim "%" character. + */ +sds sdscatfmt(sds s, char const *fmt, ...) { + const char *f = fmt; + int i; + va_list ap; + + va_start(ap,fmt); + i = sdslen(s); /* Position of the next byte to write to dest str. */ + while(*f) { + char next, *str; + size_t l; + long long num; + unsigned long long unum; + + /* Make sure there is always space for at least 1 char. */ + if (sdsavail(s)==0) { + s = sdsMakeRoomFor(s,1); + } + + switch(*f) { + case '%': + next = *(f+1); + f++; + switch(next) { + case 's': + case 'S': + str = va_arg(ap,char*); + l = (next == 's') ? strlen(str) : sdslen(str); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + } + memcpy(s+i,str,l); + sdsinclen(s,l); + i += l; + break; + case 'i': + case 'I': + if (next == 'i') + num = va_arg(ap,int); + else + num = va_arg(ap,long long); + { + char buf[SDS_LLSTR_SIZE]; + l = sdsll2str(buf,num); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + } + memcpy(s+i,buf,l); + sdsinclen(s,l); + i += l; + } + break; + case 'u': + case 'U': + if (next == 'u') + unum = va_arg(ap,unsigned int); + else + unum = va_arg(ap,unsigned long long); + { + char buf[SDS_LLSTR_SIZE]; + l = sdsull2str(buf,unum); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + } + memcpy(s+i,buf,l); + sdsinclen(s,l); + i += l; + } + break; + default: /* Handle %% and generally %. */ + s[i++] = next; + sdsinclen(s,1); + break; + } + break; + default: + s[i++] = *f; + sdsinclen(s,1); + break; + } + f++; + } + va_end(ap); + + /* Add null-term */ + s[i] = '\0'; + return s; +} + +/* Remove the part of the string from left and from right composed just of + * contiguous characters found in 'cset', that is a null terminted C string. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. + * + * Example: + * + * s = sdsnew("AA...AA.a.aa.aHelloWorld :::"); + * s = sdstrim(s,"Aa. :"); + * printf("%s\n", s); + * + * Output will be just "Hello World". + */ +sds sdstrim(sds s, const char *cset) { + char *start, *end, *sp, *ep; + size_t len; + + sp = start = s; + ep = end = s+sdslen(s)-1; + while(sp <= end && strchr(cset, *sp)) sp++; + while(ep > sp && strchr(cset, *ep)) ep--; + len = (sp > ep) ? 0 : ((ep-sp)+1); + if (s != sp) memmove(s, sp, len); + s[len] = '\0'; + sdssetlen(s,len); + return s; +} + +/* Turn the string into a smaller (or equal) string containing only the + * substring specified by the 'start' and 'end' indexes. + * + * start and end can be negative, where -1 means the last character of the + * string, -2 the penultimate character, and so forth. + * + * The interval is inclusive, so the start and end characters will be part + * of the resulting string. + * + * The string is modified in-place. + * + * Example: + * + * s = sdsnew("Hello World"); + * sdsrange(s,1,-1); => "ello World" + */ +void sdsrange(sds s, int start, int end) { + size_t newlen, len = sdslen(s); + + if (len == 0) return; + if (start < 0) { + start = len+start; + if (start < 0) start = 0; + } + if (end < 0) { + end = len+end; + if (end < 0) end = 0; + } + newlen = (start > end) ? 0 : (end-start)+1; + if (newlen != 0) { + if (start >= (signed)len) { + newlen = 0; + } else if (end >= (signed)len) { + end = len-1; + newlen = (start > end) ? 0 : (end-start)+1; + } + } else { + start = 0; + } + if (start && newlen) memmove(s, s+start, newlen); + s[newlen] = 0; + sdssetlen(s,newlen); +} + +/* Apply tolower() to every character of the sds string 's'. */ +void sdstolower(sds s) { + int len = sdslen(s), j; + + for (j = 0; j < len; j++) s[j] = tolower(s[j]); +} + +/* Apply toupper() to every character of the sds string 's'. */ +void sdstoupper(sds s) { + int len = sdslen(s), j; + + for (j = 0; j < len; j++) s[j] = toupper(s[j]); +} + +/* Compare two sds strings s1 and s2 with memcmp(). + * + * Return value: + * + * positive if s1 > s2. + * negative if s1 < s2. + * 0 if s1 and s2 are exactly the same binary string. + * + * If two strings share exactly the same prefix, but one of the two has + * additional characters, the longer string is considered to be greater than + * the smaller one. */ +int sdscmp(const sds s1, const sds s2) { + size_t l1, l2, minlen; + int cmp; + + l1 = sdslen(s1); + l2 = sdslen(s2); + minlen = (l1 < l2) ? l1 : l2; + cmp = memcmp(s1,s2,minlen); + if (cmp == 0) return l1-l2; + return cmp; +} + +/* Split 's' with separator in 'sep'. An array + * of sds strings is returned. *count will be set + * by reference to the number of tokens returned. + * + * On out of memory, zero length string, zero length + * separator, NULL is returned. + * + * Note that 'sep' is able to split a string using + * a multi-character separator. For example + * sdssplit("foo_-_bar","_-_"); will return two + * elements "foo" and "bar". + * + * This version of the function is binary-safe but + * requires length arguments. sdssplit() is just the + * same function but for zero-terminated strings. + */ +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count) { + int elements = 0, slots = 5, start = 0, j; + sds *tokens; + + if (seplen < 1 || len < 0) return NULL; + + tokens = s_malloc(sizeof(sds)*slots); + if (tokens == NULL) return NULL; + + if (len == 0) { + *count = 0; + return tokens; + } + for (j = 0; j < (len-(seplen-1)); j++) { + /* make sure there is room for the next element and the final one */ + if (slots < elements+2) { + sds *newtokens; + + slots *= 2; + newtokens = s_realloc(tokens,sizeof(sds)*slots); + if (newtokens == NULL) goto cleanup; + tokens = newtokens; + } + /* search the separator */ + if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) { + tokens[elements] = sdsnewlen(s+start,j-start); + if (tokens[elements] == NULL) goto cleanup; + elements++; + start = j+seplen; + j = j+seplen-1; /* skip the separator */ + } + } + /* Add the final element. We are sure there is room in the tokens array. */ + tokens[elements] = sdsnewlen(s+start,len-start); + if (tokens[elements] == NULL) goto cleanup; + elements++; + *count = elements; + return tokens; + +cleanup: + { + int i; + for (i = 0; i < elements; i++) sdsfree(tokens[i]); + s_free(tokens); + *count = 0; + return NULL; + } +} + +/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */ +void sdsfreesplitres(sds *tokens, int count) { + if (!tokens) return; + while(count--) + sdsfree(tokens[count]); + s_free(tokens); +} + +/* Append to the sds string "s" an escaped string representation where + * all the non-printable characters (tested with isprint()) are turned into + * escapes in the form "\n\r\a...." or "\x". + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatrepr(sds s, const char *p, size_t len) { + s = sdscatlen(s,"\"",1); + while(len--) { + switch(*p) { + case '\\': + case '"': + s = sdscatprintf(s,"\\%c",*p); + break; + case '\n': s = sdscatlen(s,"\\n",2); break; + case '\r': s = sdscatlen(s,"\\r",2); break; + case '\t': s = sdscatlen(s,"\\t",2); break; + case '\a': s = sdscatlen(s,"\\a",2); break; + case '\b': s = sdscatlen(s,"\\b",2); break; + default: + if (isprint(*p)) + s = sdscatprintf(s,"%c",*p); + else + s = sdscatprintf(s,"\\x%02x",(unsigned char)*p); + break; + } + p++; + } + return sdscatlen(s,"\"",1); +} + +/* Helper function for sdssplitargs() that returns non zero if 'c' + * is a valid hex digit. */ +int is_hex_digit(char c) { + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F'); +} + +/* Helper function for sdssplitargs() that converts a hex digit into an + * integer from 0 to 15 */ +int hex_digit_to_int(char c) { + switch(c) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'a': case 'A': return 10; + case 'b': case 'B': return 11; + case 'c': case 'C': return 12; + case 'd': case 'D': return 13; + case 'e': case 'E': return 14; + case 'f': case 'F': return 15; + default: return 0; + } +} + +/* Split a line into arguments, where every argument can be in the + * following programming-language REPL-alike form: + * + * foo bar "newline are supported\n" and "\xff\x00otherstuff" + * + * The number of arguments is stored into *argc, and an array + * of sds is returned. + * + * The caller should free the resulting array of sds strings with + * sdsfreesplitres(). + * + * Note that sdscatrepr() is able to convert back a string into + * a quoted string in the same format sdssplitargs() is able to parse. + * + * The function returns the allocated tokens on success, even when the + * input string is empty, or NULL if the input contains unbalanced + * quotes or closed quotes followed by non space characters + * as in: "foo"bar or "foo' + */ +sds *sdssplitargs(const char *line, int *argc) { + const char *p = line; + char *current = NULL; + char **vector = NULL; + + *argc = 0; + while(1) { + /* skip blanks */ + while(*p && isspace(*p)) p++; + if (*p) { + /* get a token */ + int inq=0; /* set to 1 if we are in "quotes" */ + int insq=0; /* set to 1 if we are in 'single quotes' */ + int done=0; + + if (current == NULL) current = sdsempty(); + while(!done) { + if (inq) { + if (*p == '\\' && *(p+1) == 'x' && + is_hex_digit(*(p+2)) && + is_hex_digit(*(p+3))) + { + unsigned char byte; + + byte = (hex_digit_to_int(*(p+2))*16)+ + hex_digit_to_int(*(p+3)); + current = sdscatlen(current,(char*)&byte,1); + p += 3; + } else if (*p == '\\' && *(p+1)) { + char c; + + p++; + switch(*p) { + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'b': c = '\b'; break; + case 'a': c = '\a'; break; + default: c = *p; break; + } + current = sdscatlen(current,&c,1); + } else if (*p == '"') { + /* closing quote must be followed by a space or + * nothing at all. */ + if (*(p+1) && !isspace(*(p+1))) goto err; + done=1; + } else if (!*p) { + /* unterminated quotes */ + goto err; + } else { + current = sdscatlen(current,p,1); + } + } else if (insq) { + if (*p == '\\' && *(p+1) == '\'') { + p++; + current = sdscatlen(current,"'",1); + } else if (*p == '\'') { + /* closing quote must be followed by a space or + * nothing at all. */ + if (*(p+1) && !isspace(*(p+1))) goto err; + done=1; + } else if (!*p) { + /* unterminated quotes */ + goto err; + } else { + current = sdscatlen(current,p,1); + } + } else { + switch(*p) { + case ' ': + case '\n': + case '\r': + case '\t': + case '\0': + done=1; + break; + case '"': + inq=1; + break; + case '\'': + insq=1; + break; + default: + current = sdscatlen(current,p,1); + break; + } + } + if (*p) p++; + } + /* add the token to the vector */ + vector = s_realloc(vector,((*argc)+1)*sizeof(char*)); + vector[*argc] = current; + (*argc)++; + current = NULL; + } else { + /* Even on empty input string return something not NULL. */ + if (vector == NULL) vector = s_malloc(sizeof(void*)); + return vector; + } + } + +err: + while((*argc)--) + sdsfree(vector[*argc]); + s_free(vector); + if (current) sdsfree(current); + *argc = 0; + return NULL; +} + +/* Modify the string substituting all the occurrences of the set of + * characters specified in the 'from' string to the corresponding character + * in the 'to' array. + * + * For instance: sdsmapchars(mystring, "ho", "01", 2) + * will have the effect of turning the string "hello" into "0ell1". + * + * The function returns the sds string pointer, that is always the same + * as the input pointer since no resize is needed. */ +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) { + size_t j, i, l = sdslen(s); + + for (j = 0; j < l; j++) { + for (i = 0; i < setlen; i++) { + if (s[j] == from[i]) { + s[j] = to[i]; + break; + } + } + } + return s; +} + +/* Join an array of C strings using the specified separator (also a C string). + * Returns the result as an sds string. */ +sds sdsjoin(char **argv, int argc, char *sep) { + sds join = sdsempty(); + int j; + + for (j = 0; j < argc; j++) { + join = sdscat(join, argv[j]); + if (j != argc-1) join = sdscat(join,sep); + } + return join; +} + +/* Like sdsjoin, but joins an array of SDS strings. */ +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) { + sds join = sdsempty(); + int j; + + for (j = 0; j < argc; j++) { + join = sdscatsds(join, argv[j]); + if (j != argc-1) join = sdscatlen(join,sep,seplen); + } + return join; +} + +/* Wrappers to the allocators used by SDS. Note that SDS will actually + * just use the macros defined into sdsalloc.h in order to avoid to pay + * the overhead of function calls. Here we define these wrappers only for + * the programs SDS is linked to, if they want to touch the SDS internals + * even if they use a different allocator. */ +void *sds_malloc(size_t size) { return s_malloc(size); } +void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); } +void sds_free(void *ptr) { s_free(ptr); } + +#if defined(SDS_TEST_MAIN) +#include +#include "testhelp.h" +#include "limits.h" + +#define UNUSED(x) (void)(x) +int sdsTest(void) { + { + sds x = sdsnew("foo"), y; + + test_cond("Create a string and obtain the length", + sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0) + + sdsfree(x); + x = sdsnewlen("foo",2); + test_cond("Create a string with specified length", + sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0) + + x = sdscat(x,"bar"); + test_cond("Strings concatenation", + sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0); + + x = sdscpy(x,"a"); + test_cond("sdscpy() against an originally longer string", + sdslen(x) == 1 && memcmp(x,"a\0",2) == 0) + + x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk"); + test_cond("sdscpy() against an originally shorter string", + sdslen(x) == 33 && + memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0) + + sdsfree(x); + x = sdscatprintf(sdsempty(),"%d",123); + test_cond("sdscatprintf() seems working in the base case", + sdslen(x) == 3 && memcmp(x,"123\0",4) == 0) + + sdsfree(x); + x = sdsnew("--"); + x = sdscatfmt(x, "Hello %s World %I,%I--", "Hi!", LLONG_MIN,LLONG_MAX); + test_cond("sdscatfmt() seems working in the base case", + sdslen(x) == 60 && + memcmp(x,"--Hello Hi! World -9223372036854775808," + "9223372036854775807--",60) == 0) + printf("[%s]\n",x); + + sdsfree(x); + x = sdsnew("--"); + x = sdscatfmt(x, "%u,%U--", UINT_MAX, ULLONG_MAX); + test_cond("sdscatfmt() seems working with unsigned numbers", + sdslen(x) == 35 && + memcmp(x,"--4294967295,18446744073709551615--",35) == 0) + + sdsfree(x); + x = sdsnew(" x "); + sdstrim(x," x"); + test_cond("sdstrim() works when all chars match", + sdslen(x) == 0) + + sdsfree(x); + x = sdsnew(" x "); + sdstrim(x," "); + test_cond("sdstrim() works when a single char remains", + sdslen(x) == 1 && x[0] == 'x') + + sdsfree(x); + x = sdsnew("xxciaoyyy"); + sdstrim(x,"xy"); + test_cond("sdstrim() correctly trims characters", + sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0) + + y = sdsdup(x); + sdsrange(y,1,1); + test_cond("sdsrange(...,1,1)", + sdslen(y) == 1 && memcmp(y,"i\0",2) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,1,-1); + test_cond("sdsrange(...,1,-1)", + sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,-2,-1); + test_cond("sdsrange(...,-2,-1)", + sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,2,1); + test_cond("sdsrange(...,2,1)", + sdslen(y) == 0 && memcmp(y,"\0",1) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,1,100); + test_cond("sdsrange(...,1,100)", + sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,100,100); + test_cond("sdsrange(...,100,100)", + sdslen(y) == 0 && memcmp(y,"\0",1) == 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("foo"); + y = sdsnew("foa"); + test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("bar"); + y = sdsnew("bar"); + test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("aar"); + y = sdsnew("bar"); + test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0) + + sdsfree(y); + sdsfree(x); + x = sdsnewlen("\a\n\0foo\r",7); + y = sdscatrepr(sdsempty(),x,sdslen(x)); + test_cond("sdscatrepr(...data...)", + memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0) + + { + unsigned int oldfree; + char *p; + int step = 10, j, i; + + sdsfree(x); + sdsfree(y); + x = sdsnew("0"); + test_cond("sdsnew() free/len buffers", sdslen(x) == 1 && sdsavail(x) == 0); + + /* Run the test a few times in order to hit the first two + * SDS header types. */ + for (i = 0; i < 10; i++) { + int oldlen = sdslen(x); + x = sdsMakeRoomFor(x,step); + int type = x[-1]&SDS_TYPE_MASK; + + test_cond("sdsMakeRoomFor() len", sdslen(x) == oldlen); + if (type != SDS_TYPE_5) { + test_cond("sdsMakeRoomFor() free", sdsavail(x) >= step); + oldfree = sdsavail(x); + } + p = x+oldlen; + for (j = 0; j < step; j++) { + p[j] = 'A'+j; + } + sdsIncrLen(x,step); + } + test_cond("sdsMakeRoomFor() content", + memcmp("0ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ",x,101) == 0); + test_cond("sdsMakeRoomFor() final length",sdslen(x)==101); + + sdsfree(x); + } + } + test_report() + return 0; +} +#endif + +#ifdef SDS_TEST_MAIN +int main(void) { + return sdsTest(); +} +#endif diff --git a/ext/hiredis-0.14.1/sds.h b/ext/hiredis-0.14.1/sds.h new file mode 100644 index 0000000..13be75a --- /dev/null +++ b/ext/hiredis-0.14.1/sds.h @@ -0,0 +1,273 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SDS_H +#define __SDS_H + +#define SDS_MAX_PREALLOC (1024*1024) + +#include +#include +#include + +typedef char *sds; + +/* Note: sdshdr5 is never used, we just access the flags byte directly. + * However is here to document the layout of type 5 SDS strings. */ +struct __attribute__ ((__packed__)) sdshdr5 { + unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr8 { + uint8_t len; /* used */ + uint8_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr16 { + uint16_t len; /* used */ + uint16_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr32 { + uint32_t len; /* used */ + uint32_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr64 { + uint64_t len; /* used */ + uint64_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; + +#define SDS_TYPE_5 0 +#define SDS_TYPE_8 1 +#define SDS_TYPE_16 2 +#define SDS_TYPE_32 3 +#define SDS_TYPE_64 4 +#define SDS_TYPE_MASK 7 +#define SDS_TYPE_BITS 3 +#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))); +#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)))) +#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) + +static inline size_t sdslen(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->len; + case SDS_TYPE_16: + return SDS_HDR(16,s)->len; + case SDS_TYPE_32: + return SDS_HDR(32,s)->len; + case SDS_TYPE_64: + return SDS_HDR(64,s)->len; + } + return 0; +} + +static inline size_t sdsavail(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + return 0; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + return sh->alloc - sh->len; + } + } + return 0; +} + +static inline void sdssetlen(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len = newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len = newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len = newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len = newlen; + break; + } +} + +static inline void sdsinclen(sds s, size_t inc) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char newlen = SDS_TYPE_5_LEN(flags)+inc; + *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len += inc; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len += inc; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len += inc; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len += inc; + break; + } +} + +/* sdsalloc() = sdsavail() + sdslen() */ +static inline size_t sdsalloc(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->alloc; + case SDS_TYPE_16: + return SDS_HDR(16,s)->alloc; + case SDS_TYPE_32: + return SDS_HDR(32,s)->alloc; + case SDS_TYPE_64: + return SDS_HDR(64,s)->alloc; + } + return 0; +} + +static inline void sdssetalloc(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + /* Nothing to do, this type has no total allocation info. */ + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->alloc = newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->alloc = newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->alloc = newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->alloc = newlen; + break; + } +} + +sds sdsnewlen(const void *init, size_t initlen); +sds sdsnew(const char *init); +sds sdsempty(void); +sds sdsdup(const sds s); +void sdsfree(sds s); +sds sdsgrowzero(sds s, size_t len); +sds sdscatlen(sds s, const void *t, size_t len); +sds sdscat(sds s, const char *t); +sds sdscatsds(sds s, const sds t); +sds sdscpylen(sds s, const char *t, size_t len); +sds sdscpy(sds s, const char *t); + +sds sdscatvprintf(sds s, const char *fmt, va_list ap); +#ifdef __GNUC__ +sds sdscatprintf(sds s, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +#else +sds sdscatprintf(sds s, const char *fmt, ...); +#endif + +sds sdscatfmt(sds s, char const *fmt, ...); +sds sdstrim(sds s, const char *cset); +void sdsrange(sds s, int start, int end); +void sdsupdatelen(sds s); +void sdsclear(sds s); +int sdscmp(const sds s1, const sds s2); +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count); +void sdsfreesplitres(sds *tokens, int count); +void sdstolower(sds s); +void sdstoupper(sds s); +sds sdsfromlonglong(long long value); +sds sdscatrepr(sds s, const char *p, size_t len); +sds *sdssplitargs(const char *line, int *argc); +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); +sds sdsjoin(char **argv, int argc, char *sep); +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen); + +/* Low level functions exposed to the user API */ +sds sdsMakeRoomFor(sds s, size_t addlen); +void sdsIncrLen(sds s, int incr); +sds sdsRemoveFreeSpace(sds s); +size_t sdsAllocSize(sds s); +void *sdsAllocPtr(sds s); + +/* Export the allocator used by SDS to the program using SDS. + * Sometimes the program SDS is linked to, may use a different set of + * allocators, but may want to allocate or free things that SDS will + * respectively free or allocate. */ +void *sds_malloc(size_t size); +void *sds_realloc(void *ptr, size_t size); +void sds_free(void *ptr); + +#ifdef REDIS_TEST +int sdsTest(int argc, char *argv[]); +#endif + +#endif diff --git a/ext/hiredis-0.14.1/sdsalloc.h b/ext/hiredis-0.14.1/sdsalloc.h new file mode 100644 index 0000000..f43023c --- /dev/null +++ b/ext/hiredis-0.14.1/sdsalloc.h @@ -0,0 +1,42 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* SDS allocator selection. + * + * This file is used in order to change the SDS allocator at compile time. + * Just define the following defines to what you want to use. Also add + * the include of your alternate allocator if needed (not needed in order + * to use the default libc allocator). */ + +#define s_malloc malloc +#define s_realloc realloc +#define s_free free diff --git a/ext/hiredis-0.14.1/test.c b/ext/hiredis-0.14.1/test.c new file mode 100644 index 0000000..0f5bfe5 --- /dev/null +++ b/ext/hiredis-0.14.1/test.c @@ -0,0 +1,923 @@ +#include "fmacros.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hiredis.h" +#include "net.h" + +enum connection_type { + CONN_TCP, + CONN_UNIX, + CONN_FD +}; + +struct config { + enum connection_type type; + + struct { + const char *host; + int port; + struct timeval timeout; + } tcp; + + struct { + const char *path; + } unix_sock; +}; + +/* The following lines make up our testing "framework" :) */ +static int tests = 0, fails = 0; +#define test(_s) { printf("#%02d ", ++tests); printf(_s); } +#define test_cond(_c) if(_c) printf("\033[0;32mPASSED\033[0;0m\n"); else {printf("\033[0;31mFAILED\033[0;0m\n"); fails++;} + +static long long usec(void) { + struct timeval tv; + gettimeofday(&tv,NULL); + return (((long long)tv.tv_sec)*1000000)+tv.tv_usec; +} + +/* The assert() calls below have side effects, so we need assert() + * even if we are compiling without asserts (-DNDEBUG). */ +#ifdef NDEBUG +#undef assert +#define assert(e) (void)(e) +#endif + +static redisContext *select_database(redisContext *c) { + redisReply *reply; + + /* Switch to DB 9 for testing, now that we know we can chat. */ + reply = redisCommand(c,"SELECT 9"); + assert(reply != NULL); + freeReplyObject(reply); + + /* Make sure the DB is emtpy */ + reply = redisCommand(c,"DBSIZE"); + assert(reply != NULL); + if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) { + /* Awesome, DB 9 is empty and we can continue. */ + freeReplyObject(reply); + } else { + printf("Database #9 is not empty, test can not continue\n"); + exit(1); + } + + return c; +} + +static int disconnect(redisContext *c, int keep_fd) { + redisReply *reply; + + /* Make sure we're on DB 9. */ + reply = redisCommand(c,"SELECT 9"); + assert(reply != NULL); + freeReplyObject(reply); + reply = redisCommand(c,"FLUSHDB"); + assert(reply != NULL); + freeReplyObject(reply); + + /* Free the context as well, but keep the fd if requested. */ + if (keep_fd) + return redisFreeKeepFd(c); + redisFree(c); + return -1; +} + +static redisContext *connect(struct config config) { + redisContext *c = NULL; + + if (config.type == CONN_TCP) { + c = redisConnect(config.tcp.host, config.tcp.port); + } else if (config.type == CONN_UNIX) { + c = redisConnectUnix(config.unix_sock.path); + } else if (config.type == CONN_FD) { + /* Create a dummy connection just to get an fd to inherit */ + redisContext *dummy_ctx = redisConnectUnix(config.unix_sock.path); + if (dummy_ctx) { + int fd = disconnect(dummy_ctx, 1); + printf("Connecting to inherited fd %d\n", fd); + c = redisConnectFd(fd); + } + } else { + assert(NULL); + } + + if (c == NULL) { + printf("Connection error: can't allocate redis context\n"); + exit(1); + } else if (c->err) { + printf("Connection error: %s\n", c->errstr); + redisFree(c); + exit(1); + } + + return select_database(c); +} + +static void test_format_commands(void) { + char *cmd; + int len; + + test("Format command without interpolation: "); + len = redisFormatCommand(&cmd,"SET foo bar"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + free(cmd); + + test("Format command with %%s string interpolation: "); + len = redisFormatCommand(&cmd,"SET %s %s","foo","bar"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + free(cmd); + + test("Format command with %%s and an empty string: "); + len = redisFormatCommand(&cmd,"SET %s %s","foo",""); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(0+2)); + free(cmd); + + test("Format command with an empty string in between proper interpolations: "); + len = redisFormatCommand(&cmd,"SET %s %s","","foo"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 && + len == 4+4+(3+2)+4+(0+2)+4+(3+2)); + free(cmd); + + test("Format command with %%b string interpolation: "); + len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + free(cmd); + + test("Format command with %%b and an empty string: "); + len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(0+2)); + free(cmd); + + test("Format command with literal %%: "); + len = redisFormatCommand(&cmd,"SET %% %%"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 && + len == 4+4+(3+2)+4+(1+2)+4+(1+2)); + free(cmd); + + /* Vararg width depends on the type. These tests make sure that the + * width is correctly determined using the format and subsequent varargs + * can correctly be interpolated. */ +#define INTEGER_WIDTH_TEST(fmt, type) do { \ + type value = 123; \ + test("Format command with printf-delegation (" #type "): "); \ + len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \ + test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \ + len == 4+5+(12+2)+4+(9+2)); \ + free(cmd); \ +} while(0) + +#define FLOAT_WIDTH_TEST(type) do { \ + type value = 123.0; \ + test("Format command with printf-delegation (" #type "): "); \ + len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \ + test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \ + len == 4+5+(12+2)+4+(9+2)); \ + free(cmd); \ +} while(0) + + INTEGER_WIDTH_TEST("d", int); + INTEGER_WIDTH_TEST("hhd", char); + INTEGER_WIDTH_TEST("hd", short); + INTEGER_WIDTH_TEST("ld", long); + INTEGER_WIDTH_TEST("lld", long long); + INTEGER_WIDTH_TEST("u", unsigned int); + INTEGER_WIDTH_TEST("hhu", unsigned char); + INTEGER_WIDTH_TEST("hu", unsigned short); + INTEGER_WIDTH_TEST("lu", unsigned long); + INTEGER_WIDTH_TEST("llu", unsigned long long); + FLOAT_WIDTH_TEST(float); + FLOAT_WIDTH_TEST(double); + + test("Format command with invalid printf format: "); + len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3); + test_cond(len == -1); + + const char *argv[3]; + argv[0] = "SET"; + argv[1] = "foo\0xxx"; + argv[2] = "bar"; + size_t lens[3] = { 3, 7, 3 }; + int argc = 3; + + test("Format command by passing argc/argv without lengths: "); + len = redisFormatCommandArgv(&cmd,argc,argv,NULL); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + free(cmd); + + test("Format command by passing argc/argv with lengths: "); + len = redisFormatCommandArgv(&cmd,argc,argv,lens); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(7+2)+4+(3+2)); + free(cmd); + + sds sds_cmd; + + sds_cmd = sdsempty(); + test("Format command into sds by passing argc/argv without lengths: "); + len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,NULL); + test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + sdsfree(sds_cmd); + + sds_cmd = sdsempty(); + test("Format command into sds by passing argc/argv with lengths: "); + len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,lens); + test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(7+2)+4+(3+2)); + sdsfree(sds_cmd); +} + +static void test_append_formatted_commands(struct config config) { + redisContext *c; + redisReply *reply; + char *cmd; + int len; + + c = connect(config); + + test("Append format command: "); + + len = redisFormatCommand(&cmd, "SET foo bar"); + + test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK); + + assert(redisGetReply(c, (void*)&reply) == REDIS_OK); + + free(cmd); + freeReplyObject(reply); + + disconnect(c, 0); +} + +static void test_reply_reader(void) { + redisReader *reader; + void *reply; + int ret; + int i; + + test("Error handling in reply parser: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"@foo\r\n",6); + ret = redisReaderGetReply(reader,NULL); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); + redisReaderFree(reader); + + /* when the reply already contains multiple items, they must be free'd + * on an error. valgrind will bark when this doesn't happen. */ + test("Memory cleanup in reply parser: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"*2\r\n",4); + redisReaderFeed(reader,(char*)"$5\r\nhello\r\n",11); + redisReaderFeed(reader,(char*)"@foo\r\n",6); + ret = redisReaderGetReply(reader,NULL); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); + redisReaderFree(reader); + + test("Set error on nested multi bulks with depth > 7: "); + reader = redisReaderCreate(); + + for (i = 0; i < 9; i++) { + redisReaderFeed(reader,(char*)"*1\r\n",4); + } + + ret = redisReaderGetReply(reader,NULL); + test_cond(ret == REDIS_ERR && + strncasecmp(reader->errstr,"No support for",14) == 0); + redisReaderFree(reader); + + test("Correctly parses LLONG_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":9223372036854775807\r\n",22); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_INTEGER && + ((redisReply*)reply)->integer == LLONG_MAX); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when > LLONG_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":9223372036854775808\r\n",22); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bad integer value") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Correctly parses LLONG_MIN: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":-9223372036854775808\r\n",23); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_INTEGER && + ((redisReply*)reply)->integer == LLONG_MIN); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when < LLONG_MIN: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":-9223372036854775809\r\n",23); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bad integer value") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when array < -1: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "*-2\r\n+asdf\r\n",12); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when bulk < -1: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "$-2\r\nasdf\r\n",11); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bulk string length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when array > INT_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "*9223372036854775807\r\n+asdf\r\n",29); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + +#if LLONG_MAX > SIZE_MAX + test("Set error when bulk > SIZE_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "$9223372036854775807\r\nasdf\r\n",28); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bulk string length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); +#endif + + test("Works with NULL functions for reply: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"+OK\r\n",5); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); + redisReaderFree(reader); + + test("Works when a single newline (\\r\\n) covers two calls to feed: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"+OK\r",4); + ret = redisReaderGetReply(reader,&reply); + assert(ret == REDIS_OK && reply == NULL); + redisReaderFeed(reader,(char*)"\n",1); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); + redisReaderFree(reader); + + test("Don't reset state after protocol error: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"x",1); + ret = redisReaderGetReply(reader,&reply); + assert(ret == REDIS_ERR); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && reply == NULL); + redisReaderFree(reader); + + /* Regression test for issue #45 on GitHub. */ + test("Don't do empty allocation for empty multi bulk: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"*0\r\n",4); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && + ((redisReply*)reply)->elements == 0); + freeReplyObject(reply); + redisReaderFree(reader); +} + +static void test_free_null(void) { + void *redisCtx = NULL; + void *reply = NULL; + + test("Don't fail when redisFree is passed a NULL value: "); + redisFree(redisCtx); + test_cond(redisCtx == NULL); + + test("Don't fail when freeReplyObject is passed a NULL value: "); + freeReplyObject(reply); + test_cond(reply == NULL); +} + +static void test_blocking_connection_errors(void) { + redisContext *c; + + test("Returns error when host cannot be resolved: "); + c = redisConnect((char*)"idontexist.test", 6379); + test_cond(c->err == REDIS_ERR_OTHER && + (strcmp(c->errstr,"Name or service not known") == 0 || + strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 || + strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 || + strcmp(c->errstr,"No address associated with hostname") == 0 || + strcmp(c->errstr,"Temporary failure in name resolution") == 0 || + strcmp(c->errstr,"hostname nor servname provided, or not known") == 0 || + strcmp(c->errstr,"no address associated with name") == 0)); + redisFree(c); + + test("Returns error when the port is not open: "); + c = redisConnect((char*)"localhost", 1); + test_cond(c->err == REDIS_ERR_IO && + strcmp(c->errstr,"Connection refused") == 0); + redisFree(c); + + test("Returns error when the unix_sock socket path doesn't accept connections: "); + c = redisConnectUnix((char*)"/tmp/idontexist.sock"); + test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */ + redisFree(c); +} + +static void test_blocking_connection(struct config config) { + redisContext *c; + redisReply *reply; + + c = connect(config); + + test("Is able to deliver commands: "); + reply = redisCommand(c,"PING"); + test_cond(reply->type == REDIS_REPLY_STATUS && + strcasecmp(reply->str,"pong") == 0) + freeReplyObject(reply); + + test("Is a able to send commands verbatim: "); + reply = redisCommand(c,"SET foo bar"); + test_cond (reply->type == REDIS_REPLY_STATUS && + strcasecmp(reply->str,"ok") == 0) + freeReplyObject(reply); + + test("%%s String interpolation works: "); + reply = redisCommand(c,"SET %s %s","foo","hello world"); + freeReplyObject(reply); + reply = redisCommand(c,"GET foo"); + test_cond(reply->type == REDIS_REPLY_STRING && + strcmp(reply->str,"hello world") == 0); + freeReplyObject(reply); + + test("%%b String interpolation works: "); + reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11); + freeReplyObject(reply); + reply = redisCommand(c,"GET foo"); + test_cond(reply->type == REDIS_REPLY_STRING && + memcmp(reply->str,"hello\x00world",11) == 0) + + test("Binary reply length is correct: "); + test_cond(reply->len == 11) + freeReplyObject(reply); + + test("Can parse nil replies: "); + reply = redisCommand(c,"GET nokey"); + test_cond(reply->type == REDIS_REPLY_NIL) + freeReplyObject(reply); + + /* test 7 */ + test("Can parse integer replies: "); + reply = redisCommand(c,"INCR mycounter"); + test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) + freeReplyObject(reply); + + test("Can parse multi bulk replies: "); + freeReplyObject(redisCommand(c,"LPUSH mylist foo")); + freeReplyObject(redisCommand(c,"LPUSH mylist bar")); + reply = redisCommand(c,"LRANGE mylist 0 -1"); + test_cond(reply->type == REDIS_REPLY_ARRAY && + reply->elements == 2 && + !memcmp(reply->element[0]->str,"bar",3) && + !memcmp(reply->element[1]->str,"foo",3)) + freeReplyObject(reply); + + /* m/e with multi bulk reply *before* other reply. + * specifically test ordering of reply items to parse. */ + test("Can handle nested multi bulk replies: "); + freeReplyObject(redisCommand(c,"MULTI")); + freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1")); + freeReplyObject(redisCommand(c,"PING")); + reply = (redisCommand(c,"EXEC")); + test_cond(reply->type == REDIS_REPLY_ARRAY && + reply->elements == 2 && + reply->element[0]->type == REDIS_REPLY_ARRAY && + reply->element[0]->elements == 2 && + !memcmp(reply->element[0]->element[0]->str,"bar",3) && + !memcmp(reply->element[0]->element[1]->str,"foo",3) && + reply->element[1]->type == REDIS_REPLY_STATUS && + strcasecmp(reply->element[1]->str,"pong") == 0); + freeReplyObject(reply); + + disconnect(c, 0); +} + +static void test_blocking_connection_timeouts(struct config config) { + redisContext *c; + redisReply *reply; + ssize_t s; + const char *cmd = "DEBUG SLEEP 3\r\n"; + struct timeval tv; + + c = connect(config); + test("Successfully completes a command when the timeout is not exceeded: "); + reply = redisCommand(c,"SET foo fast"); + freeReplyObject(reply); + tv.tv_sec = 0; + tv.tv_usec = 10000; + redisSetTimeout(c, tv); + reply = redisCommand(c, "GET foo"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0); + freeReplyObject(reply); + disconnect(c, 0); + + c = connect(config); + test("Does not return a reply when the command times out: "); + s = write(c->fd, cmd, strlen(cmd)); + tv.tv_sec = 0; + tv.tv_usec = 10000; + redisSetTimeout(c, tv); + reply = redisCommand(c, "GET foo"); + test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0); + freeReplyObject(reply); + + test("Reconnect properly reconnects after a timeout: "); + redisReconnect(c); + reply = redisCommand(c, "PING"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + freeReplyObject(reply); + + test("Reconnect properly uses owned parameters: "); + config.tcp.host = "foo"; + config.unix_sock.path = "foo"; + redisReconnect(c); + reply = redisCommand(c, "PING"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + freeReplyObject(reply); + + disconnect(c, 0); +} + +static void test_blocking_io_errors(struct config config) { + redisContext *c; + redisReply *reply; + void *_reply; + int major, minor; + + /* Connect to target given by config. */ + c = connect(config); + { + /* Find out Redis version to determine the path for the next test */ + const char *field = "redis_version:"; + char *p, *eptr; + + reply = redisCommand(c,"INFO"); + p = strstr(reply->str,field); + major = strtol(p+strlen(field),&eptr,10); + p = eptr+1; /* char next to the first "." */ + minor = strtol(p,&eptr,10); + freeReplyObject(reply); + } + + test("Returns I/O error when the connection is lost: "); + reply = redisCommand(c,"QUIT"); + if (major > 2 || (major == 2 && minor > 0)) { + /* > 2.0 returns OK on QUIT and read() should be issued once more + * to know the descriptor is at EOF. */ + test_cond(strcasecmp(reply->str,"OK") == 0 && + redisGetReply(c,&_reply) == REDIS_ERR); + freeReplyObject(reply); + } else { + test_cond(reply == NULL); + } + + /* On 2.0, QUIT will cause the connection to be closed immediately and + * the read(2) for the reply on QUIT will set the error to EOF. + * On >2.0, QUIT will return with OK and another read(2) needed to be + * issued to find out the socket was closed by the server. In both + * conditions, the error will be set to EOF. */ + assert(c->err == REDIS_ERR_EOF && + strcmp(c->errstr,"Server closed the connection") == 0); + redisFree(c); + + c = connect(config); + test("Returns I/O error on socket timeout: "); + struct timeval tv = { 0, 1000 }; + assert(redisSetTimeout(c,tv) == REDIS_OK); + test_cond(redisGetReply(c,&_reply) == REDIS_ERR && + c->err == REDIS_ERR_IO && errno == EAGAIN); + redisFree(c); +} + +static void test_invalid_timeout_errors(struct config config) { + redisContext *c; + + test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: "); + + config.tcp.timeout.tv_sec = 0; + config.tcp.timeout.tv_usec = 10000001; + + c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout); + + test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); + redisFree(c); + + test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: "); + + config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1; + config.tcp.timeout.tv_usec = 0; + + c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout); + + test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); + redisFree(c); +} + +static void test_throughput(struct config config) { + redisContext *c = connect(config); + redisReply **replies; + int i, num; + long long t1, t2; + + test("Throughput:\n"); + for (i = 0; i < 500; i++) + freeReplyObject(redisCommand(c,"LPUSH mylist foo")); + + num = 1000; + replies = malloc(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c,"PING"); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx PING: %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = malloc(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c,"LRANGE mylist 0 499"); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); + assert(replies[i] != NULL && replies[i]->elements == 500); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = malloc(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c, "INCRBY incrkey %d", 1000000); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx INCRBY: %.3fs)\n", num, (t2-t1)/1000000.0); + + num = 10000; + replies = malloc(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"PING"); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx PING (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = malloc(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"LRANGE mylist 0 499"); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); + assert(replies[i] != NULL && replies[i]->elements == 500); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = malloc(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"INCRBY incrkey %d", 1000000); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx INCRBY (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + disconnect(c, 0); +} + +// static long __test_callback_flags = 0; +// static void __test_callback(redisContext *c, void *privdata) { +// ((void)c); +// /* Shift to detect execution order */ +// __test_callback_flags <<= 8; +// __test_callback_flags |= (long)privdata; +// } +// +// static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) { +// ((void)c); +// /* Shift to detect execution order */ +// __test_callback_flags <<= 8; +// __test_callback_flags |= (long)privdata; +// if (reply) freeReplyObject(reply); +// } +// +// static redisContext *__connect_nonblock() { +// /* Reset callback flags */ +// __test_callback_flags = 0; +// return redisConnectNonBlock("127.0.0.1", port, NULL); +// } +// +// static void test_nonblocking_connection() { +// redisContext *c; +// int wdone = 0; +// +// test("Calls command callback when command is issued: "); +// c = __connect_nonblock(); +// redisSetCommandCallback(c,__test_callback,(void*)1); +// redisCommand(c,"PING"); +// test_cond(__test_callback_flags == 1); +// redisFree(c); +// +// test("Calls disconnect callback on redisDisconnect: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)2); +// redisDisconnect(c); +// test_cond(__test_callback_flags == 2); +// redisFree(c); +// +// test("Calls disconnect callback and free callback on redisFree: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)2); +// redisSetFreeCallback(c,__test_callback,(void*)4); +// redisFree(c); +// test_cond(__test_callback_flags == ((2 << 8) | 4)); +// +// test("redisBufferWrite against empty write buffer: "); +// c = __connect_nonblock(); +// test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1); +// redisFree(c); +// +// test("redisBufferWrite against not yet connected fd: "); +// c = __connect_nonblock(); +// redisCommand(c,"PING"); +// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && +// strncmp(c->error,"write:",6) == 0); +// redisFree(c); +// +// test("redisBufferWrite against closed fd: "); +// c = __connect_nonblock(); +// redisCommand(c,"PING"); +// redisDisconnect(c); +// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && +// strncmp(c->error,"write:",6) == 0); +// redisFree(c); +// +// test("Process callbacks in the right sequence: "); +// c = __connect_nonblock(); +// redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING"); +// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); +// redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING"); +// +// /* Write output buffer */ +// wdone = 0; +// while(!wdone) { +// usleep(500); +// redisBufferWrite(c,&wdone); +// } +// +// /* Read until at least one callback is executed (the 3 replies will +// * arrive in a single packet, causing all callbacks to be executed in +// * a single pass). */ +// while(__test_callback_flags == 0) { +// assert(redisBufferRead(c) == REDIS_OK); +// redisProcessCallbacks(c); +// } +// test_cond(__test_callback_flags == 0x010203); +// redisFree(c); +// +// test("redisDisconnect executes pending callbacks with NULL reply: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)1); +// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); +// redisDisconnect(c); +// test_cond(__test_callback_flags == 0x0201); +// redisFree(c); +// } + +int main(int argc, char **argv) { + struct config cfg = { + .tcp = { + .host = "127.0.0.1", + .port = 6379 + }, + .unix_sock = { + .path = "/tmp/redis.sock" + } + }; + int throughput = 1; + int test_inherit_fd = 1; + + /* Ignore broken pipe signal (for I/O error tests). */ + signal(SIGPIPE, SIG_IGN); + + /* Parse command line options. */ + argv++; argc--; + while (argc) { + if (argc >= 2 && !strcmp(argv[0],"-h")) { + argv++; argc--; + cfg.tcp.host = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"-p")) { + argv++; argc--; + cfg.tcp.port = atoi(argv[0]); + } else if (argc >= 2 && !strcmp(argv[0],"-s")) { + argv++; argc--; + cfg.unix_sock.path = argv[0]; + } else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) { + throughput = 0; + } else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) { + test_inherit_fd = 0; + } else { + fprintf(stderr, "Invalid argument: %s\n", argv[0]); + exit(1); + } + argv++; argc--; + } + + test_format_commands(); + test_reply_reader(); + test_blocking_connection_errors(); + test_free_null(); + + printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port); + cfg.type = CONN_TCP; + test_blocking_connection(cfg); + test_blocking_connection_timeouts(cfg); + test_blocking_io_errors(cfg); + test_invalid_timeout_errors(cfg); + test_append_formatted_commands(cfg); + if (throughput) test_throughput(cfg); + + printf("\nTesting against Unix socket connection (%s):\n", cfg.unix_sock.path); + cfg.type = CONN_UNIX; + test_blocking_connection(cfg); + test_blocking_connection_timeouts(cfg); + test_blocking_io_errors(cfg); + if (throughput) test_throughput(cfg); + + if (test_inherit_fd) { + printf("\nTesting against inherited fd (%s):\n", cfg.unix_sock.path); + cfg.type = CONN_FD; + test_blocking_connection(cfg); + } + + + if (fails) { + printf("*** %d TESTS FAILED ***\n", fails); + return 1; + } + + printf("ALL TESTS PASSED\n"); + return 0; +} diff --git a/ext/hiredis-0.14.1/win32.h b/ext/hiredis-0.14.1/win32.h new file mode 100644 index 0000000..1a27c18 --- /dev/null +++ b/ext/hiredis-0.14.1/win32.h @@ -0,0 +1,42 @@ +#ifndef _WIN32_HELPER_INCLUDE +#define _WIN32_HELPER_INCLUDE +#ifdef _MSC_VER + +#ifndef inline +#define inline __inline +#endif + +#ifndef va_copy +#define va_copy(d,s) ((d) = (s)) +#endif + +#ifndef snprintf +#define snprintf c99_snprintf + +__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +__inline int c99_snprintf(char* str, size_t size, const char* format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} +#endif + +#endif +#endif \ No newline at end of file diff --git a/ext/hiredis-1.0.2/.gitignore b/ext/hiredis-1.0.2/.gitignore new file mode 100644 index 0000000..056959f --- /dev/null +++ b/ext/hiredis-1.0.2/.gitignore @@ -0,0 +1,9 @@ +/hiredis-test +/examples/hiredis-example* +/*.o +/*.so +/*.dylib +/*.a +/*.pc +*.dSYM +tags diff --git a/ext/hiredis-1.0.2/.travis.yml b/ext/hiredis-1.0.2/.travis.yml new file mode 100644 index 0000000..f9a9460 --- /dev/null +++ b/ext/hiredis-1.0.2/.travis.yml @@ -0,0 +1,131 @@ +language: c +compiler: + - gcc + - clang + +os: + - linux + - osx + +dist: bionic + +branches: + only: + - staging + - trying + - master + - /^release\/.*$/ + +install: + - if [ "$BITS" == "64" ]; then + wget https://github.com/redis/redis/archive/6.0.6.tar.gz; + tar -xzvf 6.0.6.tar.gz; + pushd redis-6.0.6 && BUILD_TLS=yes make && export PATH=$PWD/src:$PATH && popd; + fi + +before_script: + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then + curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.6.2-10.13-HighSierra.pkg; + sudo installer -pkg MacPorts-2.6.2-10.13-HighSierra.pkg -target /; + export PATH=$PATH:/opt/local/bin && sudo port -v selfupdate; + sudo port -N install openssl redis; + fi; + +addons: + apt: + sources: + - sourceline: 'ppa:chris-lea/redis-server' + packages: + - libc6-dbg + - libc6-dev + - libc6:i386 + - libc6-dev-i386 + - libc6-dbg:i386 + - gcc-multilib + - g++-multilib + - libssl-dev + - libssl-dev:i386 + - valgrind + - redis + +env: + - BITS="32" + - BITS="64" + +script: + - EXTRA_CMAKE_OPTS="-DENABLE_EXAMPLES:BOOL=ON -DENABLE_SSL:BOOL=ON"; + if [ "$BITS" == "64" ]; then + EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DENABLE_SSL_TESTS:BOOL=ON"; + fi; + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + if [ "$BITS" == "32" ]; then + CFLAGS="-m32 -Werror"; + CXXFLAGS="-m32 -Werror"; + LDFLAGS="-m32"; + EXTRA_CMAKE_OPTS=; + else + CFLAGS="-Werror"; + CXXFLAGS="-Werror"; + fi; + else + TEST_PREFIX="valgrind --track-origins=yes --leak-check=full"; + if [ "$BITS" == "32" ]; then + CFLAGS="-m32 -Werror"; + CXXFLAGS="-m32 -Werror"; + LDFLAGS="-m32"; + EXTRA_CMAKE_OPTS=; + else + CFLAGS="-Werror"; + CXXFLAGS="-Werror"; + fi; + fi; + export CFLAGS CXXFLAGS LDFLAGS TEST_PREFIX EXTRA_CMAKE_OPTS + - make && make clean; + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + if [ "$BITS" == "64" ]; then + OPENSSL_PREFIX="$(ls -d /usr/local/Cellar/openssl@1.1/*)" USE_SSL=1 make; + fi; + else + USE_SSL=1 make; + fi; + - mkdir build/ && cd build/ + - cmake .. ${EXTRA_CMAKE_OPTS} + - make VERBOSE=1 + - if [ "$BITS" == "64" ]; then + TEST_SSL=1 SKIPS_AS_FAILS=1 ctest -V; + else + SKIPS_AS_FAILS=1 ctest -V; + fi; + +jobs: + include: + # Windows MinGW cross compile on Linux + - os: linux + dist: xenial + compiler: mingw + addons: + apt: + packages: + - ninja-build + - gcc-mingw-w64-x86-64 + - g++-mingw-w64-x86-64 + script: + - mkdir build && cd build + - CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_WITH_INSTALL_RPATH=on + - ninja -v + + # Windows MSVC 2017 + - os: windows + compiler: msvc + env: + - MATRIX_EVAL="CC=cl.exe && CXX=cl.exe" + before_install: + - eval "${MATRIX_EVAL}" + install: + - choco install ninja + - choco install -y memurai-developer + script: + - mkdir build && cd build + - cmd.exe //C 'C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat' amd64 '&&' + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DENABLE_EXAMPLES=ON '&&' ninja -v + - ./hiredis-test.exe diff --git a/ext/hiredis-1.0.2/CHANGELOG.md b/ext/hiredis-1.0.2/CHANGELOG.md new file mode 100644 index 0000000..2a2bc31 --- /dev/null +++ b/ext/hiredis-1.0.2/CHANGELOG.md @@ -0,0 +1,364 @@ +## [1.0.2](https://github.com/redis/hiredis/tree/v1.0.2) - (2021-10-07) + +Announcing Hiredis v1.0.2, which fixes CVE-2021-32765 but returns the SONAME to the correct value of `1.0.0`. + +- [Revert SONAME bump](https://github.com/redis/hiredis/commit/d4e6f109a064690cde64765c654e679fea1d3548) + ([Michael Grunder](https://github.com/michael-grunder)) + +## [1.0.1](https://github.com/redis/hiredis/tree/v1.0.1) - (2021-10-04) + +This release erroneously bumped the SONAME, please use [1.0.2](https://github.com/redis/hiredis/tree/v1.0.2) + +Announcing Hiredis v1.0.1, a security release fixing CVE-2021-32765 + +- Fix for [CVE-2021-32765](https://github.com/redis/hiredis/security/advisories/GHSA-hfm9-39pp-55p2) + [commit](https://github.com/redis/hiredis/commit/76a7b10005c70babee357a7d0f2becf28ec7ed1e) + ([Yossi Gottlieb](https://github.com/yossigo)) + +_Thanks to [Yossi Gottlieb](https://github.com/yossigo) for the security fix and to [Microsoft Security Vulnerability Research](https://www.microsoft.com/en-us/msrc/msvr) for finding the bug._ :sparkling_heart: + +## [1.0.0](https://github.com/redis/hiredis/tree/v1.0.0) - (2020-08-03) + +Announcing Hiredis v1.0.0, which adds support for RESP3, SSL connections, allocator injection, and better Windows support! :tada: + +_A big thanks to everyone who helped with this release. The following list includes everyone who contributed at least five lines, sorted by lines contributed._ :sparkling_heart: + +[Michael Grunder](https://github.com/michael-grunder), [Yossi Gottlieb](https://github.com/yossigo), +[Mark Nunberg](https://github.com/mnunberg), [Marcus Geelnard](https://github.com/mbitsnbites), +[Justin Brewer](https://github.com/justinbrewer), [Valentino Geron](https://github.com/valentinogeron), +[Minun Dragonation](https://github.com/dragonation), [Omri Steiner](https://github.com/OmriSteiner), +[Sangmoon Yi](https://github.com/jman-krafton), [Jinjiazh](https://github.com/jinjiazhang), +[Odin Hultgren Van Der Horst](https://github.com/Miniwoffer), [Muhammad Zahalqa](https://github.com/tryfinally), +[Nick Rivera](https://github.com/heronr), [Qi Yang](https://github.com/movebean), +[kevin1018](https://github.com/kevin1018) + +[Full Changelog](https://github.com/redis/hiredis/compare/v0.14.1...v1.0.0) + +**BREAKING CHANGES**: + +* `redisOptions` now has two timeout fields. One for connecting, and one for commands. If you're presently using `options->timeout` you will need to change it to use `options->connect_timeout`. (See [example](https://github.com/redis/hiredis/commit/38b5ae543f5c99eb4ccabbe277770fc6bc81226f#diff-86ba39d37aa829c8c82624cce4f049fbL36)) + +* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now protocol errors. This is consistent + with the RESP specification. On 32-bit platforms, the upper bound is lowered to `SIZE_MAX`. + +* `redisReplyObjectFunctions.createArray` now takes `size_t` for its length parameter. + +**New features:** +- Support for RESP3 + [\#697](https://github.com/redis/hiredis/pull/697), + [\#805](https://github.com/redis/hiredis/pull/805), + [\#819](https://github.com/redis/hiredis/pull/819), + [\#841](https://github.com/redis/hiredis/pull/841) + ([Yossi Gottlieb](https://github.com/yossigo), [Michael Grunder](https://github.com/michael-grunder)) +- Support for SSL connections + [\#645](https://github.com/redis/hiredis/pull/645), + [\#699](https://github.com/redis/hiredis/pull/699), + [\#702](https://github.com/redis/hiredis/pull/702), + [\#708](https://github.com/redis/hiredis/pull/708), + [\#711](https://github.com/redis/hiredis/pull/711), + [\#821](https://github.com/redis/hiredis/pull/821), + [more](https://github.com/redis/hiredis/pulls?q=is%3Apr+is%3Amerged+SSL) + ([Mark Nunberg](https://github.com/mnunberg), [Yossi Gottlieb](https://github.com/yossigo)) +- Run-time allocator injection + [\#800](https://github.com/redis/hiredis/pull/800) + ([Michael Grunder](https://github.com/michael-grunder)) +- Improved Windows support (including MinGW and Windows CI) + [\#652](https://github.com/redis/hiredis/pull/652), + [\#663](https://github.com/redis/hiredis/pull/663) + ([Marcus Geelnard](https://www.bitsnbites.eu/author/m/)) +- Adds support for distinct connect and command timeouts + [\#839](https://github.com/redis/hiredis/pull/839), + [\#829](https://github.com/redis/hiredis/pull/829) + ([Valentino Geron](https://github.com/valentinogeron)) +- Add generic pointer and destructor to `redisContext` that users can use for context. + [\#855](https://github.com/redis/hiredis/pull/855) + ([Michael Grunder](https://github.com/michael-grunder)) + +**Closed issues (that involved code changes):** + +- Makefile does not install TLS libraries [\#809](https://github.com/redis/hiredis/issues/809) +- redisConnectWithOptions should not set command timeout [\#722](https://github.com/redis/hiredis/issues/722), [\#829](https://github.com/redis/hiredis/pull/829) ([valentinogeron](https://github.com/valentinogeron)) +- Fix integer overflow in `sdsrange` [\#827](https://github.com/redis/hiredis/issues/827) +- INFO & CLUSTER commands failed when using RESP3 [\#802](https://github.com/redis/hiredis/issues/802) +- Windows compatibility patches [\#687](https://github.com/redis/hiredis/issues/687), [\#838](https://github.com/redis/hiredis/issues/838), [\#842](https://github.com/redis/hiredis/issues/842) +- RESP3 PUSH messages incorrectly use pending callback [\#825](https://github.com/redis/hiredis/issues/825) +- Asynchronous PSUBSCRIBE command fails when using RESP3 [\#815](https://github.com/redis/hiredis/issues/815) +- New SSL API [\#804](https://github.com/redis/hiredis/issues/804), [\#813](https://github.com/redis/hiredis/issues/813) +- Hard-coded limit of nested reply depth [\#794](https://github.com/redis/hiredis/issues/794) +- Fix TCP_NODELAY in Windows/OSX [\#679](https://github.com/redis/hiredis/issues/679), [\#690](https://github.com/redis/hiredis/issues/690), [\#779](https://github.com/redis/hiredis/issues/779), [\#785](https://github.com/redis/hiredis/issues/785), +- Added timers to libev adapter. [\#778](https://github.com/redis/hiredis/issues/778), [\#795](https://github.com/redis/hiredis/pull/795) +- Initialization discards const qualifier [\#777](https://github.com/redis/hiredis/issues/777) +- \[BUG\]\[MinGW64\] Error setting socket timeout [\#775](https://github.com/redis/hiredis/issues/775) +- undefined reference to hi_malloc [\#769](https://github.com/redis/hiredis/issues/769) +- hiredis pkg-config file incorrectly ignores multiarch libdir spec'n [\#767](https://github.com/redis/hiredis/issues/767) +- Don't use -G to build shared object on Solaris [\#757](https://github.com/redis/hiredis/issues/757) +- error when make USE\_SSL=1 [\#748](https://github.com/redis/hiredis/issues/748) +- Allow to change SSL Mode [\#646](https://github.com/redis/hiredis/issues/646) +- hiredis/adapters/libevent.h memleak [\#618](https://github.com/redis/hiredis/issues/618) +- redisLibuvPoll crash when server closes the connetion [\#545](https://github.com/redis/hiredis/issues/545) +- about redisAsyncDisconnect question [\#518](https://github.com/redis/hiredis/issues/518) +- hiredis adapters libuv error for help [\#508](https://github.com/redis/hiredis/issues/508) +- API/ABI changes analysis [\#506](https://github.com/redis/hiredis/issues/506) +- Memory leak patch in Redis [\#502](https://github.com/redis/hiredis/issues/502) +- Remove the depth limitation [\#421](https://github.com/redis/hiredis/issues/421) + +**Merged pull requests:** + +- Move SSL management to a distinct private pointer [\#855](https://github.com/redis/hiredis/pull/855) ([michael-grunder](https://github.com/michael-grunder)) +- Move include to sockcompat.h to maintain style [\#850](https://github.com/redis/hiredis/pull/850) ([michael-grunder](https://github.com/michael-grunder)) +- Remove erroneous tag and add license to push example [\#849](https://github.com/redis/hiredis/pull/849) ([michael-grunder](https://github.com/michael-grunder)) +- fix windows compiling with mingw [\#848](https://github.com/redis/hiredis/pull/848) ([rmalizia44](https://github.com/rmalizia44)) +- Some Windows quality of life improvements. [\#846](https://github.com/redis/hiredis/pull/846) ([michael-grunder](https://github.com/michael-grunder)) +- Use \_WIN32 define instead of WIN32 [\#845](https://github.com/redis/hiredis/pull/845) ([michael-grunder](https://github.com/michael-grunder)) +- Non Linux CI fixes [\#844](https://github.com/redis/hiredis/pull/844) ([michael-grunder](https://github.com/michael-grunder)) +- Resp3 oob push support [\#841](https://github.com/redis/hiredis/pull/841) ([michael-grunder](https://github.com/michael-grunder)) +- fix \#785: defer TCP\_NODELAY in async tcp connections [\#836](https://github.com/redis/hiredis/pull/836) ([OmriSteiner](https://github.com/OmriSteiner)) +- sdsrange overflow fix [\#830](https://github.com/redis/hiredis/pull/830) ([michael-grunder](https://github.com/michael-grunder)) +- Use explicit pointer casting for c++ compatibility [\#826](https://github.com/redis/hiredis/pull/826) ([aureus1](https://github.com/aureus1)) +- Document allocator injection and completeness fix in test.c [\#824](https://github.com/redis/hiredis/pull/824) ([michael-grunder](https://github.com/michael-grunder)) +- Use unique names for allocator struct members [\#823](https://github.com/redis/hiredis/pull/823) ([michael-grunder](https://github.com/michael-grunder)) +- New SSL API to replace redisSecureConnection\(\). [\#821](https://github.com/redis/hiredis/pull/821) ([yossigo](https://github.com/yossigo)) +- Add logic to handle RESP3 push messages [\#819](https://github.com/redis/hiredis/pull/819) ([michael-grunder](https://github.com/michael-grunder)) +- Use standrad isxdigit instead of custom helper function. [\#814](https://github.com/redis/hiredis/pull/814) ([tryfinally](https://github.com/tryfinally)) +- Fix missing SSL build/install options. [\#812](https://github.com/redis/hiredis/pull/812) ([yossigo](https://github.com/yossigo)) +- Add link to ABI tracker [\#808](https://github.com/redis/hiredis/pull/808) ([michael-grunder](https://github.com/michael-grunder)) +- Resp3 verbatim string support [\#805](https://github.com/redis/hiredis/pull/805) ([michael-grunder](https://github.com/michael-grunder)) +- Allow users to replace allocator and handle OOM everywhere. [\#800](https://github.com/redis/hiredis/pull/800) ([michael-grunder](https://github.com/michael-grunder)) +- Remove nested depth limitation. [\#797](https://github.com/redis/hiredis/pull/797) ([michael-grunder](https://github.com/michael-grunder)) +- Attempt to fix compilation on Solaris [\#796](https://github.com/redis/hiredis/pull/796) ([michael-grunder](https://github.com/michael-grunder)) +- Support timeouts in libev adapater [\#795](https://github.com/redis/hiredis/pull/795) ([michael-grunder](https://github.com/michael-grunder)) +- Fix pkgconfig when installing to a custom lib dir [\#793](https://github.com/redis/hiredis/pull/793) ([michael-grunder](https://github.com/michael-grunder)) +- Fix USE\_SSL=1 make/cmake on OSX and CMake tests [\#789](https://github.com/redis/hiredis/pull/789) ([michael-grunder](https://github.com/michael-grunder)) +- Use correct libuv call on Windows [\#784](https://github.com/redis/hiredis/pull/784) ([michael-grunder](https://github.com/michael-grunder)) +- Added CMake package config and fixed hiredis\_ssl on Windows [\#783](https://github.com/redis/hiredis/pull/783) ([michael-grunder](https://github.com/michael-grunder)) +- CMake: Set hiredis\_ssl shared object version. [\#780](https://github.com/redis/hiredis/pull/780) ([yossigo](https://github.com/yossigo)) +- Win32 tests and timeout fix [\#776](https://github.com/redis/hiredis/pull/776) ([michael-grunder](https://github.com/michael-grunder)) +- Provides an optional cleanup callback for async data. [\#768](https://github.com/redis/hiredis/pull/768) ([heronr](https://github.com/heronr)) +- Housekeeping fixes [\#764](https://github.com/redis/hiredis/pull/764) ([michael-grunder](https://github.com/michael-grunder)) +- install alloc.h [\#756](https://github.com/redis/hiredis/pull/756) ([ch1aki](https://github.com/ch1aki)) +- fix spelling mistakes [\#746](https://github.com/redis/hiredis/pull/746) ([ShooterIT](https://github.com/ShooterIT)) +- Free the reply in redisGetReply when passed NULL [\#741](https://github.com/redis/hiredis/pull/741) ([michael-grunder](https://github.com/michael-grunder)) +- Fix dead code in sslLogCallback relating to should\_log variable. [\#737](https://github.com/redis/hiredis/pull/737) ([natoscott](https://github.com/natoscott)) +- Fix typo in dict.c. [\#731](https://github.com/redis/hiredis/pull/731) ([Kevin-Xi](https://github.com/Kevin-Xi)) +- Adding an option to DISABLE\_TESTS [\#727](https://github.com/redis/hiredis/pull/727) ([pbotros](https://github.com/pbotros)) +- Update README with SSL support. [\#720](https://github.com/redis/hiredis/pull/720) ([yossigo](https://github.com/yossigo)) +- Fixes leaks in unit tests [\#715](https://github.com/redis/hiredis/pull/715) ([michael-grunder](https://github.com/michael-grunder)) +- SSL Tests [\#711](https://github.com/redis/hiredis/pull/711) ([yossigo](https://github.com/yossigo)) +- SSL Reorganization [\#708](https://github.com/redis/hiredis/pull/708) ([yossigo](https://github.com/yossigo)) +- Fix MSVC build. [\#706](https://github.com/redis/hiredis/pull/706) ([yossigo](https://github.com/yossigo)) +- SSL: Properly report SSL\_connect\(\) errors. [\#702](https://github.com/redis/hiredis/pull/702) ([yossigo](https://github.com/yossigo)) +- Silent SSL trace to stdout by default. [\#699](https://github.com/redis/hiredis/pull/699) ([yossigo](https://github.com/yossigo)) +- Port RESP3 support from Redis. [\#697](https://github.com/redis/hiredis/pull/697) ([yossigo](https://github.com/yossigo)) +- Removed whitespace before newline [\#691](https://github.com/redis/hiredis/pull/691) ([Miniwoffer](https://github.com/Miniwoffer)) +- Add install adapters header files [\#688](https://github.com/redis/hiredis/pull/688) ([kevin1018](https://github.com/kevin1018)) +- Remove unnecessary null check before free [\#684](https://github.com/redis/hiredis/pull/684) ([qlyoung](https://github.com/qlyoung)) +- redisReaderGetReply leak memory [\#671](https://github.com/redis/hiredis/pull/671) ([movebean](https://github.com/movebean)) +- fix timeout code in windows [\#670](https://github.com/redis/hiredis/pull/670) ([jman-krafton](https://github.com/jman-krafton)) +- test: fix errstr matching for musl libc [\#665](https://github.com/redis/hiredis/pull/665) ([ghost](https://github.com/ghost)) +- Windows: MinGW fixes and Windows Travis builders [\#663](https://github.com/redis/hiredis/pull/663) ([mbitsnbites](https://github.com/mbitsnbites)) +- The setsockopt and getsockopt API diffs from BSD socket and WSA one [\#662](https://github.com/redis/hiredis/pull/662) ([dragonation](https://github.com/dragonation)) +- Fix Compile Error On Windows \(Visual Studio\) [\#658](https://github.com/redis/hiredis/pull/658) ([jinjiazhang](https://github.com/jinjiazhang)) +- Fix NXDOMAIN test case [\#653](https://github.com/redis/hiredis/pull/653) ([michael-grunder](https://github.com/michael-grunder)) +- Add MinGW support [\#652](https://github.com/redis/hiredis/pull/652) ([mbitsnbites](https://github.com/mbitsnbites)) +- SSL Support [\#645](https://github.com/redis/hiredis/pull/645) ([mnunberg](https://github.com/mnunberg)) +- Fix Invalid argument after redisAsyncConnectUnix [\#644](https://github.com/redis/hiredis/pull/644) ([codehz](https://github.com/codehz)) +- Makefile: use predefined AR [\#632](https://github.com/redis/hiredis/pull/632) ([Mic92](https://github.com/Mic92)) +- FreeBSD build fix [\#628](https://github.com/redis/hiredis/pull/628) ([devnexen](https://github.com/devnexen)) +- Fix errors not propagating properly with libuv.h. [\#624](https://github.com/redis/hiredis/pull/624) ([yossigo](https://github.com/yossigo)) +- Update README.md [\#621](https://github.com/redis/hiredis/pull/621) ([Crunsher](https://github.com/Crunsher)) +- Fix redisBufferRead documentation [\#620](https://github.com/redis/hiredis/pull/620) ([hacst](https://github.com/hacst)) +- Add CPPFLAGS to REAL\_CFLAGS [\#614](https://github.com/redis/hiredis/pull/614) ([thomaslee](https://github.com/thomaslee)) +- Update createArray to take size\_t [\#597](https://github.com/redis/hiredis/pull/597) ([justinbrewer](https://github.com/justinbrewer)) +- fix common realloc mistake and add null check more [\#580](https://github.com/redis/hiredis/pull/580) ([charsyam](https://github.com/charsyam)) +- Proper error reporting for connect failures [\#578](https://github.com/redis/hiredis/pull/578) ([mnunberg](https://github.com/mnunberg)) + +\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* + +## [1.0.0-rc1](https://github.com/redis/hiredis/tree/v1.0.0-rc1) - (2020-07-29) + +_Note: There were no changes to code between v1.0.0-rc1 and v1.0.0 so see v1.0.0 for changelog_ + +### 0.14.1 (2020-03-13) + +* Adds safe allocation wrappers (CVE-2020-7105, #747, #752) (Michael Grunder) + +### 0.14.0 (2018-09-25) +**BREAKING CHANGES**: + +* Change `redisReply.len` to `size_t`, as it denotes the the size of a string + + User code should compare this to `size_t` values as well. + If it was used to compare to other values, casting might be necessary or can be removed, if casting was applied before. + +* Make string2ll static to fix conflict with Redis (Tom Lee [c3188b]) +* Use -dynamiclib instead of -shared for OSX (Ryan Schmidt [a65537]) +* Use string2ll from Redis w/added tests (Michael Grunder [7bef04, 60f622]) +* Makefile - OSX compilation fixes (Ryan Schmidt [881fcb, 0e9af8]) +* Remove redundant NULL checks (Justin Brewer [54acc8, 58e6b8]) +* Fix bulk and multi-bulk length truncation (Justin Brewer [109197]) +* Fix SIGSEGV in OpenBSD by checking for NULL before calling freeaddrinfo (Justin Brewer [546d94]) +* Several POSIX compatibility fixes (Justin Brewer [bbeab8, 49bbaa, d1c1b6]) +* Makefile - Compatibility fixes (Dimitri Vorobiev [3238cf, 12a9d1]) +* Makefile - Fix make install on FreeBSD (Zach Shipko [a2ef2b]) +* Makefile - don't assume $(INSTALL) is cp (Igor Gnatenko [725a96]) +* Separate side-effect causing function from assert and small cleanup (amallia [b46413, 3c3234]) +* Don't send negative values to `__redisAsyncCommand` (Frederik Deweerdt [706129]) +* Fix leak if setsockopt fails (Frederik Deweerdt [e21c9c]) +* Fix libevent leak (zfz [515228]) +* Clean up GCC warning (Ichito Nagata [2ec774]) +* Keep track of errno in `__redisSetErrorFromErrno()` as snprintf may use it (Jin Qing [25cd88]) +* Solaris compilation fix (Donald Whyte [41b07d]) +* Reorder linker arguments when building examples (Tustfarm-heart [06eedd]) +* Keep track of subscriptions in case of rapid subscribe/unsubscribe (Hyungjin Kim [073dc8, be76c5, d46999]) +* libuv use after free fix (Paul Scott [cbb956]) +* Properly close socket fd on reconnect attempt (WSL [64d1ec]) +* Skip valgrind in OSX tests (Jan-Erik Rediger [9deb78]) +* Various updates for Travis testing OSX (Ted Nyman [fa3774, 16a459, bc0ea5]) +* Update libevent (Chris Xin [386802]) +* Change sds.h for building in C++ projects (Ali Volkan ATLI [f5b32e]) +* Use proper format specifier in redisFormatSdsCommandArgv (Paulino Huerta, Jan-Erik Rediger [360a06, 8655a6]) +* Better handling of NULL reply in example code (Jan-Erik Rediger [1b8ed3]) +* Prevent overflow when formatting an error (Jan-Erik Rediger [0335cb]) +* Compatibility fix for strerror_r (Tom Lee [bb1747]) +* Properly detect integer parse/overflow errors (Justin Brewer [93421f]) +* Adds CI for Windows and cygwin fixes (owent, [6c53d6, 6c3e40]) +* Catch a buffer overflow when formatting the error message +* Import latest upstream sds. This breaks applications that are linked against the old hiredis v0.13 +* Fix warnings, when compiled with -Wshadow +* Make hiredis compile in Cygwin on Windows, now CI-tested +* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now + protocol errors. This is consistent with the RESP specification. On 32-bit + platforms, the upper bound is lowered to `SIZE_MAX`. + +* Remove backwards compatibility macro's + +This removes the following old function aliases, use the new name now: + +| Old | New | +| --------------------------- | ---------------------- | +| redisReplyReaderCreate | redisReaderCreate | +| redisReplyReaderCreate | redisReaderCreate | +| redisReplyReaderFree | redisReaderFree | +| redisReplyReaderFeed | redisReaderFeed | +| redisReplyReaderGetReply | redisReaderGetReply | +| redisReplyReaderSetPrivdata | redisReaderSetPrivdata | +| redisReplyReaderGetObject | redisReaderGetObject | +| redisReplyReaderGetError | redisReaderGetError | + +* The `DEBUG` variable in the Makefile was renamed to `DEBUG_FLAGS` + +Previously it broke some builds for people that had `DEBUG` set to some arbitrary value, +due to debugging other software. +By renaming we avoid unintentional name clashes. + +Simply rename `DEBUG` to `DEBUG_FLAGS` in your environment to make it working again. + +### 0.13.3 (2015-09-16) + +* Revert "Clear `REDIS_CONNECTED` flag when connection is closed". +* Make tests pass on FreeBSD (Thanks, Giacomo Olgeni) + + +If the `REDIS_CONNECTED` flag is cleared, +the async onDisconnect callback function will never be called. +This causes problems as the disconnect is never reported back to the user. + +### 0.13.2 (2015-08-25) + +* Prevent crash on pending replies in async code (Thanks, @switch-st) +* Clear `REDIS_CONNECTED` flag when connection is closed (Thanks, Jerry Jacobs) +* Add MacOS X addapter (Thanks, @dizzus) +* Add Qt adapter (Thanks, Pietro Cerutti) +* Add Ivykis adapter (Thanks, Gergely Nagy) + +All adapters are provided as is and are only tested where possible. + +### 0.13.1 (2015-05-03) + +This is a bug fix release. +The new `reconnect` method introduced new struct members, which clashed with pre-defined names in pre-C99 code. +Another commit forced C99 compilation just to make it work, but of course this is not desirable for outside projects. +Other non-C99 code can now use hiredis as usual again. +Sorry for the inconvenience. + +* Fix memory leak in async reply handling (Salvatore Sanfilippo) +* Rename struct member to avoid name clash with pre-c99 code (Alex Balashov, ncopa) + +### 0.13.0 (2015-04-16) + +This release adds a minimal Windows compatibility layer. +The parser, standalone since v0.12.0, can now be compiled on Windows +(and thus used in other client libraries as well) + +* Windows compatibility layer for parser code (tzickel) +* Properly escape data printed to PKGCONF file (Dan Skorupski) +* Fix tests when assert() undefined (Keith Bennett, Matt Stancliff) +* Implement a reconnect method for the client context, this changes the structure of `redisContext` (Aaron Bedra) + +### 0.12.1 (2015-01-26) + +* Fix `make install`: DESTDIR support, install all required files, install PKGCONF in proper location +* Fix `make test` as 32 bit build on 64 bit platform + +### 0.12.0 (2015-01-22) + +* Add optional KeepAlive support + +* Try again on EINTR errors + +* Add libuv adapter + +* Add IPv6 support + +* Remove possibility of multiple close on same fd + +* Add ability to bind source address on connect + +* Add redisConnectFd() and redisFreeKeepFd() + +* Fix getaddrinfo() memory leak + +* Free string if it is unused (fixes memory leak) + +* Improve redisAppendCommandArgv performance 2.5x + +* Add support for SO_REUSEADDR + +* Fix redisvFormatCommand format parsing + +* Add GLib 2.0 adapter + +* Refactor reading code into read.c + +* Fix errno error buffers to not clobber errors + +* Generate pkgconf during build + +* Silence _BSD_SOURCE warnings + +* Improve digit counting for multibulk creation + + +### 0.11.0 + +* Increase the maximum multi-bulk reply depth to 7. + +* Increase the read buffer size from 2k to 16k. + +* Use poll(2) instead of select(2) to support large fds (>= 1024). + +### 0.10.1 + +* Makefile overhaul. Important to check out if you override one or more + variables using environment variables or via arguments to the "make" tool. + +* Issue #45: Fix potential memory leak for a multi bulk reply with 0 elements + being created by the default reply object functions. + +* Issue #43: Don't crash in an asynchronous context when Redis returns an error + reply after the connection has been made (this happens when the maximum + number of connections is reached). + +### 0.10.0 + +* See commit log. diff --git a/ext/hiredis-1.0.2/CMakeLists.txt b/ext/hiredis-1.0.2/CMakeLists.txt new file mode 100644 index 0000000..f86c9b7 --- /dev/null +++ b/ext/hiredis-1.0.2/CMakeLists.txt @@ -0,0 +1,165 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.4.0) +INCLUDE(GNUInstallDirs) +PROJECT(hiredis) + +OPTION(ENABLE_SSL "Build hiredis_ssl for SSL support" OFF) +OPTION(DISABLE_TESTS "If tests should be compiled or not" OFF) +OPTION(ENABLE_SSL_TESTS, "Should we test SSL connections" OFF) + +MACRO(getVersionBit name) + SET(VERSION_REGEX "^#define ${name} (.+)$") + FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/hiredis.h" + VERSION_BIT REGEX ${VERSION_REGEX}) + STRING(REGEX REPLACE ${VERSION_REGEX} "\\1" ${name} "${VERSION_BIT}") +ENDMACRO(getVersionBit) + +getVersionBit(HIREDIS_MAJOR) +getVersionBit(HIREDIS_MINOR) +getVersionBit(HIREDIS_PATCH) +getVersionBit(HIREDIS_SONAME) +SET(VERSION "${HIREDIS_MAJOR}.${HIREDIS_MINOR}.${HIREDIS_PATCH}") +MESSAGE("Detected version: ${VERSION}") + +PROJECT(hiredis VERSION "${VERSION}") + +SET(ENABLE_EXAMPLES OFF CACHE BOOL "Enable building hiredis examples") + +SET(hiredis_sources + alloc.c + async.c + dict.c + hiredis.c + net.c + read.c + sds.c + sockcompat.c) + +SET(hiredis_sources ${hiredis_sources}) + +IF(WIN32) + ADD_COMPILE_DEFINITIONS(_CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN) +ENDIF() + +ADD_LIBRARY(hiredis SHARED ${hiredis_sources}) + +SET_TARGET_PROPERTIES(hiredis + PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE + VERSION "${HIREDIS_SONAME}") +IF(WIN32 OR MINGW) + TARGET_LINK_LIBRARIES(hiredis PRIVATE ws2_32) +ENDIF() + +TARGET_INCLUDE_DIRECTORIES(hiredis PUBLIC $ $) + +CONFIGURE_FILE(hiredis.pc.in hiredis.pc @ONLY) + +INSTALL(TARGETS hiredis + EXPORT hiredis-targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +INSTALL(FILES hiredis.h read.h sds.h async.h alloc.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) + +INSTALL(DIRECTORY adapters + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) + +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + +export(EXPORT hiredis-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/hiredis-targets.cmake" + NAMESPACE hiredis::) + +SET(CMAKE_CONF_INSTALL_DIR share/hiredis) +SET(INCLUDE_INSTALL_DIR include) +include(CMakePackageConfigHelpers) +configure_package_config_file(hiredis-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/hiredis-config.cmake + INSTALL_DESTINATION ${CMAKE_CONF_INSTALL_DIR} + PATH_VARS INCLUDE_INSTALL_DIR) + +INSTALL(EXPORT hiredis-targets + FILE hiredis-targets.cmake + NAMESPACE hiredis:: + DESTINATION ${CMAKE_CONF_INSTALL_DIR}) + +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis-config.cmake + DESTINATION ${CMAKE_CONF_INSTALL_DIR}) + + +IF(ENABLE_SSL) + IF (NOT OPENSSL_ROOT_DIR) + IF (APPLE) + SET(OPENSSL_ROOT_DIR "/usr/local/opt/openssl") + ENDIF() + ENDIF() + FIND_PACKAGE(OpenSSL REQUIRED) + SET(hiredis_ssl_sources + ssl.c) + ADD_LIBRARY(hiredis_ssl SHARED + ${hiredis_ssl_sources}) + + IF (APPLE) + SET_PROPERTY(TARGET hiredis_ssl PROPERTY LINK_FLAGS "-Wl,-undefined -Wl,dynamic_lookup") + ENDIF() + + SET_TARGET_PROPERTIES(hiredis_ssl + PROPERTIES + WINDOWS_EXPORT_ALL_SYMBOLS TRUE + VERSION "${HIREDIS_SONAME}") + + TARGET_INCLUDE_DIRECTORIES(hiredis_ssl PRIVATE "${OPENSSL_INCLUDE_DIR}") + TARGET_LINK_LIBRARIES(hiredis_ssl PRIVATE ${OPENSSL_LIBRARIES}) + IF (WIN32 OR MINGW) + TARGET_LINK_LIBRARIES(hiredis_ssl PRIVATE hiredis) + ENDIF() + CONFIGURE_FILE(hiredis_ssl.pc.in hiredis_ssl.pc @ONLY) + + INSTALL(TARGETS hiredis_ssl + EXPORT hiredis_ssl-targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + + INSTALL(FILES hiredis_ssl.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) + + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + + export(EXPORT hiredis_ssl-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl-targets.cmake" + NAMESPACE hiredis::) + + SET(CMAKE_CONF_INSTALL_DIR share/hiredis_ssl) + configure_package_config_file(hiredis_ssl-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl-config.cmake + INSTALL_DESTINATION ${CMAKE_CONF_INSTALL_DIR} + PATH_VARS INCLUDE_INSTALL_DIR) + + INSTALL(EXPORT hiredis_ssl-targets + FILE hiredis_ssl-targets.cmake + NAMESPACE hiredis:: + DESTINATION ${CMAKE_CONF_INSTALL_DIR}) + + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl-config.cmake + DESTINATION ${CMAKE_CONF_INSTALL_DIR}) +ENDIF() + +IF(NOT DISABLE_TESTS) + ENABLE_TESTING() + ADD_EXECUTABLE(hiredis-test test.c) + IF(ENABLE_SSL_TESTS) + ADD_DEFINITIONS(-DHIREDIS_TEST_SSL=1) + TARGET_LINK_LIBRARIES(hiredis-test hiredis hiredis_ssl) + ELSE() + TARGET_LINK_LIBRARIES(hiredis-test hiredis) + ENDIF() + ADD_TEST(NAME hiredis-test + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test.sh) +ENDIF() + +# Add examples +IF(ENABLE_EXAMPLES) + ADD_SUBDIRECTORY(examples) +ENDIF(ENABLE_EXAMPLES) diff --git a/ext/hiredis-1.0.2/COPYING b/ext/hiredis-1.0.2/COPYING new file mode 100644 index 0000000..a5fc973 --- /dev/null +++ b/ext/hiredis-1.0.2/COPYING @@ -0,0 +1,29 @@ +Copyright (c) 2009-2011, Salvatore Sanfilippo +Copyright (c) 2010-2011, Pieter Noordhuis + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of Redis nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ext/hiredis-1.0.2/Makefile b/ext/hiredis-1.0.2/Makefile new file mode 100644 index 0000000..a8d37a2 --- /dev/null +++ b/ext/hiredis-1.0.2/Makefile @@ -0,0 +1,308 @@ +# Hiredis Makefile +# Copyright (C) 2010-2011 Salvatore Sanfilippo +# Copyright (C) 2010-2011 Pieter Noordhuis +# This file is released under the BSD license, see the COPYING file + +OBJ=alloc.o net.o hiredis.o sds.o async.o read.o sockcompat.o +SSL_OBJ=ssl.o +EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib hiredis-example-push +ifeq ($(USE_SSL),1) +EXAMPLES+=hiredis-example-ssl hiredis-example-libevent-ssl +endif +TESTS=hiredis-test +LIBNAME=libhiredis +PKGCONFNAME=hiredis.pc +SSL_LIBNAME=libhiredis_ssl +SSL_PKGCONFNAME=hiredis_ssl.pc + +HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}') +HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}') +HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}') +HIREDIS_SONAME=$(shell grep HIREDIS_SONAME hiredis.h | awk '{print $$3}') + +# Installation related variables and target +PREFIX?=/usr/local +INCLUDE_PATH?=include/hiredis +LIBRARY_PATH?=lib +PKGCONF_PATH?=pkgconfig +INSTALL_INCLUDE_PATH= $(DESTDIR)$(PREFIX)/$(INCLUDE_PATH) +INSTALL_LIBRARY_PATH= $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH) +INSTALL_PKGCONF_PATH= $(INSTALL_LIBRARY_PATH)/$(PKGCONF_PATH) + +# redis-server configuration used for testing +REDIS_PORT=56379 +REDIS_SERVER=redis-server +define REDIS_TEST_CONFIG + daemonize yes + pidfile /tmp/hiredis-test-redis.pid + port $(REDIS_PORT) + bind 127.0.0.1 + unixsocket /tmp/hiredis-test-redis.sock +endef +export REDIS_TEST_CONFIG + +# Fallback to gcc when $CC is not in $PATH. +CC:=$(shell sh -c 'type $${CC%% *} >/dev/null 2>/dev/null && echo $(CC) || echo gcc') +CXX:=$(shell sh -c 'type $${CXX%% *} >/dev/null 2>/dev/null && echo $(CXX) || echo g++') +OPTIMIZATION?=-O3 +WARNINGS=-Wall -W -Wstrict-prototypes -Wwrite-strings -Wno-missing-field-initializers +DEBUG_FLAGS?= -g -ggdb +REAL_CFLAGS=$(OPTIMIZATION) -fPIC $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEBUG_FLAGS) +REAL_LDFLAGS=$(LDFLAGS) + +DYLIBSUFFIX=so +STLIBSUFFIX=a +DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME) +DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR) +DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX) + +DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) +STLIBNAME=$(LIBNAME).$(STLIBSUFFIX) +STLIB_MAKE_CMD=$(AR) rcs + +SSL_DYLIB_MINOR_NAME=$(SSL_LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME) +SSL_DYLIB_MAJOR_NAME=$(SSL_LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR) +SSL_DYLIBNAME=$(SSL_LIBNAME).$(DYLIBSUFFIX) +SSL_STLIBNAME=$(SSL_LIBNAME).$(STLIBSUFFIX) +SSL_DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(SSL_DYLIB_MINOR_NAME) + +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +USE_SSL?=0 + +# This is required for test.c only +ifeq ($(USE_SSL),1) + CFLAGS+=-DHIREDIS_TEST_SSL +endif + +ifeq ($(uname_S),Linux) + SSL_LDFLAGS=-lssl -lcrypto +else + OPENSSL_PREFIX?=/usr/local/opt/openssl + CFLAGS+=-I$(OPENSSL_PREFIX)/include + SSL_LDFLAGS+=-L$(OPENSSL_PREFIX)/lib -lssl -lcrypto +endif + +ifeq ($(uname_S),SunOS) + IS_SUN_CC=$(shell sh -c '$(CC) -V 2>&1 |egrep -i -c "sun|studio"') + ifeq ($(IS_SUN_CC),1) + SUN_SHARED_FLAG=-G + else + SUN_SHARED_FLAG=-shared + endif + REAL_LDFLAGS+= -ldl -lnsl -lsocket + DYLIB_MAKE_CMD=$(CC) $(SUN_SHARED_FLAG) -o $(DYLIBNAME) -h $(DYLIB_MINOR_NAME) $(LDFLAGS) + SSL_DYLIB_MAKE_CMD=$(CC) $(SUN_SHARED_FLAG) -o $(SSL_DYLIBNAME) -h $(SSL_DYLIB_MINOR_NAME) $(LDFLAGS) $(SSL_LDFLAGS) +endif +ifeq ($(uname_S),Darwin) + DYLIBSUFFIX=dylib + DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_SONAME).$(DYLIBSUFFIX) + DYLIB_MAKE_CMD=$(CC) -dynamiclib -Wl,-install_name,$(PREFIX)/$(LIBRARY_PATH)/$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS) + SSL_DYLIB_MAKE_CMD=$(CC) -dynamiclib -Wl,-install_name,$(PREFIX)/$(LIBRARY_PATH)/$(SSL_DYLIB_MINOR_NAME) -o $(SSL_DYLIBNAME) $(LDFLAGS) $(SSL_LDFLAGS) + DYLIB_PLUGIN=-Wl,-undefined -Wl,dynamic_lookup +endif + +all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME) +ifeq ($(USE_SSL),1) +all: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME) +endif + +# Deps (use make dep to generate this) +alloc.o: alloc.c fmacros.h alloc.h +async.o: async.c fmacros.h alloc.h async.h hiredis.h read.h sds.h net.h dict.c dict.h win32.h async_private.h +dict.o: dict.c fmacros.h alloc.h dict.h +hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h alloc.h net.h async.h win32.h +net.o: net.c fmacros.h net.h hiredis.h read.h sds.h alloc.h sockcompat.h win32.h +read.o: read.c fmacros.h alloc.h read.h sds.h win32.h +sds.o: sds.c sds.h sdsalloc.h alloc.h +sockcompat.o: sockcompat.c sockcompat.h +ssl.o: ssl.c hiredis.h read.h sds.h alloc.h async.h win32.h async_private.h +test.o: test.c fmacros.h hiredis.h read.h sds.h alloc.h net.h sockcompat.h win32.h + +$(DYLIBNAME): $(OBJ) + $(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS) + +$(STLIBNAME): $(OBJ) + $(STLIB_MAKE_CMD) $(STLIBNAME) $(OBJ) + +$(SSL_DYLIBNAME): $(SSL_OBJ) + $(SSL_DYLIB_MAKE_CMD) $(DYLIB_PLUGIN) -o $(SSL_DYLIBNAME) $(SSL_OBJ) $(REAL_LDFLAGS) $(LDFLAGS) $(SSL_LDFLAGS) + +$(SSL_STLIBNAME): $(SSL_OBJ) + $(STLIB_MAKE_CMD) $(SSL_STLIBNAME) $(SSL_OBJ) + +dynamic: $(DYLIBNAME) +static: $(STLIBNAME) +ifeq ($(USE_SSL),1) +dynamic: $(SSL_DYLIBNAME) +static: $(SSL_STLIBNAME) +endif + +# Binaries: +hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-libevent-ssl: examples/example-libevent-ssl.c adapters/libevent.h $(STLIBNAME) $(SSL_STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) + +hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -lev $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(shell pkg-config --cflags --libs glib-2.0) $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -livykis $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -framework CoreFoundation $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-ssl: examples/example-ssl.c $(STLIBNAME) $(SSL_STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) + + +ifndef AE_DIR +hiredis-example-ae: + @echo "Please specify AE_DIR (e.g. /src)" + @false +else +hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME) +endif + +ifndef LIBUV_DIR +hiredis-example-libuv: + @echo "Please specify LIBUV_DIR (e.g. ../libuv/)" + @false +else +hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread -lrt $(STLIBNAME) $(REAL_LDFLAGS) +endif + +ifeq ($(and $(QT_MOC),$(QT_INCLUDE_DIR),$(QT_LIBRARY_DIR)),) +hiredis-example-qt: + @echo "Please specify QT_MOC, QT_INCLUDE_DIR AND QT_LIBRARY_DIR" + @false +else +hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME) + $(QT_MOC) adapters/qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ + $(CXX) -x c++ -o qt-adapter-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore + $(QT_MOC) examples/example-qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ + $(CXX) -x c++ -o qt-example-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore + $(CXX) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore -L$(QT_LIBRARY_DIR) qt-adapter-moc.o qt-example-moc.o $< -pthread $(STLIBNAME) -lQtCore +endif + +hiredis-example: examples/example.c $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-push: examples/example-push.c $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(REAL_LDFLAGS) + +examples: $(EXAMPLES) + +TEST_LIBS = $(STLIBNAME) +ifeq ($(USE_SSL),1) + TEST_LIBS += $(SSL_STLIBNAME) + TEST_LDFLAGS = $(SSL_LDFLAGS) -lssl -lcrypto -lpthread +endif + +hiredis-test: test.o $(TEST_LIBS) + $(CC) -o $@ $(REAL_CFLAGS) -I. $^ $(REAL_LDFLAGS) $(TEST_LDFLAGS) + +hiredis-%: %.o $(STLIBNAME) + $(CC) $(REAL_CFLAGS) -o $@ $< $(TEST_LIBS) $(REAL_LDFLAGS) + +test: hiredis-test + ./hiredis-test + +check: hiredis-test + TEST_SSL=$(USE_SSL) ./test.sh + +.c.o: + $(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $< + +clean: + rm -rf $(DYLIBNAME) $(STLIBNAME) $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov + +dep: + $(CC) $(CPPFLAGS) $(CFLAGS) -MM *.c + +INSTALL?= cp -pPR + +$(PKGCONFNAME): hiredis.h + @echo "Generating $@ for pkgconfig..." + @echo prefix=$(PREFIX) > $@ + @echo exec_prefix=\$${prefix} >> $@ + @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@ + @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ + @echo >> $@ + @echo Name: hiredis >> $@ + @echo Description: Minimalistic C client library for Redis. >> $@ + @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ + @echo Libs: -L\$${libdir} -lhiredis >> $@ + @echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@ + +$(SSL_PKGCONFNAME): hiredis_ssl.h + @echo "Generating $@ for pkgconfig..." + @echo prefix=$(PREFIX) > $@ + @echo exec_prefix=\$${prefix} >> $@ + @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@ + @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ + @echo >> $@ + @echo Name: hiredis_ssl >> $@ + @echo Description: SSL Support for hiredis. >> $@ + @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ + @echo Requires: hiredis >> $@ + @echo Libs: -L\$${libdir} -lhiredis_ssl >> $@ + @echo Libs.private: -lssl -lcrypto >> $@ + +install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME) + mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH) + $(INSTALL) hiredis.h async.h read.h sds.h alloc.h $(INSTALL_INCLUDE_PATH) + $(INSTALL) adapters/*.h $(INSTALL_INCLUDE_PATH)/adapters + $(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME) + cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME) + $(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH) + mkdir -p $(INSTALL_PKGCONF_PATH) + $(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH) + +ifeq ($(USE_SSL),1) +install: install-ssl + +install-ssl: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME) + mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH) + $(INSTALL) hiredis_ssl.h $(INSTALL_INCLUDE_PATH) + $(INSTALL) $(SSL_DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(SSL_DYLIB_MINOR_NAME) + cd $(INSTALL_LIBRARY_PATH) && ln -sf $(SSL_DYLIB_MINOR_NAME) $(SSL_DYLIBNAME) + $(INSTALL) $(SSL_STLIBNAME) $(INSTALL_LIBRARY_PATH) + mkdir -p $(INSTALL_PKGCONF_PATH) + $(INSTALL) $(SSL_PKGCONFNAME) $(INSTALL_PKGCONF_PATH) +endif + +32bit: + @echo "" + @echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386" + @echo "" + $(MAKE) CFLAGS="-m32" LDFLAGS="-m32" + +32bit-vars: + $(eval CFLAGS=-m32) + $(eval LDFLAGS=-m32) + +gprof: + $(MAKE) CFLAGS="-pg" LDFLAGS="-pg" + +gcov: + $(MAKE) CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs" + +coverage: gcov + make check + mkdir -p tmp/lcov + lcov -d . -c -o tmp/lcov/hiredis.info + genhtml --legend -o tmp/lcov/report tmp/lcov/hiredis.info + +noopt: + $(MAKE) OPTIMIZATION="" + +.PHONY: all test check clean dep install 32bit 32bit-vars gprof gcov noopt diff --git a/ext/hiredis-1.0.2/README.md b/ext/hiredis-1.0.2/README.md new file mode 100644 index 0000000..c544d57 --- /dev/null +++ b/ext/hiredis-1.0.2/README.md @@ -0,0 +1,664 @@ +[![Build Status](https://travis-ci.org/redis/hiredis.png)](https://travis-ci.org/redis/hiredis) + +**This Readme reflects the latest changed in the master branch. See [v1.0.0](https://github.com/redis/hiredis/tree/v1.0.0) for the Readme and documentation for the latest release ([API/ABI history](https://abi-laboratory.pro/?view=timeline&l=hiredis)).** + +# HIREDIS + +Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database. + +It is minimalistic because it just adds minimal support for the protocol, but +at the same time it uses a high level printf-alike API in order to make it +much higher level than otherwise suggested by its minimal code base and the +lack of explicit bindings for every Redis command. + +Apart from supporting sending commands and receiving replies, it comes with +a reply parser that is decoupled from the I/O layer. It +is a stream parser designed for easy reusability, which can for instance be used +in higher level language bindings for efficient reply parsing. + +Hiredis only supports the binary-safe Redis protocol, so you can use it with any +Redis version >= 1.2.0. + +The library comes with multiple APIs. There is the +*synchronous API*, the *asynchronous API* and the *reply parsing API*. + +## Upgrading to `1.0.2` + +NOTE: v1.0.1 erroneously bumped SONAME, which is why it is skipped here. + +Version 1.0.2 is simply 1.0.0 with a fix for [CVE-2021-32765](https://github.com/redis/hiredis/security/advisories/GHSA-hfm9-39pp-55p2). They are otherwise identical. + +## Upgrading to `1.0.0` + +Version 1.0.0 marks the first stable release of Hiredis. +It includes some minor breaking changes, mostly to make the exposed API more uniform and self-explanatory. +It also bundles the updated `sds` library, to sync up with upstream and Redis. +For code changes see the [Changelog](CHANGELOG.md). + +_Note: As described below, a few member names have been changed but most applications should be able to upgrade with minor code changes and recompiling._ + +## IMPORTANT: Breaking changes from `0.14.1` -> `1.0.0` + +* `redisContext` has two additional members (`free_privdata`, and `privctx`). +* `redisOptions.timeout` has been renamed to `redisOptions.connect_timeout`, and we've added `redisOptions.command_timeout`. +* `redisReplyObjectFunctions.createArray` now takes `size_t` instead of `int` for its length parameter. + +## IMPORTANT: Breaking changes when upgrading from 0.13.x -> 0.14.x + +Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now +protocol errors. This is consistent with the RESP specification. On 32-bit +platforms, the upper bound is lowered to `SIZE_MAX`. + +Change `redisReply.len` to `size_t`, as it denotes the the size of a string + +User code should compare this to `size_t` values as well. If it was used to +compare to other values, casting might be necessary or can be removed, if +casting was applied before. + +## Upgrading from `<0.9.0` + +Version 0.9.0 is a major overhaul of hiredis in every aspect. However, upgrading existing +code using hiredis should not be a big pain. The key thing to keep in mind when +upgrading is that hiredis >= 0.9.0 uses a `redisContext*` to keep state, in contrast to +the stateless 0.0.1 that only has a file descriptor to work with. + +## Synchronous API + +To consume the synchronous API, there are only a few function calls that need to be introduced: + +```c +redisContext *redisConnect(const char *ip, int port); +void *redisCommand(redisContext *c, const char *format, ...); +void freeReplyObject(void *reply); +``` + +### Connecting + +The function `redisConnect` is used to create a so-called `redisContext`. The +context is where Hiredis holds state for a connection. The `redisContext` +struct has an integer `err` field that is non-zero when the connection is in +an error state. The field `errstr` will contain a string with a description of +the error. More information on errors can be found in the **Errors** section. +After trying to connect to Redis using `redisConnect` you should +check the `err` field to see if establishing the connection was successful: +```c +redisContext *c = redisConnect("127.0.0.1", 6379); +if (c == NULL || c->err) { + if (c) { + printf("Error: %s\n", c->errstr); + // handle error + } else { + printf("Can't allocate redis context\n"); + } +} +``` + +*Note: A `redisContext` is not thread-safe.* + +### Sending commands + +There are several ways to issue commands to Redis. The first that will be introduced is +`redisCommand`. This function takes a format similar to printf. In the simplest form, +it is used like this: +```c +reply = redisCommand(context, "SET foo bar"); +``` + +The specifier `%s` interpolates a string in the command, and uses `strlen` to +determine the length of the string: +```c +reply = redisCommand(context, "SET foo %s", value); +``` +When you need to pass binary safe strings in a command, the `%b` specifier can be +used. Together with a pointer to the string, it requires a `size_t` length argument +of the string: +```c +reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen); +``` +Internally, Hiredis splits the command in different arguments and will +convert it to the protocol used to communicate with Redis. +One or more spaces separates arguments, so you can use the specifiers +anywhere in an argument: +```c +reply = redisCommand(context, "SET key:%s %s", myid, value); +``` + +### Using replies + +The return value of `redisCommand` holds a reply when the command was +successfully executed. When an error occurs, the return value is `NULL` and +the `err` field in the context will be set (see section on **Errors**). +Once an error is returned the context cannot be reused and you should set up +a new connection. + +The standard replies that `redisCommand` are of the type `redisReply`. The +`type` field in the `redisReply` should be used to test what kind of reply +was received: + +### RESP2 + +* **`REDIS_REPLY_STATUS`**: + * The command replied with a status reply. The status string can be accessed using `reply->str`. + The length of this string can be accessed using `reply->len`. + +* **`REDIS_REPLY_ERROR`**: + * The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`. + +* **`REDIS_REPLY_INTEGER`**: + * The command replied with an integer. The integer value can be accessed using the + `reply->integer` field of type `long long`. + +* **`REDIS_REPLY_NIL`**: + * The command replied with a **nil** object. There is no data to access. + +* **`REDIS_REPLY_STRING`**: + * A bulk (string) reply. The value of the reply can be accessed using `reply->str`. + The length of this string can be accessed using `reply->len`. + +* **`REDIS_REPLY_ARRAY`**: + * A multi bulk reply. The number of elements in the multi bulk reply is stored in + `reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well + and can be accessed via `reply->element[..index..]`. + Redis may reply with nested arrays but this is fully supported. + +### RESP3 + +Hiredis also supports every new `RESP3` data type which are as follows. For more information about the protocol see the `RESP3` [specification.](https://github.com/antirez/RESP3/blob/master/spec.md) + +* **`REDIS_REPLY_DOUBLE`**: + * The command replied with a double-precision floating point number. + The value is stored as a string in the `str` member, and can be converted with `strtod` or similar. + +* **`REDIS_REPLY_BOOL`**: + * A boolean true/false reply. + The value is stored in the `integer` member and will be either `0` or `1`. + +* **`REDIS_REPLY_MAP`**: + * An array with the added invariant that there will always be an even number of elements. + The MAP is functionally equivelant to `REDIS_REPLY_ARRAY` except for the previously mentioned invariant. + +* **`REDIS_REPLY_SET`**: + * An array response where each entry is unique. + Like the MAP type, the data is identical to an array response except there are no duplicate values. + +* **`REDIS_REPLY_PUSH`**: + * An array that can be generated spontaneously by Redis. + This array response will always contain at least two subelements. The first contains the type of `PUSH` message (e.g. `message`, or `invalidate`), and the second being a sub-array with the `PUSH` payload itself. + +* **`REDIS_REPLY_ATTR`**: + * An array structurally identical to a `MAP` but intended as meta-data about a reply. + _As of Redis 6.0.6 this reply type is not used in Redis_ + +* **`REDIS_REPLY_BIGNUM`**: + * A string representing an arbitrarily large signed or unsigned integer value. + The number will be encoded as a string in the `str` member of `redisReply`. + +* **`REDIS_REPLY_VERB`**: + * A verbatim string, intended to be presented to the user without modification. + The string payload is stored in the `str` memeber, and type data is stored in the `vtype` member (e.g. `txt` for raw text or `md` for markdown). + +Replies should be freed using the `freeReplyObject()` function. +Note that this function will take care of freeing sub-reply objects +contained in arrays and nested arrays, so there is no need for the user to +free the sub replies (it is actually harmful and will corrupt the memory). + +**Important:** the current version of hiredis (1.0.0) frees replies when the +asynchronous API is used. This means you should not call `freeReplyObject` when +you use this API. The reply is cleaned up by hiredis _after_ the callback +returns. We may introduce a flag to make this configurable in future versions of the library. + +### Cleaning up + +To disconnect and free the context the following function can be used: +```c +void redisFree(redisContext *c); +``` +This function immediately closes the socket and then frees the allocations done in +creating the context. + +### Sending commands (cont'd) + +Together with `redisCommand`, the function `redisCommandArgv` can be used to issue commands. +It has the following prototype: +```c +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +``` +It takes the number of arguments `argc`, an array of strings `argv` and the lengths of the +arguments `argvlen`. For convenience, `argvlen` may be set to `NULL` and the function will +use `strlen(3)` on every argument to determine its length. Obviously, when any of the arguments +need to be binary safe, the entire array of lengths `argvlen` should be provided. + +The return value has the same semantic as `redisCommand`. + +### Pipelining + +To explain how Hiredis supports pipelining in a blocking connection, there needs to be +understanding of the internal execution flow. + +When any of the functions in the `redisCommand` family is called, Hiredis first formats the +command according to the Redis protocol. The formatted command is then put in the output buffer +of the context. This output buffer is dynamic, so it can hold any number of commands. +After the command is put in the output buffer, `redisGetReply` is called. This function has the +following two execution paths: + +1. The input buffer is non-empty: + * Try to parse a single reply from the input buffer and return it + * If no reply could be parsed, continue at *2* +2. The input buffer is empty: + * Write the **entire** output buffer to the socket + * Read from the socket until a single reply could be parsed + +The function `redisGetReply` is exported as part of the Hiredis API and can be used when a reply +is expected on the socket. To pipeline commands, the only things that needs to be done is +filling up the output buffer. For this cause, two commands can be used that are identical +to the `redisCommand` family, apart from not returning a reply: +```c +void redisAppendCommand(redisContext *c, const char *format, ...); +void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +``` +After calling either function one or more times, `redisGetReply` can be used to receive the +subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_ERR`, where +the latter means an error occurred while reading a reply. Just as with the other commands, +the `err` field in the context can be used to find out what the cause of this error is. + +The following examples shows a simple pipeline (resulting in only a single call to `write(2)` and +a single call to `read(2)`): +```c +redisReply *reply; +redisAppendCommand(context,"SET foo bar"); +redisAppendCommand(context,"GET foo"); +redisGetReply(context,(void *)&reply); // reply for SET +freeReplyObject(reply); +redisGetReply(context,(void *)&reply); // reply for GET +freeReplyObject(reply); +``` +This API can also be used to implement a blocking subscriber: +```c +reply = redisCommand(context,"SUBSCRIBE foo"); +freeReplyObject(reply); +while(redisGetReply(context,(void *)&reply) == REDIS_OK) { + // consume message + freeReplyObject(reply); +} +``` +### Errors + +When a function call is not successful, depending on the function either `NULL` or `REDIS_ERR` is +returned. The `err` field inside the context will be non-zero and set to one of the +following constants: + +* **`REDIS_ERR_IO`**: + There was an I/O error while creating the connection, trying to write + to the socket or read from the socket. If you included `errno.h` in your + application, you can use the global `errno` variable to find out what is + wrong. + +* **`REDIS_ERR_EOF`**: + The server closed the connection which resulted in an empty read. + +* **`REDIS_ERR_PROTOCOL`**: + There was an error while parsing the protocol. + +* **`REDIS_ERR_OTHER`**: + Any other error. Currently, it is only used when a specified hostname to connect + to cannot be resolved. + +In every case, the `errstr` field in the context will be set to hold a string representation +of the error. + +## Asynchronous API + +Hiredis comes with an asynchronous API that works easily with any event library. +Examples are bundled that show using Hiredis with [libev](http://software.schmorp.de/pkg/libev.html) +and [libevent](http://monkey.org/~provos/libevent/). + +### Connecting + +The function `redisAsyncConnect` can be used to establish a non-blocking connection to +Redis. It returns a pointer to the newly created `redisAsyncContext` struct. The `err` field +should be checked after creation to see if there were errors creating the connection. +Because the connection that will be created is non-blocking, the kernel is not able to +instantly return if the specified host and port is able to accept a connection. + +*Note: A `redisAsyncContext` is not thread-safe.* + +```c +redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); +if (c->err) { + printf("Error: %s\n", c->errstr); + // handle error +} +``` + +The asynchronous context can hold a disconnect callback function that is called when the +connection is disconnected (either because of an error or per user request). This function should +have the following prototype: +```c +void(const redisAsyncContext *c, int status); +``` +On a disconnect, the `status` argument is set to `REDIS_OK` when disconnection was initiated by the +user, or `REDIS_ERR` when the disconnection was caused by an error. When it is `REDIS_ERR`, the `err` +field in the context can be accessed to find out the cause of the error. + +The context object is always freed after the disconnect callback fired. When a reconnect is needed, +the disconnect callback is a good point to do so. + +Setting the disconnect callback can only be done once per context. For subsequent calls it will +return `REDIS_ERR`. The function to set the disconnect callback has the following prototype: +```c +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); +``` +`ac->data` may be used to pass user data to this callback, the same can be done for redisConnectCallback. +### Sending commands and their callbacks + +In an asynchronous context, commands are automatically pipelined due to the nature of an event loop. +Therefore, unlike the synchronous API, there is only a single way to send commands. +Because commands are sent to Redis asynchronously, issuing a command requires a callback function +that is called when the reply is received. Reply callbacks should have the following prototype: +```c +void(redisAsyncContext *c, void *reply, void *privdata); +``` +The `privdata` argument can be used to curry arbitrary data to the callback from the point where +the command is initially queued for execution. + +The functions that can be used to issue commands in an asynchronous context are: +```c +int redisAsyncCommand( + redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, + const char *format, ...); +int redisAsyncCommandArgv( + redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, + int argc, const char **argv, const size_t *argvlen); +``` +Both functions work like their blocking counterparts. The return value is `REDIS_OK` when the command +was successfully added to the output buffer and `REDIS_ERR` otherwise. Example: when the connection +is being disconnected per user-request, no new commands may be added to the output buffer and `REDIS_ERR` is +returned on calls to the `redisAsyncCommand` family. + +If the reply for a command with a `NULL` callback is read, it is immediately freed. When the callback +for a command is non-`NULL`, the memory is freed immediately following the callback: the reply is only +valid for the duration of the callback. + +All pending callbacks are called with a `NULL` reply when the context encountered an error. + +### Disconnecting + +An asynchronous connection can be terminated using: +```c +void redisAsyncDisconnect(redisAsyncContext *ac); +``` +When this function is called, the connection is **not** immediately terminated. Instead, new +commands are no longer accepted and the connection is only terminated when all pending commands +have been written to the socket, their respective replies have been read and their respective +callbacks have been executed. After this, the disconnection callback is executed with the +`REDIS_OK` status and the context object is freed. + +### Hooking it up to event library *X* + +There are a few hooks that need to be set on the context object after it is created. +See the `adapters/` directory for bindings to *libev* and *libevent*. + +## Reply parsing API + +Hiredis comes with a reply parsing API that makes it easy for writing higher +level language bindings. + +The reply parsing API consists of the following functions: +```c +redisReader *redisReaderCreate(void); +void redisReaderFree(redisReader *reader); +int redisReaderFeed(redisReader *reader, const char *buf, size_t len); +int redisReaderGetReply(redisReader *reader, void **reply); +``` +The same set of functions are used internally by hiredis when creating a +normal Redis context, the above API just exposes it to the user for a direct +usage. + +### Usage + +The function `redisReaderCreate` creates a `redisReader` structure that holds a +buffer with unparsed data and state for the protocol parser. + +Incoming data -- most likely from a socket -- can be placed in the internal +buffer of the `redisReader` using `redisReaderFeed`. This function will make a +copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed +when `redisReaderGetReply` is called. This function returns an integer status +and a reply object (as described above) via `void **reply`. The returned status +can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went +wrong (either a protocol error, or an out of memory error). + +The parser limits the level of nesting for multi bulk payloads to 7. If the +multi bulk nesting level is higher than this, the parser returns an error. + +### Customizing replies + +The function `redisReaderGetReply` creates `redisReply` and makes the function +argument `reply` point to the created `redisReply` variable. For instance, if +the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply` +will hold the status as a vanilla C string. However, the functions that are +responsible for creating instances of the `redisReply` can be customized by +setting the `fn` field on the `redisReader` struct. This should be done +immediately after creating the `redisReader`. + +For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c) +uses customized reply object functions to create Ruby objects. + +### Reader max buffer + +Both when using the Reader API directly or when using it indirectly via a +normal Redis context, the redisReader structure uses a buffer in order to +accumulate data from the server. +Usually this buffer is destroyed when it is empty and is larger than 16 +KiB in order to avoid wasting memory in unused buffers + +However when working with very big payloads destroying the buffer may slow +down performances considerably, so it is possible to modify the max size of +an idle buffer changing the value of the `maxbuf` field of the reader structure +to the desired value. The special value of 0 means that there is no maximum +value for an idle buffer, so the buffer will never get freed. + +For instance if you have a normal Redis context you can set the maximum idle +buffer to zero (unlimited) just with: +```c +context->reader->maxbuf = 0; +``` +This should be done only in order to maximize performances when working with +large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again +as soon as possible in order to prevent allocation of useless memory. + +### Reader max array elements + +By default the hiredis reply parser sets the maximum number of multi-bulk elements +to 2^32 - 1 or 4,294,967,295 entries. If you need to process multi-bulk replies +with more than this many elements you can set the value higher or to zero, meaning +unlimited with: +```c +context->reader->maxelements = 0; +``` + +## SSL/TLS Support + +### Building + +SSL/TLS support is not built by default and requires an explicit flag: + + make USE_SSL=1 + +This requires OpenSSL development package (e.g. including header files to be +available. + +When enabled, SSL/TLS support is built into extra `libhiredis_ssl.a` and +`libhiredis_ssl.so` static/dynamic libraries. This leaves the original libraries +unaffected so no additional dependencies are introduced. + +### Using it + +First, you'll need to make sure you include the SSL header file: + +```c +#include "hiredis.h" +#include "hiredis_ssl.h" +``` + +You will also need to link against `libhiredis_ssl`, **in addition** to +`libhiredis` and add `-lssl -lcrypto` to satisfy its dependencies. + +Hiredis implements SSL/TLS on top of its normal `redisContext` or +`redisAsyncContext`, so you will need to establish a connection first and then +initiate an SSL/TLS handshake. + +#### Hiredis OpenSSL Wrappers + +Before Hiredis can negotiate an SSL/TLS connection, it is necessary to +initialize OpenSSL and create a context. You can do that in two ways: + +1. Work directly with the OpenSSL API to initialize the library's global context + and create `SSL_CTX *` and `SSL *` contexts. With an `SSL *` object you can + call `redisInitiateSSL()`. +2. Work with a set of Hiredis-provided wrappers around OpenSSL, create a + `redisSSLContext` object to hold configuration and use + `redisInitiateSSLWithContext()` to initiate the SSL/TLS handshake. + +```c +/* An Hiredis SSL context. It holds SSL configuration and can be reused across + * many contexts. + */ +redisSSLContext *ssl; + +/* An error variable to indicate what went wrong, if the context fails to + * initialize. + */ +redisSSLContextError ssl_error; + +/* Initialize global OpenSSL state. + * + * You should call this only once when your app initializes, and only if + * you don't explicitly or implicitly initialize OpenSSL it elsewhere. + */ +redisInitOpenSSL(); + +/* Create SSL context */ +ssl = redisCreateSSLContext( + "cacertbundle.crt", /* File name of trusted CA/ca bundle file, optional */ + "/path/to/certs", /* Path of trusted certificates, optional */ + "client_cert.pem", /* File name of client certificate file, optional */ + "client_key.pem", /* File name of client private key, optional */ + "redis.mydomain.com", /* Server name to request (SNI), optional */ + &ssl_error + ) != REDIS_OK) { + printf("SSL error: %s\n", redisSSLContextGetError(ssl_error); + /* Abort... */ + } + +/* Create Redis context and establish connection */ +c = redisConnect("localhost", 6443); +if (c == NULL || c->err) { + /* Handle error and abort... */ +} + +/* Negotiate SSL/TLS */ +if (redisInitiateSSLWithContext(c, ssl) != REDIS_OK) { + /* Handle error, in c->err / c->errstr */ +} +``` + +## RESP3 PUSH replies +Redis 6.0 introduced PUSH replies with the reply-type `>`. These messages are generated spontaneously and can arrive at any time, so must be handled using callbacks. + +### Default behavior +Hiredis installs handlers on `redisContext` and `redisAsyncContext` by default, which will intercept and free any PUSH replies detected. This means existing code will work as-is after upgrading to Redis 6 and switching to `RESP3`. + +### Custom PUSH handler prototypes +The callback prototypes differ between `redisContext` and `redisAsyncContext`. + +#### redisContext +```c +void my_push_handler(void *privdata, void *reply) { + /* Handle the reply */ + + /* Note: We need to free the reply in our custom handler for + blocking contexts. This lets us keep the reply if + we want. */ + freeReplyObject(reply); +} +``` + +#### redisAsyncContext +```c +void my_async_push_handler(redisAsyncContext *ac, void *reply) { + /* Handle the reply */ + + /* Note: Because async hiredis always frees replies, you should + not call freeReplyObject in an async push callback. */ +} +``` + +### Installing a custom handler +There are two ways to set your own PUSH handlers. + +1. Set `push_cb` or `async_push_cb` in the `redisOptions` struct and connect with `redisConnectWithOptions` or `redisAsyncConnectWithOptions`. + ```c + redisOptions = {0}; + REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); + options->push_cb = my_push_handler; + redisContext *context = redisConnectWithOptions(&options); + ``` +2. Call `redisSetPushCallback` or `redisAsyncSetPushCallback` on a connected context. + ```c + redisContext *context = redisConnect("127.0.0.1", 6379); + redisSetPushCallback(context, my_push_handler); + ``` + + _Note `redisSetPushCallback` and `redisAsyncSetPushCallback` both return any currently configured handler, making it easy to override and then return to the old value._ + +### Specifying no handler +If you have a unique use-case where you don't want hiredis to automatically intercept and free PUSH replies, you will want to configure no handler at all. This can be done in two ways. +1. Set the `REDIS_OPT_NO_PUSH_AUTOFREE` flag in `redisOptions` and leave the callback function pointer `NULL`. + ```c + redisOptions = {0}; + REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); + options->options |= REDIS_OPT_NO_PUSH_AUTOFREE; + redisContext *context = redisConnectWithOptions(&options); + ``` +3. Call `redisSetPushCallback` with `NULL` once connected. + ```c + redisContext *context = redisConnect("127.0.0.1", 6379); + redisSetPushCallback(context, NULL); + ``` + + _Note: With no handler configured, calls to `redisCommand` may generate more than one reply, so this strategy is only applicable when there's some kind of blocking`redisGetReply()` loop (e.g. `MONITOR` or `SUBSCRIBE` workloads)._ + +## Allocator injection + +Hiredis uses a pass-thru structure of function pointers defined in [alloc.h](https://github.com/redis/hiredis/blob/f5d25850/alloc.h#L41) that contain the currently configured allocation and deallocation functions. By default they just point to libc (`malloc`, `calloc`, `realloc`, etc). + +### Overriding + +One can override the allocators like so: + +```c +hiredisAllocFuncs myfuncs = { + .mallocFn = my_malloc, + .callocFn = my_calloc, + .reallocFn = my_realloc, + .strdupFn = my_strdup, + .freeFn = my_free, +}; + +// Override allocators (function returns current allocators if needed) +hiredisAllocFuncs orig = hiredisSetAllocators(&myfuncs); +``` + +To reset the allocators to their default libc function simply call: + +```c +hiredisResetAllocators(); +``` + +## AUTHORS + +Salvatore Sanfilippo (antirez at gmail),\ +Pieter Noordhuis (pcnoordhuis at gmail)\ +Michael Grunder (michael dot grunder at gmail) + +_Hiredis is released under the BSD license._ diff --git a/ext/hiredis-1.0.2/adapters/ae.h b/ext/hiredis-1.0.2/adapters/ae.h new file mode 100644 index 0000000..660d82e --- /dev/null +++ b/ext/hiredis-1.0.2/adapters/ae.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_AE_H__ +#define __HIREDIS_AE_H__ +#include +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisAeEvents { + redisAsyncContext *context; + aeEventLoop *loop; + int fd; + int reading, writing; +} redisAeEvents; + +static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { + ((void)el); ((void)fd); ((void)mask); + + redisAeEvents *e = (redisAeEvents*)privdata; + redisAsyncHandleRead(e->context); +} + +static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { + ((void)el); ((void)fd); ((void)mask); + + redisAeEvents *e = (redisAeEvents*)privdata; + redisAsyncHandleWrite(e->context); +} + +static void redisAeAddRead(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (!e->reading) { + e->reading = 1; + aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); + } +} + +static void redisAeDelRead(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (e->reading) { + e->reading = 0; + aeDeleteFileEvent(loop,e->fd,AE_READABLE); + } +} + +static void redisAeAddWrite(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (!e->writing) { + e->writing = 1; + aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e); + } +} + +static void redisAeDelWrite(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (e->writing) { + e->writing = 0; + aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); + } +} + +static void redisAeCleanup(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + redisAeDelRead(privdata); + redisAeDelWrite(privdata); + hi_free(e); +} + +static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisAeEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisAeEvents*)hi_malloc(sizeof(*e)); + if (e == NULL) + return REDIS_ERR; + + e->context = ac; + e->loop = loop; + e->fd = c->fd; + e->reading = e->writing = 0; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisAeAddRead; + ac->ev.delRead = redisAeDelRead; + ac->ev.addWrite = redisAeAddWrite; + ac->ev.delWrite = redisAeDelWrite; + ac->ev.cleanup = redisAeCleanup; + ac->ev.data = e; + + return REDIS_OK; +} +#endif diff --git a/ext/hiredis-1.0.2/adapters/glib.h b/ext/hiredis-1.0.2/adapters/glib.h new file mode 100644 index 0000000..ad59dd1 --- /dev/null +++ b/ext/hiredis-1.0.2/adapters/glib.h @@ -0,0 +1,156 @@ +#ifndef __HIREDIS_GLIB_H__ +#define __HIREDIS_GLIB_H__ + +#include + +#include "../hiredis.h" +#include "../async.h" + +typedef struct +{ + GSource source; + redisAsyncContext *ac; + GPollFD poll_fd; +} RedisSource; + +static void +redis_source_add_read (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events |= G_IO_IN; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_del_read (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events &= ~G_IO_IN; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_add_write (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events |= G_IO_OUT; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_del_write (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events &= ~G_IO_OUT; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_cleanup (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + + g_return_if_fail(source); + + redis_source_del_read(source); + redis_source_del_write(source); + /* + * It is not our responsibility to remove ourself from the + * current main loop. However, we will remove the GPollFD. + */ + if (source->poll_fd.fd >= 0) { + g_source_remove_poll((GSource *)data, &source->poll_fd); + source->poll_fd.fd = -1; + } +} + +static gboolean +redis_source_prepare (GSource *source, + gint *timeout_) +{ + RedisSource *redis = (RedisSource *)source; + *timeout_ = -1; + return !!(redis->poll_fd.events & redis->poll_fd.revents); +} + +static gboolean +redis_source_check (GSource *source) +{ + RedisSource *redis = (RedisSource *)source; + return !!(redis->poll_fd.events & redis->poll_fd.revents); +} + +static gboolean +redis_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + RedisSource *redis = (RedisSource *)source; + + if ((redis->poll_fd.revents & G_IO_OUT)) { + redisAsyncHandleWrite(redis->ac); + redis->poll_fd.revents &= ~G_IO_OUT; + } + + if ((redis->poll_fd.revents & G_IO_IN)) { + redisAsyncHandleRead(redis->ac); + redis->poll_fd.revents &= ~G_IO_IN; + } + + if (callback) { + return callback(user_data); + } + + return TRUE; +} + +static void +redis_source_finalize (GSource *source) +{ + RedisSource *redis = (RedisSource *)source; + + if (redis->poll_fd.fd >= 0) { + g_source_remove_poll(source, &redis->poll_fd); + redis->poll_fd.fd = -1; + } +} + +static GSource * +redis_source_new (redisAsyncContext *ac) +{ + static GSourceFuncs source_funcs = { + .prepare = redis_source_prepare, + .check = redis_source_check, + .dispatch = redis_source_dispatch, + .finalize = redis_source_finalize, + }; + redisContext *c = &ac->c; + RedisSource *source; + + g_return_val_if_fail(ac != NULL, NULL); + + source = (RedisSource *)g_source_new(&source_funcs, sizeof *source); + if (source == NULL) + return NULL; + + source->ac = ac; + source->poll_fd.fd = c->fd; + source->poll_fd.events = 0; + source->poll_fd.revents = 0; + g_source_add_poll((GSource *)source, &source->poll_fd); + + ac->ev.addRead = redis_source_add_read; + ac->ev.delRead = redis_source_del_read; + ac->ev.addWrite = redis_source_add_write; + ac->ev.delWrite = redis_source_del_write; + ac->ev.cleanup = redis_source_cleanup; + ac->ev.data = source; + + return (GSource *)source; +} + +#endif /* __HIREDIS_GLIB_H__ */ diff --git a/ext/hiredis-1.0.2/adapters/ivykis.h b/ext/hiredis-1.0.2/adapters/ivykis.h new file mode 100644 index 0000000..179f6ab --- /dev/null +++ b/ext/hiredis-1.0.2/adapters/ivykis.h @@ -0,0 +1,84 @@ +#ifndef __HIREDIS_IVYKIS_H__ +#define __HIREDIS_IVYKIS_H__ +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisIvykisEvents { + redisAsyncContext *context; + struct iv_fd fd; +} redisIvykisEvents; + +static void redisIvykisReadEvent(void *arg) { + redisAsyncContext *context = (redisAsyncContext *)arg; + redisAsyncHandleRead(context); +} + +static void redisIvykisWriteEvent(void *arg) { + redisAsyncContext *context = (redisAsyncContext *)arg; + redisAsyncHandleWrite(context); +} + +static void redisIvykisAddRead(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent); +} + +static void redisIvykisDelRead(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_in(&e->fd, NULL); +} + +static void redisIvykisAddWrite(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent); +} + +static void redisIvykisDelWrite(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_out(&e->fd, NULL); +} + +static void redisIvykisCleanup(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + + iv_fd_unregister(&e->fd); + hi_free(e); +} + +static int redisIvykisAttach(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisIvykisEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisIvykisEvents*)hi_malloc(sizeof(*e)); + if (e == NULL) + return REDIS_ERR; + + e->context = ac; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisIvykisAddRead; + ac->ev.delRead = redisIvykisDelRead; + ac->ev.addWrite = redisIvykisAddWrite; + ac->ev.delWrite = redisIvykisDelWrite; + ac->ev.cleanup = redisIvykisCleanup; + ac->ev.data = e; + + /* Initialize and install read/write events */ + IV_FD_INIT(&e->fd); + e->fd.fd = c->fd; + e->fd.handler_in = redisIvykisReadEvent; + e->fd.handler_out = redisIvykisWriteEvent; + e->fd.handler_err = NULL; + e->fd.cookie = e->context; + + iv_fd_register(&e->fd); + + return REDIS_OK; +} +#endif diff --git a/ext/hiredis-1.0.2/adapters/libev.h b/ext/hiredis-1.0.2/adapters/libev.h new file mode 100644 index 0000000..e1e7bbd --- /dev/null +++ b/ext/hiredis-1.0.2/adapters/libev.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_LIBEV_H__ +#define __HIREDIS_LIBEV_H__ +#include +#include +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisLibevEvents { + redisAsyncContext *context; + struct ev_loop *loop; + int reading, writing; + ev_io rev, wev; + ev_timer timer; +} redisLibevEvents; + +static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { +#if EV_MULTIPLICITY + ((void)loop); +#endif + ((void)revents); + + redisLibevEvents *e = (redisLibevEvents*)watcher->data; + redisAsyncHandleRead(e->context); +} + +static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { +#if EV_MULTIPLICITY + ((void)loop); +#endif + ((void)revents); + + redisLibevEvents *e = (redisLibevEvents*)watcher->data; + redisAsyncHandleWrite(e->context); +} + +static void redisLibevAddRead(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (!e->reading) { + e->reading = 1; + ev_io_start(EV_A_ &e->rev); + } +} + +static void redisLibevDelRead(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (e->reading) { + e->reading = 0; + ev_io_stop(EV_A_ &e->rev); + } +} + +static void redisLibevAddWrite(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (!e->writing) { + e->writing = 1; + ev_io_start(EV_A_ &e->wev); + } +} + +static void redisLibevDelWrite(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (e->writing) { + e->writing = 0; + ev_io_stop(EV_A_ &e->wev); + } +} + +static void redisLibevStopTimer(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + ev_timer_stop(EV_A_ &e->timer); +} + +static void redisLibevCleanup(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + redisLibevDelRead(privdata); + redisLibevDelWrite(privdata); + redisLibevStopTimer(privdata); + hi_free(e); +} + +static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) { + ((void)revents); + redisLibevEvents *e = (redisLibevEvents*)timer->data; + redisAsyncHandleTimeout(e->context); +} + +static void redisLibevSetTimeout(void *privdata, struct timeval tv) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + + if (!ev_is_active(&e->timer)) { + ev_init(&e->timer, redisLibevTimeout); + e->timer.data = e; + } + + e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00; + ev_timer_again(EV_A_ &e->timer); +} + +static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisLibevEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisLibevEvents*)hi_calloc(1, sizeof(*e)); + if (e == NULL) + return REDIS_ERR; + + e->context = ac; +#if EV_MULTIPLICITY + e->loop = loop; +#else + e->loop = NULL; +#endif + e->rev.data = e; + e->wev.data = e; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisLibevAddRead; + ac->ev.delRead = redisLibevDelRead; + ac->ev.addWrite = redisLibevAddWrite; + ac->ev.delWrite = redisLibevDelWrite; + ac->ev.cleanup = redisLibevCleanup; + ac->ev.scheduleTimer = redisLibevSetTimeout; + ac->ev.data = e; + + /* Initialize read/write events */ + ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); + ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); + return REDIS_OK; +} + +#endif diff --git a/ext/hiredis-1.0.2/adapters/libevent.h b/ext/hiredis-1.0.2/adapters/libevent.h new file mode 100644 index 0000000..9150979 --- /dev/null +++ b/ext/hiredis-1.0.2/adapters/libevent.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_LIBEVENT_H__ +#define __HIREDIS_LIBEVENT_H__ +#include +#include "../hiredis.h" +#include "../async.h" + +#define REDIS_LIBEVENT_DELETED 0x01 +#define REDIS_LIBEVENT_ENTERED 0x02 + +typedef struct redisLibeventEvents { + redisAsyncContext *context; + struct event *ev; + struct event_base *base; + struct timeval tv; + short flags; + short state; +} redisLibeventEvents; + +static void redisLibeventDestroy(redisLibeventEvents *e) { + hi_free(e); +} + +static void redisLibeventHandler(int fd, short event, void *arg) { + ((void)fd); + redisLibeventEvents *e = (redisLibeventEvents*)arg; + e->state |= REDIS_LIBEVENT_ENTERED; + + #define CHECK_DELETED() if (e->state & REDIS_LIBEVENT_DELETED) {\ + redisLibeventDestroy(e);\ + return; \ + } + + if ((event & EV_TIMEOUT) && (e->state & REDIS_LIBEVENT_DELETED) == 0) { + redisAsyncHandleTimeout(e->context); + CHECK_DELETED(); + } + + if ((event & EV_READ) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { + redisAsyncHandleRead(e->context); + CHECK_DELETED(); + } + + if ((event & EV_WRITE) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { + redisAsyncHandleWrite(e->context); + CHECK_DELETED(); + } + + e->state &= ~REDIS_LIBEVENT_ENTERED; + #undef CHECK_DELETED +} + +static void redisLibeventUpdate(void *privdata, short flag, int isRemove) { + redisLibeventEvents *e = (redisLibeventEvents *)privdata; + const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL; + + if (isRemove) { + if ((e->flags & flag) == 0) { + return; + } else { + e->flags &= ~flag; + } + } else { + if (e->flags & flag) { + return; + } else { + e->flags |= flag; + } + } + + event_del(e->ev); + event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST, + redisLibeventHandler, privdata); + event_add(e->ev, tv); +} + +static void redisLibeventAddRead(void *privdata) { + redisLibeventUpdate(privdata, EV_READ, 0); +} + +static void redisLibeventDelRead(void *privdata) { + redisLibeventUpdate(privdata, EV_READ, 1); +} + +static void redisLibeventAddWrite(void *privdata) { + redisLibeventUpdate(privdata, EV_WRITE, 0); +} + +static void redisLibeventDelWrite(void *privdata) { + redisLibeventUpdate(privdata, EV_WRITE, 1); +} + +static void redisLibeventCleanup(void *privdata) { + redisLibeventEvents *e = (redisLibeventEvents*)privdata; + if (!e) { + return; + } + event_del(e->ev); + event_free(e->ev); + e->ev = NULL; + + if (e->state & REDIS_LIBEVENT_ENTERED) { + e->state |= REDIS_LIBEVENT_DELETED; + } else { + redisLibeventDestroy(e); + } +} + +static void redisLibeventSetTimeout(void *privdata, struct timeval tv) { + redisLibeventEvents *e = (redisLibeventEvents *)privdata; + short flags = e->flags; + e->flags = 0; + e->tv = tv; + redisLibeventUpdate(e, flags, 0); +} + +static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) { + redisContext *c = &(ac->c); + redisLibeventEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e)); + if (e == NULL) + return REDIS_ERR; + + e->context = ac; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisLibeventAddRead; + ac->ev.delRead = redisLibeventDelRead; + ac->ev.addWrite = redisLibeventAddWrite; + ac->ev.delWrite = redisLibeventDelWrite; + ac->ev.cleanup = redisLibeventCleanup; + ac->ev.scheduleTimer = redisLibeventSetTimeout; + ac->ev.data = e; + + /* Initialize and install read/write events */ + e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, redisLibeventHandler, e); + e->base = base; + return REDIS_OK; +} +#endif diff --git a/ext/hiredis-1.0.2/adapters/libuv.h b/ext/hiredis-1.0.2/adapters/libuv.h new file mode 100644 index 0000000..c120b1b --- /dev/null +++ b/ext/hiredis-1.0.2/adapters/libuv.h @@ -0,0 +1,117 @@ +#ifndef __HIREDIS_LIBUV_H__ +#define __HIREDIS_LIBUV_H__ +#include +#include +#include "../hiredis.h" +#include "../async.h" +#include + +typedef struct redisLibuvEvents { + redisAsyncContext* context; + uv_poll_t handle; + int events; +} redisLibuvEvents; + + +static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { + redisLibuvEvents* p = (redisLibuvEvents*)handle->data; + int ev = (status ? p->events : events); + + if (p->context != NULL && (ev & UV_READABLE)) { + redisAsyncHandleRead(p->context); + } + if (p->context != NULL && (ev & UV_WRITABLE)) { + redisAsyncHandleWrite(p->context); + } +} + + +static void redisLibuvAddRead(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events |= UV_READABLE; + + uv_poll_start(&p->handle, p->events, redisLibuvPoll); +} + + +static void redisLibuvDelRead(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events &= ~UV_READABLE; + + if (p->events) { + uv_poll_start(&p->handle, p->events, redisLibuvPoll); + } else { + uv_poll_stop(&p->handle); + } +} + + +static void redisLibuvAddWrite(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events |= UV_WRITABLE; + + uv_poll_start(&p->handle, p->events, redisLibuvPoll); +} + + +static void redisLibuvDelWrite(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events &= ~UV_WRITABLE; + + if (p->events) { + uv_poll_start(&p->handle, p->events, redisLibuvPoll); + } else { + uv_poll_stop(&p->handle); + } +} + + +static void on_close(uv_handle_t* handle) { + redisLibuvEvents* p = (redisLibuvEvents*)handle->data; + + hi_free(p); +} + + +static void redisLibuvCleanup(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->context = NULL; // indicate that context might no longer exist + uv_close((uv_handle_t*)&p->handle, on_close); +} + + +static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { + redisContext *c = &(ac->c); + + if (ac->ev.data != NULL) { + return REDIS_ERR; + } + + ac->ev.addRead = redisLibuvAddRead; + ac->ev.delRead = redisLibuvDelRead; + ac->ev.addWrite = redisLibuvAddWrite; + ac->ev.delWrite = redisLibuvDelWrite; + ac->ev.cleanup = redisLibuvCleanup; + + redisLibuvEvents* p = (redisLibuvEvents*)hi_malloc(sizeof(*p)); + if (p == NULL) + return REDIS_ERR; + + memset(p, 0, sizeof(*p)); + + if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) { + return REDIS_ERR; + } + + ac->ev.data = p; + p->handle.data = p; + p->context = ac; + + return REDIS_OK; +} +#endif diff --git a/ext/hiredis-1.0.2/adapters/macosx.h b/ext/hiredis-1.0.2/adapters/macosx.h new file mode 100644 index 0000000..3c87f1b --- /dev/null +++ b/ext/hiredis-1.0.2/adapters/macosx.h @@ -0,0 +1,115 @@ +// +// Created by Дмитрий Бахвалов on 13.07.15. +// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. +// + +#ifndef __HIREDIS_MACOSX_H__ +#define __HIREDIS_MACOSX_H__ + +#include + +#include "../hiredis.h" +#include "../async.h" + +typedef struct { + redisAsyncContext *context; + CFSocketRef socketRef; + CFRunLoopSourceRef sourceRef; +} RedisRunLoop; + +static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) { + if( redisRunLoop != NULL ) { + if( redisRunLoop->sourceRef != NULL ) { + CFRunLoopSourceInvalidate(redisRunLoop->sourceRef); + CFRelease(redisRunLoop->sourceRef); + } + if( redisRunLoop->socketRef != NULL ) { + CFSocketInvalidate(redisRunLoop->socketRef); + CFRelease(redisRunLoop->socketRef); + } + hi_free(redisRunLoop); + } + return REDIS_ERR; +} + +static void redisMacOSAddRead(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); +} + +static void redisMacOSDelRead(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); +} + +static void redisMacOSAddWrite(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); +} + +static void redisMacOSDelWrite(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); +} + +static void redisMacOSCleanup(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + freeRedisRunLoop(redisRunLoop); +} + +static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) { + redisAsyncContext* context = (redisAsyncContext*) info; + + switch (callbackType) { + case kCFSocketReadCallBack: + redisAsyncHandleRead(context); + break; + + case kCFSocketWriteCallBack: + redisAsyncHandleWrite(context); + break; + + default: + break; + } +} + +static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) { + redisContext *redisCtx = &(redisAsyncCtx->c); + + /* Nothing should be attached when something is already attached */ + if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR; + + RedisRunLoop* redisRunLoop = (RedisRunLoop*) hi_calloc(1, sizeof(RedisRunLoop)); + if (redisRunLoop == NULL) + return REDIS_ERR; + + /* Setup redis stuff */ + redisRunLoop->context = redisAsyncCtx; + + redisAsyncCtx->ev.addRead = redisMacOSAddRead; + redisAsyncCtx->ev.delRead = redisMacOSDelRead; + redisAsyncCtx->ev.addWrite = redisMacOSAddWrite; + redisAsyncCtx->ev.delWrite = redisMacOSDelWrite; + redisAsyncCtx->ev.cleanup = redisMacOSCleanup; + redisAsyncCtx->ev.data = redisRunLoop; + + /* Initialize and install read/write events */ + CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL }; + + redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd, + kCFSocketReadCallBack | kCFSocketWriteCallBack, + redisMacOSAsyncCallback, + &socketCtx); + if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop); + + redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0); + if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop); + + CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode); + + return REDIS_OK; +} + +#endif + diff --git a/ext/hiredis-1.0.2/adapters/qt.h b/ext/hiredis-1.0.2/adapters/qt.h new file mode 100644 index 0000000..5cc02e6 --- /dev/null +++ b/ext/hiredis-1.0.2/adapters/qt.h @@ -0,0 +1,135 @@ +/*- + * Copyright (C) 2014 Pietro Cerutti + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __HIREDIS_QT_H__ +#define __HIREDIS_QT_H__ +#include +#include "../async.h" + +static void RedisQtAddRead(void *); +static void RedisQtDelRead(void *); +static void RedisQtAddWrite(void *); +static void RedisQtDelWrite(void *); +static void RedisQtCleanup(void *); + +class RedisQtAdapter : public QObject { + + Q_OBJECT + + friend + void RedisQtAddRead(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->addRead(); + } + + friend + void RedisQtDelRead(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->delRead(); + } + + friend + void RedisQtAddWrite(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->addWrite(); + } + + friend + void RedisQtDelWrite(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->delWrite(); + } + + friend + void RedisQtCleanup(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->cleanup(); + } + + public: + RedisQtAdapter(QObject * parent = 0) + : QObject(parent), m_ctx(0), m_read(0), m_write(0) { } + + ~RedisQtAdapter() { + if (m_ctx != 0) { + m_ctx->ev.data = NULL; + } + } + + int setContext(redisAsyncContext * ac) { + if (ac->ev.data != NULL) { + return REDIS_ERR; + } + m_ctx = ac; + m_ctx->ev.data = this; + m_ctx->ev.addRead = RedisQtAddRead; + m_ctx->ev.delRead = RedisQtDelRead; + m_ctx->ev.addWrite = RedisQtAddWrite; + m_ctx->ev.delWrite = RedisQtDelWrite; + m_ctx->ev.cleanup = RedisQtCleanup; + return REDIS_OK; + } + + private: + void addRead() { + if (m_read) return; + m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0); + connect(m_read, SIGNAL(activated(int)), this, SLOT(read())); + } + + void delRead() { + if (!m_read) return; + delete m_read; + m_read = 0; + } + + void addWrite() { + if (m_write) return; + m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0); + connect(m_write, SIGNAL(activated(int)), this, SLOT(write())); + } + + void delWrite() { + if (!m_write) return; + delete m_write; + m_write = 0; + } + + void cleanup() { + delRead(); + delWrite(); + } + + private slots: + void read() { redisAsyncHandleRead(m_ctx); } + void write() { redisAsyncHandleWrite(m_ctx); } + + private: + redisAsyncContext * m_ctx; + QSocketNotifier * m_read; + QSocketNotifier * m_write; +}; + +#endif /* !__HIREDIS_QT_H__ */ diff --git a/ext/hiredis-1.0.2/alloc.c b/ext/hiredis-1.0.2/alloc.c new file mode 100644 index 0000000..7fb6b35 --- /dev/null +++ b/ext/hiredis-1.0.2/alloc.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include "alloc.h" +#include +#include + +hiredisAllocFuncs hiredisAllocFns = { + .mallocFn = malloc, + .callocFn = calloc, + .reallocFn = realloc, + .strdupFn = strdup, + .freeFn = free, +}; + +/* Override hiredis' allocators with ones supplied by the user */ +hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *override) { + hiredisAllocFuncs orig = hiredisAllocFns; + + hiredisAllocFns = *override; + + return orig; +} + +/* Reset allocators to use libc defaults */ +void hiredisResetAllocators(void) { + hiredisAllocFns = (hiredisAllocFuncs) { + .mallocFn = malloc, + .callocFn = calloc, + .reallocFn = realloc, + .strdupFn = strdup, + .freeFn = free, + }; +} + +#ifdef _WIN32 + +void *hi_malloc(size_t size) { + return hiredisAllocFns.mallocFn(size); +} + +void *hi_calloc(size_t nmemb, size_t size) { + return hiredisAllocFns.callocFn(nmemb, size); +} + +void *hi_realloc(void *ptr, size_t size) { + return hiredisAllocFns.reallocFn(ptr, size); +} + +char *hi_strdup(const char *str) { + return hiredisAllocFns.strdupFn(str); +} + +void hi_free(void *ptr) { + hiredisAllocFns.freeFn(ptr); +} + +#endif diff --git a/ext/hiredis-1.0.2/alloc.h b/ext/hiredis-1.0.2/alloc.h new file mode 100644 index 0000000..34a05f4 --- /dev/null +++ b/ext/hiredis-1.0.2/alloc.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HIREDIS_ALLOC_H +#define HIREDIS_ALLOC_H + +#include /* for size_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure pointing to our actually configured allocators */ +typedef struct hiredisAllocFuncs { + void *(*mallocFn)(size_t); + void *(*callocFn)(size_t,size_t); + void *(*reallocFn)(void*,size_t); + char *(*strdupFn)(const char*); + void (*freeFn)(void*); +} hiredisAllocFuncs; + +hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *ha); +void hiredisResetAllocators(void); + +#ifndef _WIN32 + +/* Hiredis' configured allocator function pointer struct */ +extern hiredisAllocFuncs hiredisAllocFns; + +static inline void *hi_malloc(size_t size) { + return hiredisAllocFns.mallocFn(size); +} + +static inline void *hi_calloc(size_t nmemb, size_t size) { + return hiredisAllocFns.callocFn(nmemb, size); +} + +static inline void *hi_realloc(void *ptr, size_t size) { + return hiredisAllocFns.reallocFn(ptr, size); +} + +static inline char *hi_strdup(const char *str) { + return hiredisAllocFns.strdupFn(str); +} + +static inline void hi_free(void *ptr) { + hiredisAllocFns.freeFn(ptr); +} + +#else + +void *hi_malloc(size_t size); +void *hi_calloc(size_t nmemb, size_t size); +void *hi_realloc(void *ptr, size_t size); +char *hi_strdup(const char *str); +void hi_free(void *ptr); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* HIREDIS_ALLOC_H */ diff --git a/ext/hiredis-1.0.2/appveyor.yml b/ext/hiredis-1.0.2/appveyor.yml new file mode 100644 index 0000000..5b43fdb --- /dev/null +++ b/ext/hiredis-1.0.2/appveyor.yml @@ -0,0 +1,24 @@ +# Appveyor configuration file for CI build of hiredis on Windows (under Cygwin) +environment: + matrix: + - CYG_BASH: C:\cygwin64\bin\bash + CC: gcc + - CYG_BASH: C:\cygwin\bin\bash + CC: gcc + CFLAGS: -m32 + CXXFLAGS: -m32 + LDFLAGS: -m32 + +clone_depth: 1 + +# Attempt to ensure we don't try to convert line endings to Win32 CRLF as this will cause build to fail +init: + - git config --global core.autocrlf input + +# Install needed build dependencies +install: + - '%CYG_BASH% -lc "cygcheck -dc cygwin"' + +build_script: + - 'echo building...' + - '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0 + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include "alloc.h" +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include +#include +#include "async.h" +#include "net.h" +#include "dict.c" +#include "sds.h" +#include "win32.h" + +#include "async_private.h" + +/* Forward declarations of hiredis.c functions */ +int __redisAppendCommand(redisContext *c, const char *cmd, size_t len); +void __redisSetError(redisContext *c, int type, const char *str); + +/* Functions managing dictionary of callbacks for pub/sub. */ +static unsigned int callbackHash(const void *key) { + return dictGenHashFunction((const unsigned char *)key, + sdslen((const sds)key)); +} + +static void *callbackValDup(void *privdata, const void *src) { + ((void) privdata); + redisCallback *dup; + + dup = hi_malloc(sizeof(*dup)); + if (dup == NULL) + return NULL; + + memcpy(dup,src,sizeof(*dup)); + return dup; +} + +static int callbackKeyCompare(void *privdata, const void *key1, const void *key2) { + int l1, l2; + ((void) privdata); + + l1 = sdslen((const sds)key1); + l2 = sdslen((const sds)key2); + if (l1 != l2) return 0; + return memcmp(key1,key2,l1) == 0; +} + +static void callbackKeyDestructor(void *privdata, void *key) { + ((void) privdata); + sdsfree((sds)key); +} + +static void callbackValDestructor(void *privdata, void *val) { + ((void) privdata); + hi_free(val); +} + +static dictType callbackDict = { + callbackHash, + NULL, + callbackValDup, + callbackKeyCompare, + callbackKeyDestructor, + callbackValDestructor +}; + +static redisAsyncContext *redisAsyncInitialize(redisContext *c) { + redisAsyncContext *ac; + dict *channels = NULL, *patterns = NULL; + + channels = dictCreate(&callbackDict,NULL); + if (channels == NULL) + goto oom; + + patterns = dictCreate(&callbackDict,NULL); + if (patterns == NULL) + goto oom; + + ac = hi_realloc(c,sizeof(redisAsyncContext)); + if (ac == NULL) + goto oom; + + c = &(ac->c); + + /* The regular connect functions will always set the flag REDIS_CONNECTED. + * For the async API, we want to wait until the first write event is + * received up before setting this flag, so reset it here. */ + c->flags &= ~REDIS_CONNECTED; + + ac->err = 0; + ac->errstr = NULL; + ac->data = NULL; + ac->dataCleanup = NULL; + + ac->ev.data = NULL; + ac->ev.addRead = NULL; + ac->ev.delRead = NULL; + ac->ev.addWrite = NULL; + ac->ev.delWrite = NULL; + ac->ev.cleanup = NULL; + ac->ev.scheduleTimer = NULL; + + ac->onConnect = NULL; + ac->onDisconnect = NULL; + + ac->replies.head = NULL; + ac->replies.tail = NULL; + ac->sub.invalid.head = NULL; + ac->sub.invalid.tail = NULL; + ac->sub.channels = channels; + ac->sub.patterns = patterns; + + return ac; +oom: + if (channels) dictRelease(channels); + if (patterns) dictRelease(patterns); + return NULL; +} + +/* We want the error field to be accessible directly instead of requiring + * an indirection to the redisContext struct. */ +static void __redisAsyncCopyError(redisAsyncContext *ac) { + if (!ac) + return; + + redisContext *c = &(ac->c); + ac->err = c->err; + ac->errstr = c->errstr; +} + +redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options) { + redisOptions myOptions = *options; + redisContext *c; + redisAsyncContext *ac; + + /* Clear any erroneously set sync callback and flag that we don't want to + * use freeReplyObject by default. */ + myOptions.push_cb = NULL; + myOptions.options |= REDIS_OPT_NO_PUSH_AUTOFREE; + + myOptions.options |= REDIS_OPT_NONBLOCK; + c = redisConnectWithOptions(&myOptions); + if (c == NULL) { + return NULL; + } + + ac = redisAsyncInitialize(c); + if (ac == NULL) { + redisFree(c); + return NULL; + } + + /* Set any configured async push handler */ + redisAsyncSetPushCallback(ac, myOptions.async_push_cb); + + __redisAsyncCopyError(ac); + return ac; +} + +redisAsyncContext *redisAsyncConnect(const char *ip, int port) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + return redisAsyncConnectWithOptions(&options); +} + +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, + const char *source_addr) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.endpoint.tcp.source_addr = source_addr; + return redisAsyncConnectWithOptions(&options); +} + +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.options |= REDIS_OPT_REUSEADDR; + options.endpoint.tcp.source_addr = source_addr; + return redisAsyncConnectWithOptions(&options); +} + +redisAsyncContext *redisAsyncConnectUnix(const char *path) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_UNIX(&options, path); + return redisAsyncConnectWithOptions(&options); +} + +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) { + if (ac->onConnect == NULL) { + ac->onConnect = fn; + + /* The common way to detect an established connection is to wait for + * the first write event to be fired. This assumes the related event + * library functions are already set. */ + _EL_ADD_WRITE(ac); + return REDIS_OK; + } + return REDIS_ERR; +} + +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) { + if (ac->onDisconnect == NULL) { + ac->onDisconnect = fn; + return REDIS_OK; + } + return REDIS_ERR; +} + +/* Helper functions to push/shift callbacks */ +static int __redisPushCallback(redisCallbackList *list, redisCallback *source) { + redisCallback *cb; + + /* Copy callback from stack to heap */ + cb = hi_malloc(sizeof(*cb)); + if (cb == NULL) + return REDIS_ERR_OOM; + + if (source != NULL) { + memcpy(cb,source,sizeof(*cb)); + cb->next = NULL; + } + + /* Store callback in list */ + if (list->head == NULL) + list->head = cb; + if (list->tail != NULL) + list->tail->next = cb; + list->tail = cb; + return REDIS_OK; +} + +static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) { + redisCallback *cb = list->head; + if (cb != NULL) { + list->head = cb->next; + if (cb == list->tail) + list->tail = NULL; + + /* Copy callback from heap to stack */ + if (target != NULL) + memcpy(target,cb,sizeof(*cb)); + hi_free(cb); + return REDIS_OK; + } + return REDIS_ERR; +} + +static void __redisRunCallback(redisAsyncContext *ac, redisCallback *cb, redisReply *reply) { + redisContext *c = &(ac->c); + if (cb->fn != NULL) { + c->flags |= REDIS_IN_CALLBACK; + cb->fn(ac,reply,cb->privdata); + c->flags &= ~REDIS_IN_CALLBACK; + } +} + +static void __redisRunPushCallback(redisAsyncContext *ac, redisReply *reply) { + if (ac->push_cb != NULL) { + ac->c.flags |= REDIS_IN_CALLBACK; + ac->push_cb(ac, reply); + ac->c.flags &= ~REDIS_IN_CALLBACK; + } +} + +/* Helper function to free the context. */ +static void __redisAsyncFree(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisCallback cb; + dictIterator *it; + dictEntry *de; + + /* Execute pending callbacks with NULL reply. */ + while (__redisShiftCallback(&ac->replies,&cb) == REDIS_OK) + __redisRunCallback(ac,&cb,NULL); + + /* Execute callbacks for invalid commands */ + while (__redisShiftCallback(&ac->sub.invalid,&cb) == REDIS_OK) + __redisRunCallback(ac,&cb,NULL); + + /* Run subscription callbacks with NULL reply */ + if (ac->sub.channels) { + it = dictGetIterator(ac->sub.channels); + if (it != NULL) { + while ((de = dictNext(it)) != NULL) + __redisRunCallback(ac,dictGetEntryVal(de),NULL); + dictReleaseIterator(it); + } + + dictRelease(ac->sub.channels); + } + + if (ac->sub.patterns) { + it = dictGetIterator(ac->sub.patterns); + if (it != NULL) { + while ((de = dictNext(it)) != NULL) + __redisRunCallback(ac,dictGetEntryVal(de),NULL); + dictReleaseIterator(it); + } + + dictRelease(ac->sub.patterns); + } + + /* Signal event lib to clean up */ + _EL_CLEANUP(ac); + + /* Execute disconnect callback. When redisAsyncFree() initiated destroying + * this context, the status will always be REDIS_OK. */ + if (ac->onDisconnect && (c->flags & REDIS_CONNECTED)) { + if (c->flags & REDIS_FREEING) { + ac->onDisconnect(ac,REDIS_OK); + } else { + ac->onDisconnect(ac,(ac->err == 0) ? REDIS_OK : REDIS_ERR); + } + } + + if (ac->dataCleanup) { + ac->dataCleanup(ac->data); + } + + /* Cleanup self */ + redisFree(c); +} + +/* Free the async context. When this function is called from a callback, + * control needs to be returned to redisProcessCallbacks() before actual + * free'ing. To do so, a flag is set on the context which is picked up by + * redisProcessCallbacks(). Otherwise, the context is immediately free'd. */ +void redisAsyncFree(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + c->flags |= REDIS_FREEING; + if (!(c->flags & REDIS_IN_CALLBACK)) + __redisAsyncFree(ac); +} + +/* Helper function to make the disconnect happen and clean up. */ +void __redisAsyncDisconnect(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + /* Make sure error is accessible if there is any */ + __redisAsyncCopyError(ac); + + if (ac->err == 0) { + /* For clean disconnects, there should be no pending callbacks. */ + int ret = __redisShiftCallback(&ac->replies,NULL); + assert(ret == REDIS_ERR); + } else { + /* Disconnection is caused by an error, make sure that pending + * callbacks cannot call new commands. */ + c->flags |= REDIS_DISCONNECTING; + } + + /* cleanup event library on disconnect. + * this is safe to call multiple times */ + _EL_CLEANUP(ac); + + /* For non-clean disconnects, __redisAsyncFree() will execute pending + * callbacks with a NULL-reply. */ + if (!(c->flags & REDIS_NO_AUTO_FREE)) { + __redisAsyncFree(ac); + } +} + +/* Tries to do a clean disconnect from Redis, meaning it stops new commands + * from being issued, but tries to flush the output buffer and execute + * callbacks for all remaining replies. When this function is called from a + * callback, there might be more replies and we can safely defer disconnecting + * to redisProcessCallbacks(). Otherwise, we can only disconnect immediately + * when there are no pending callbacks. */ +void redisAsyncDisconnect(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + c->flags |= REDIS_DISCONNECTING; + + /** unset the auto-free flag here, because disconnect undoes this */ + c->flags &= ~REDIS_NO_AUTO_FREE; + if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL) + __redisAsyncDisconnect(ac); +} + +static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, redisCallback *dstcb) { + redisContext *c = &(ac->c); + dict *callbacks; + redisCallback *cb; + dictEntry *de; + int pvariant; + char *stype; + sds sname; + + /* Custom reply functions are not supported for pub/sub. This will fail + * very hard when they are used... */ + if (reply->type == REDIS_REPLY_ARRAY || reply->type == REDIS_REPLY_PUSH) { + assert(reply->elements >= 2); + assert(reply->element[0]->type == REDIS_REPLY_STRING); + stype = reply->element[0]->str; + pvariant = (tolower(stype[0]) == 'p') ? 1 : 0; + + if (pvariant) + callbacks = ac->sub.patterns; + else + callbacks = ac->sub.channels; + + /* Locate the right callback */ + assert(reply->element[1]->type == REDIS_REPLY_STRING); + sname = sdsnewlen(reply->element[1]->str,reply->element[1]->len); + if (sname == NULL) + goto oom; + + de = dictFind(callbacks,sname); + if (de != NULL) { + cb = dictGetEntryVal(de); + + /* If this is an subscribe reply decrease pending counter. */ + if (strcasecmp(stype+pvariant,"subscribe") == 0) { + cb->pending_subs -= 1; + } + + memcpy(dstcb,cb,sizeof(*dstcb)); + + /* If this is an unsubscribe message, remove it. */ + if (strcasecmp(stype+pvariant,"unsubscribe") == 0) { + if (cb->pending_subs == 0) + dictDelete(callbacks,sname); + + /* If this was the last unsubscribe message, revert to + * non-subscribe mode. */ + assert(reply->element[2]->type == REDIS_REPLY_INTEGER); + + /* Unset subscribed flag only when no pipelined pending subscribe. */ + if (reply->element[2]->integer == 0 + && dictSize(ac->sub.channels) == 0 + && dictSize(ac->sub.patterns) == 0) + c->flags &= ~REDIS_SUBSCRIBED; + } + } + sdsfree(sname); + } else { + /* Shift callback for invalid commands. */ + __redisShiftCallback(&ac->sub.invalid,dstcb); + } + return REDIS_OK; +oom: + __redisSetError(&(ac->c), REDIS_ERR_OOM, "Out of memory"); + return REDIS_ERR; +} + +#define redisIsSpontaneousPushReply(r) \ + (redisIsPushReply(r) && !redisIsSubscribeReply(r)) + +static int redisIsSubscribeReply(redisReply *reply) { + char *str; + size_t len, off; + + /* We will always have at least one string with the subscribe/message type */ + if (reply->elements < 1 || reply->element[0]->type != REDIS_REPLY_STRING || + reply->element[0]->len < sizeof("message") - 1) + { + return 0; + } + + /* Get the string/len moving past 'p' if needed */ + off = tolower(reply->element[0]->str[0]) == 'p'; + str = reply->element[0]->str + off; + len = reply->element[0]->len - off; + + return !strncasecmp(str, "subscribe", len) || + !strncasecmp(str, "message", len); + +} + +void redisProcessCallbacks(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisCallback cb = {NULL, NULL, 0, NULL}; + void *reply = NULL; + int status; + + while((status = redisGetReply(c,&reply)) == REDIS_OK) { + if (reply == NULL) { + /* When the connection is being disconnected and there are + * no more replies, this is the cue to really disconnect. */ + if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0 + && ac->replies.head == NULL) { + __redisAsyncDisconnect(ac); + return; + } + + /* If monitor mode, repush callback */ + if(c->flags & REDIS_MONITORING) { + __redisPushCallback(&ac->replies,&cb); + } + + /* When the connection is not being disconnected, simply stop + * trying to get replies and wait for the next loop tick. */ + break; + } + + /* Send any non-subscribe related PUSH messages to our PUSH handler + * while allowing subscribe related PUSH messages to pass through. + * This allows existing code to be backward compatible and work in + * either RESP2 or RESP3 mode. */ + if (redisIsSpontaneousPushReply(reply)) { + __redisRunPushCallback(ac, reply); + c->reader->fn->freeObject(reply); + continue; + } + + /* Even if the context is subscribed, pending regular + * callbacks will get a reply before pub/sub messages arrive. */ + if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) { + /* + * A spontaneous reply in a not-subscribed context can be the error + * reply that is sent when a new connection exceeds the maximum + * number of allowed connections on the server side. + * + * This is seen as an error instead of a regular reply because the + * server closes the connection after sending it. + * + * To prevent the error from being overwritten by an EOF error the + * connection is closed here. See issue #43. + * + * Another possibility is that the server is loading its dataset. + * In this case we also want to close the connection, and have the + * user wait until the server is ready to take our request. + */ + if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) { + c->err = REDIS_ERR_OTHER; + snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str); + c->reader->fn->freeObject(reply); + __redisAsyncDisconnect(ac); + return; + } + /* No more regular callbacks and no errors, the context *must* be subscribed or monitoring. */ + assert((c->flags & REDIS_SUBSCRIBED || c->flags & REDIS_MONITORING)); + if(c->flags & REDIS_SUBSCRIBED) + __redisGetSubscribeCallback(ac,reply,&cb); + } + + if (cb.fn != NULL) { + __redisRunCallback(ac,&cb,reply); + c->reader->fn->freeObject(reply); + + /* Proceed with free'ing when redisAsyncFree() was called. */ + if (c->flags & REDIS_FREEING) { + __redisAsyncFree(ac); + return; + } + } else { + /* No callback for this reply. This can either be a NULL callback, + * or there were no callbacks to begin with. Either way, don't + * abort with an error, but simply ignore it because the client + * doesn't know what the server will spit out over the wire. */ + c->reader->fn->freeObject(reply); + } + } + + /* Disconnect when there was an error reading the reply */ + if (status != REDIS_OK) + __redisAsyncDisconnect(ac); +} + +static void __redisAsyncHandleConnectFailure(redisAsyncContext *ac) { + if (ac->onConnect) ac->onConnect(ac, REDIS_ERR); + __redisAsyncDisconnect(ac); +} + +/* Internal helper function to detect socket status the first time a read or + * write event fires. When connecting was not successful, the connect callback + * is called with a REDIS_ERR status and the context is free'd. */ +static int __redisAsyncHandleConnect(redisAsyncContext *ac) { + int completed = 0; + redisContext *c = &(ac->c); + + if (redisCheckConnectDone(c, &completed) == REDIS_ERR) { + /* Error! */ + redisCheckSocketError(c); + __redisAsyncHandleConnectFailure(ac); + return REDIS_ERR; + } else if (completed == 1) { + /* connected! */ + if (c->connection_type == REDIS_CONN_TCP && + redisSetTcpNoDelay(c) == REDIS_ERR) { + __redisAsyncHandleConnectFailure(ac); + return REDIS_ERR; + } + + if (ac->onConnect) ac->onConnect(ac, REDIS_OK); + c->flags |= REDIS_CONNECTED; + return REDIS_OK; + } else { + return REDIS_OK; + } +} + +void redisAsyncRead(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + if (redisBufferRead(c) == REDIS_ERR) { + __redisAsyncDisconnect(ac); + } else { + /* Always re-schedule reads */ + _EL_ADD_READ(ac); + redisProcessCallbacks(ac); + } +} + +/* This function should be called when the socket is readable. + * It processes all replies that can be read and executes their callbacks. + */ +void redisAsyncHandleRead(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + if (!(c->flags & REDIS_CONNECTED)) { + /* Abort connect was not successful. */ + if (__redisAsyncHandleConnect(ac) != REDIS_OK) + return; + /* Try again later when the context is still not connected. */ + if (!(c->flags & REDIS_CONNECTED)) + return; + } + + c->funcs->async_read(ac); +} + +void redisAsyncWrite(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + int done = 0; + + if (redisBufferWrite(c,&done) == REDIS_ERR) { + __redisAsyncDisconnect(ac); + } else { + /* Continue writing when not done, stop writing otherwise */ + if (!done) + _EL_ADD_WRITE(ac); + else + _EL_DEL_WRITE(ac); + + /* Always schedule reads after writes */ + _EL_ADD_READ(ac); + } +} + +void redisAsyncHandleWrite(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + if (!(c->flags & REDIS_CONNECTED)) { + /* Abort connect was not successful. */ + if (__redisAsyncHandleConnect(ac) != REDIS_OK) + return; + /* Try again later when the context is still not connected. */ + if (!(c->flags & REDIS_CONNECTED)) + return; + } + + c->funcs->async_write(ac); +} + +void redisAsyncHandleTimeout(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisCallback cb; + + if ((c->flags & REDIS_CONNECTED) && ac->replies.head == NULL) { + /* Nothing to do - just an idle timeout */ + return; + } + + if (!c->err) { + __redisSetError(c, REDIS_ERR_TIMEOUT, "Timeout"); + } + + if (!(c->flags & REDIS_CONNECTED) && ac->onConnect) { + ac->onConnect(ac, REDIS_ERR); + } + + while (__redisShiftCallback(&ac->replies, &cb) == REDIS_OK) { + __redisRunCallback(ac, &cb, NULL); + } + + /** + * TODO: Don't automatically sever the connection, + * rather, allow to ignore responses before the queue is clear + */ + __redisAsyncDisconnect(ac); +} + +/* Sets a pointer to the first argument and its length starting at p. Returns + * the number of bytes to skip to get to the following argument. */ +static const char *nextArgument(const char *start, const char **str, size_t *len) { + const char *p = start; + if (p[0] != '$') { + p = strchr(p,'$'); + if (p == NULL) return NULL; + } + + *len = (int)strtol(p+1,NULL,10); + p = strchr(p,'\r'); + assert(p); + *str = p+2; + return p+2+(*len)+2; +} + +/* Helper function for the redisAsyncCommand* family of functions. Writes a + * formatted command to the output buffer and registers the provided callback + * function with the context. */ +static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { + redisContext *c = &(ac->c); + redisCallback cb; + struct dict *cbdict; + dictEntry *de; + redisCallback *existcb; + int pvariant, hasnext; + const char *cstr, *astr; + size_t clen, alen; + const char *p; + sds sname; + int ret; + + /* Don't accept new commands when the connection is about to be closed. */ + if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR; + + /* Setup callback */ + cb.fn = fn; + cb.privdata = privdata; + cb.pending_subs = 1; + + /* Find out which command will be appended. */ + p = nextArgument(cmd,&cstr,&clen); + assert(p != NULL); + hasnext = (p[0] == '$'); + pvariant = (tolower(cstr[0]) == 'p') ? 1 : 0; + cstr += pvariant; + clen -= pvariant; + + if (hasnext && strncasecmp(cstr,"subscribe\r\n",11) == 0) { + c->flags |= REDIS_SUBSCRIBED; + + /* Add every channel/pattern to the list of subscription callbacks. */ + while ((p = nextArgument(p,&astr,&alen)) != NULL) { + sname = sdsnewlen(astr,alen); + if (sname == NULL) + goto oom; + + if (pvariant) + cbdict = ac->sub.patterns; + else + cbdict = ac->sub.channels; + + de = dictFind(cbdict,sname); + + if (de != NULL) { + existcb = dictGetEntryVal(de); + cb.pending_subs = existcb->pending_subs + 1; + } + + ret = dictReplace(cbdict,sname,&cb); + + if (ret == 0) sdsfree(sname); + } + } else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) { + /* It is only useful to call (P)UNSUBSCRIBE when the context is + * subscribed to one or more channels or patterns. */ + if (!(c->flags & REDIS_SUBSCRIBED)) return REDIS_ERR; + + /* (P)UNSUBSCRIBE does not have its own response: every channel or + * pattern that is unsubscribed will receive a message. This means we + * should not append a callback function for this command. */ + } else if(strncasecmp(cstr,"monitor\r\n",9) == 0) { + /* Set monitor flag and push callback */ + c->flags |= REDIS_MONITORING; + __redisPushCallback(&ac->replies,&cb); + } else { + if (c->flags & REDIS_SUBSCRIBED) + /* This will likely result in an error reply, but it needs to be + * received and passed to the callback. */ + __redisPushCallback(&ac->sub.invalid,&cb); + else + __redisPushCallback(&ac->replies,&cb); + } + + __redisAppendCommand(c,cmd,len); + + /* Always schedule a write when the write buffer is non-empty */ + _EL_ADD_WRITE(ac); + + return REDIS_OK; +oom: + __redisSetError(&(ac->c), REDIS_ERR_OOM, "Out of memory"); + return REDIS_ERR; +} + +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap) { + char *cmd; + int len; + int status; + len = redisvFormatCommand(&cmd,format,ap); + + /* We don't want to pass -1 or -2 to future functions as a length. */ + if (len < 0) + return REDIS_ERR; + + status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + hi_free(cmd); + return status; +} + +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...) { + va_list ap; + int status; + va_start(ap,format); + status = redisvAsyncCommand(ac,fn,privdata,format,ap); + va_end(ap); + return status; +} + +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) { + sds cmd; + int len; + int status; + len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); + if (len < 0) + return REDIS_ERR; + status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + sdsfree(cmd); + return status; +} + +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { + int status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + return status; +} + +redisAsyncPushFn *redisAsyncSetPushCallback(redisAsyncContext *ac, redisAsyncPushFn *fn) { + redisAsyncPushFn *old = ac->push_cb; + ac->push_cb = fn; + return old; +} + +int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) { + if (!ac->c.command_timeout) { + ac->c.command_timeout = hi_calloc(1, sizeof(tv)); + if (ac->c.command_timeout == NULL) { + __redisSetError(&ac->c, REDIS_ERR_OOM, "Out of memory"); + __redisAsyncCopyError(ac); + return REDIS_ERR; + } + } + + if (tv.tv_sec != ac->c.command_timeout->tv_sec || + tv.tv_usec != ac->c.command_timeout->tv_usec) + { + *ac->c.command_timeout = tv; + } + + return REDIS_OK; +} diff --git a/ext/hiredis-1.0.2/async.h b/ext/hiredis-1.0.2/async.h new file mode 100644 index 0000000..b1d2cb2 --- /dev/null +++ b/ext/hiredis-1.0.2/async.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_ASYNC_H +#define __HIREDIS_ASYNC_H +#include "hiredis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ +struct dict; /* dictionary header is included in async.c */ + +/* Reply callback prototype and container */ +typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); +typedef struct redisCallback { + struct redisCallback *next; /* simple singly linked list */ + redisCallbackFn *fn; + int pending_subs; + void *privdata; +} redisCallback; + +/* List of callbacks for either regular replies or pub/sub */ +typedef struct redisCallbackList { + redisCallback *head, *tail; +} redisCallbackList; + +/* Connection callback prototypes */ +typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); +typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); +typedef void(redisTimerCallback)(void *timer, void *privdata); + +/* Context for an async connection to Redis */ +typedef struct redisAsyncContext { + /* Hold the regular context, so it can be realloc'ed. */ + redisContext c; + + /* Setup error flags so they can be used directly. */ + int err; + char *errstr; + + /* Not used by hiredis */ + void *data; + void (*dataCleanup)(void *privdata); + + /* Event library data and hooks */ + struct { + void *data; + + /* Hooks that are called when the library expects to start + * reading/writing. These functions should be idempotent. */ + void (*addRead)(void *privdata); + void (*delRead)(void *privdata); + void (*addWrite)(void *privdata); + void (*delWrite)(void *privdata); + void (*cleanup)(void *privdata); + void (*scheduleTimer)(void *privdata, struct timeval tv); + } ev; + + /* Called when either the connection is terminated due to an error or per + * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ + redisDisconnectCallback *onDisconnect; + + /* Called when the first write event was received. */ + redisConnectCallback *onConnect; + + /* Regular command callbacks */ + redisCallbackList replies; + + /* Address used for connect() */ + struct sockaddr *saddr; + size_t addrlen; + + /* Subscription callbacks */ + struct { + redisCallbackList invalid; + struct dict *channels; + struct dict *patterns; + } sub; + + /* Any configured RESP3 PUSH handler */ + redisAsyncPushFn *push_cb; +} redisAsyncContext; + +/* Functions that proxy to hiredis */ +redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options); +redisAsyncContext *redisAsyncConnect(const char *ip, int port); +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr); +redisAsyncContext *redisAsyncConnectUnix(const char *path); +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); + +redisAsyncPushFn *redisAsyncSetPushCallback(redisAsyncContext *ac, redisAsyncPushFn *fn); +int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv); +void redisAsyncDisconnect(redisAsyncContext *ac); +void redisAsyncFree(redisAsyncContext *ac); + +/* Handle read/write events */ +void redisAsyncHandleRead(redisAsyncContext *ac); +void redisAsyncHandleWrite(redisAsyncContext *ac); +void redisAsyncHandleTimeout(redisAsyncContext *ac); +void redisAsyncRead(redisAsyncContext *ac); +void redisAsyncWrite(redisAsyncContext *ac); + +/* Command functions for an async context. Write the command to the + * output buffer and register the provided callback. */ +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-1.0.2/async_private.h b/ext/hiredis-1.0.2/async_private.h new file mode 100644 index 0000000..b9d23ff --- /dev/null +++ b/ext/hiredis-1.0.2/async_private.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_ASYNC_PRIVATE_H +#define __HIREDIS_ASYNC_PRIVATE_H + +#define _EL_ADD_READ(ctx) \ + do { \ + refreshTimeout(ctx); \ + if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \ + } while (0) +#define _EL_DEL_READ(ctx) do { \ + if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \ + } while(0) +#define _EL_ADD_WRITE(ctx) \ + do { \ + refreshTimeout(ctx); \ + if ((ctx)->ev.addWrite) (ctx)->ev.addWrite((ctx)->ev.data); \ + } while (0) +#define _EL_DEL_WRITE(ctx) do { \ + if ((ctx)->ev.delWrite) (ctx)->ev.delWrite((ctx)->ev.data); \ + } while(0) +#define _EL_CLEANUP(ctx) do { \ + if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \ + ctx->ev.cleanup = NULL; \ + } while(0); + +static inline void refreshTimeout(redisAsyncContext *ctx) { + #define REDIS_TIMER_ISSET(tvp) \ + (tvp && ((tvp)->tv_sec || (tvp)->tv_usec)) + + #define REDIS_EL_TIMER(ac, tvp) \ + if ((ac)->ev.scheduleTimer && REDIS_TIMER_ISSET(tvp)) { \ + (ac)->ev.scheduleTimer((ac)->ev.data, *(tvp)); \ + } + + if (ctx->c.flags & REDIS_CONNECTED) { + REDIS_EL_TIMER(ctx, ctx->c.command_timeout); + } else { + REDIS_EL_TIMER(ctx, ctx->c.connect_timeout); + } +} + +void __redisAsyncDisconnect(redisAsyncContext *ac); +void redisProcessCallbacks(redisAsyncContext *ac); + +#endif /* __HIREDIS_ASYNC_PRIVATE_H */ diff --git a/ext/hiredis-1.0.2/dict.c b/ext/hiredis-1.0.2/dict.c new file mode 100644 index 0000000..34a33ea --- /dev/null +++ b/ext/hiredis-1.0.2/dict.c @@ -0,0 +1,352 @@ +/* Hash table implementation. + * + * This file implements in memory hash tables with insert/del/replace/find/ + * get-random-element operations. Hash tables will auto resize if needed + * tables of power of two in size are used, collisions are handled by + * chaining. See the source code for more information... :) + * + * Copyright (c) 2006-2010, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include "alloc.h" +#include +#include +#include +#include "dict.h" + +/* -------------------------- private prototypes ---------------------------- */ + +static int _dictExpandIfNeeded(dict *ht); +static unsigned long _dictNextPower(unsigned long size); +static int _dictKeyIndex(dict *ht, const void *key); +static int _dictInit(dict *ht, dictType *type, void *privDataPtr); + +/* -------------------------- hash functions -------------------------------- */ + +/* Generic hash function (a popular one from Bernstein). + * I tested a few and this was the best. */ +static unsigned int dictGenHashFunction(const unsigned char *buf, int len) { + unsigned int hash = 5381; + + while (len--) + hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */ + return hash; +} + +/* ----------------------------- API implementation ------------------------- */ + +/* Reset an hashtable already initialized with ht_init(). + * NOTE: This function should only called by ht_destroy(). */ +static void _dictReset(dict *ht) { + ht->table = NULL; + ht->size = 0; + ht->sizemask = 0; + ht->used = 0; +} + +/* Create a new hash table */ +static dict *dictCreate(dictType *type, void *privDataPtr) { + dict *ht = hi_malloc(sizeof(*ht)); + if (ht == NULL) + return NULL; + + _dictInit(ht,type,privDataPtr); + return ht; +} + +/* Initialize the hash table */ +static int _dictInit(dict *ht, dictType *type, void *privDataPtr) { + _dictReset(ht); + ht->type = type; + ht->privdata = privDataPtr; + return DICT_OK; +} + +/* Expand or create the hashtable */ +static int dictExpand(dict *ht, unsigned long size) { + dict n; /* the new hashtable */ + unsigned long realsize = _dictNextPower(size), i; + + /* the size is invalid if it is smaller than the number of + * elements already inside the hashtable */ + if (ht->used > size) + return DICT_ERR; + + _dictInit(&n, ht->type, ht->privdata); + n.size = realsize; + n.sizemask = realsize-1; + n.table = hi_calloc(realsize,sizeof(dictEntry*)); + if (n.table == NULL) + return DICT_ERR; + + /* Copy all the elements from the old to the new table: + * note that if the old hash table is empty ht->size is zero, + * so dictExpand just creates an hash table. */ + n.used = ht->used; + for (i = 0; i < ht->size && ht->used > 0; i++) { + dictEntry *he, *nextHe; + + if (ht->table[i] == NULL) continue; + + /* For each hash entry on this slot... */ + he = ht->table[i]; + while(he) { + unsigned int h; + + nextHe = he->next; + /* Get the new element index */ + h = dictHashKey(ht, he->key) & n.sizemask; + he->next = n.table[h]; + n.table[h] = he; + ht->used--; + /* Pass to the next element */ + he = nextHe; + } + } + assert(ht->used == 0); + hi_free(ht->table); + + /* Remap the new hashtable in the old */ + *ht = n; + return DICT_OK; +} + +/* Add an element to the target hash table */ +static int dictAdd(dict *ht, void *key, void *val) { + int index; + dictEntry *entry; + + /* Get the index of the new element, or -1 if + * the element already exists. */ + if ((index = _dictKeyIndex(ht, key)) == -1) + return DICT_ERR; + + /* Allocates the memory and stores key */ + entry = hi_malloc(sizeof(*entry)); + if (entry == NULL) + return DICT_ERR; + + entry->next = ht->table[index]; + ht->table[index] = entry; + + /* Set the hash entry fields. */ + dictSetHashKey(ht, entry, key); + dictSetHashVal(ht, entry, val); + ht->used++; + return DICT_OK; +} + +/* Add an element, discarding the old if the key already exists. + * Return 1 if the key was added from scratch, 0 if there was already an + * element with such key and dictReplace() just performed a value update + * operation. */ +static int dictReplace(dict *ht, void *key, void *val) { + dictEntry *entry, auxentry; + + /* Try to add the element. If the key + * does not exists dictAdd will succeed. */ + if (dictAdd(ht, key, val) == DICT_OK) + return 1; + /* It already exists, get the entry */ + entry = dictFind(ht, key); + if (entry == NULL) + return 0; + + /* Free the old value and set the new one */ + /* Set the new value and free the old one. Note that it is important + * to do that in this order, as the value may just be exactly the same + * as the previous one. In this context, think to reference counting, + * you want to increment (set), and then decrement (free), and not the + * reverse. */ + auxentry = *entry; + dictSetHashVal(ht, entry, val); + dictFreeEntryVal(ht, &auxentry); + return 0; +} + +/* Search and remove an element */ +static int dictDelete(dict *ht, const void *key) { + unsigned int h; + dictEntry *de, *prevde; + + if (ht->size == 0) + return DICT_ERR; + h = dictHashKey(ht, key) & ht->sizemask; + de = ht->table[h]; + + prevde = NULL; + while(de) { + if (dictCompareHashKeys(ht,key,de->key)) { + /* Unlink the element from the list */ + if (prevde) + prevde->next = de->next; + else + ht->table[h] = de->next; + + dictFreeEntryKey(ht,de); + dictFreeEntryVal(ht,de); + hi_free(de); + ht->used--; + return DICT_OK; + } + prevde = de; + de = de->next; + } + return DICT_ERR; /* not found */ +} + +/* Destroy an entire hash table */ +static int _dictClear(dict *ht) { + unsigned long i; + + /* Free all the elements */ + for (i = 0; i < ht->size && ht->used > 0; i++) { + dictEntry *he, *nextHe; + + if ((he = ht->table[i]) == NULL) continue; + while(he) { + nextHe = he->next; + dictFreeEntryKey(ht, he); + dictFreeEntryVal(ht, he); + hi_free(he); + ht->used--; + he = nextHe; + } + } + /* Free the table and the allocated cache structure */ + hi_free(ht->table); + /* Re-initialize the table */ + _dictReset(ht); + return DICT_OK; /* never fails */ +} + +/* Clear & Release the hash table */ +static void dictRelease(dict *ht) { + _dictClear(ht); + hi_free(ht); +} + +static dictEntry *dictFind(dict *ht, const void *key) { + dictEntry *he; + unsigned int h; + + if (ht->size == 0) return NULL; + h = dictHashKey(ht, key) & ht->sizemask; + he = ht->table[h]; + while(he) { + if (dictCompareHashKeys(ht, key, he->key)) + return he; + he = he->next; + } + return NULL; +} + +static dictIterator *dictGetIterator(dict *ht) { + dictIterator *iter = hi_malloc(sizeof(*iter)); + if (iter == NULL) + return NULL; + + iter->ht = ht; + iter->index = -1; + iter->entry = NULL; + iter->nextEntry = NULL; + return iter; +} + +static dictEntry *dictNext(dictIterator *iter) { + while (1) { + if (iter->entry == NULL) { + iter->index++; + if (iter->index >= + (signed)iter->ht->size) break; + iter->entry = iter->ht->table[iter->index]; + } else { + iter->entry = iter->nextEntry; + } + if (iter->entry) { + /* We need to save the 'next' here, the iterator user + * may delete the entry we are returning. */ + iter->nextEntry = iter->entry->next; + return iter->entry; + } + } + return NULL; +} + +static void dictReleaseIterator(dictIterator *iter) { + hi_free(iter); +} + +/* ------------------------- private functions ------------------------------ */ + +/* Expand the hash table if needed */ +static int _dictExpandIfNeeded(dict *ht) { + /* If the hash table is empty expand it to the initial size, + * if the table is "full" double its size. */ + if (ht->size == 0) + return dictExpand(ht, DICT_HT_INITIAL_SIZE); + if (ht->used == ht->size) + return dictExpand(ht, ht->size*2); + return DICT_OK; +} + +/* Our hash table capability is a power of two */ +static unsigned long _dictNextPower(unsigned long size) { + unsigned long i = DICT_HT_INITIAL_SIZE; + + if (size >= LONG_MAX) return LONG_MAX; + while(1) { + if (i >= size) + return i; + i *= 2; + } +} + +/* Returns the index of a free slot that can be populated with + * an hash entry for the given 'key'. + * If the key already exists, -1 is returned. */ +static int _dictKeyIndex(dict *ht, const void *key) { + unsigned int h; + dictEntry *he; + + /* Expand the hashtable if needed */ + if (_dictExpandIfNeeded(ht) == DICT_ERR) + return -1; + /* Compute the key hash value */ + h = dictHashKey(ht, key) & ht->sizemask; + /* Search if this slot does not already contain the given key */ + he = ht->table[h]; + while(he) { + if (dictCompareHashKeys(ht, key, he->key)) + return -1; + he = he->next; + } + return h; +} + diff --git a/ext/hiredis-1.0.2/dict.h b/ext/hiredis-1.0.2/dict.h new file mode 100644 index 0000000..95fcd28 --- /dev/null +++ b/ext/hiredis-1.0.2/dict.h @@ -0,0 +1,126 @@ +/* Hash table implementation. + * + * This file implements in memory hash tables with insert/del/replace/find/ + * get-random-element operations. Hash tables will auto resize if needed + * tables of power of two in size are used, collisions are handled by + * chaining. See the source code for more information... :) + * + * Copyright (c) 2006-2010, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DICT_H +#define __DICT_H + +#define DICT_OK 0 +#define DICT_ERR 1 + +/* Unused arguments generate annoying warnings... */ +#define DICT_NOTUSED(V) ((void) V) + +typedef struct dictEntry { + void *key; + void *val; + struct dictEntry *next; +} dictEntry; + +typedef struct dictType { + unsigned int (*hashFunction)(const void *key); + void *(*keyDup)(void *privdata, const void *key); + void *(*valDup)(void *privdata, const void *obj); + int (*keyCompare)(void *privdata, const void *key1, const void *key2); + void (*keyDestructor)(void *privdata, void *key); + void (*valDestructor)(void *privdata, void *obj); +} dictType; + +typedef struct dict { + dictEntry **table; + dictType *type; + unsigned long size; + unsigned long sizemask; + unsigned long used; + void *privdata; +} dict; + +typedef struct dictIterator { + dict *ht; + int index; + dictEntry *entry, *nextEntry; +} dictIterator; + +/* This is the initial size of every hash table */ +#define DICT_HT_INITIAL_SIZE 4 + +/* ------------------------------- Macros ------------------------------------*/ +#define dictFreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->val) + +#define dictSetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ + else \ + entry->val = (_val_); \ +} while(0) + +#define dictFreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define dictSetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ + else \ + entry->key = (_key_); \ +} while(0) + +#define dictCompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ + (key1) == (key2)) + +#define dictHashKey(ht, key) (ht)->type->hashFunction(key) + +#define dictGetEntryKey(he) ((he)->key) +#define dictGetEntryVal(he) ((he)->val) +#define dictSlots(ht) ((ht)->size) +#define dictSize(ht) ((ht)->used) + +/* API */ +static unsigned int dictGenHashFunction(const unsigned char *buf, int len); +static dict *dictCreate(dictType *type, void *privDataPtr); +static int dictExpand(dict *ht, unsigned long size); +static int dictAdd(dict *ht, void *key, void *val); +static int dictReplace(dict *ht, void *key, void *val); +static int dictDelete(dict *ht, const void *key); +static void dictRelease(dict *ht); +static dictEntry * dictFind(dict *ht, const void *key); +static dictIterator *dictGetIterator(dict *ht); +static dictEntry *dictNext(dictIterator *iter); +static void dictReleaseIterator(dictIterator *iter); + +#endif /* __DICT_H */ diff --git a/ext/hiredis-1.0.2/examples/CMakeLists.txt b/ext/hiredis-1.0.2/examples/CMakeLists.txt new file mode 100644 index 0000000..1d5bc56 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/CMakeLists.txt @@ -0,0 +1,49 @@ +INCLUDE(FindPkgConfig) +# Check for GLib + +PKG_CHECK_MODULES(GLIB2 glib-2.0) +if (GLIB2_FOUND) + INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) + LINK_DIRECTORIES(${GLIB2_LIBRARY_DIRS}) + ADD_EXECUTABLE(example-glib example-glib.c) + TARGET_LINK_LIBRARIES(example-glib hiredis ${GLIB2_LIBRARIES}) +ENDIF(GLIB2_FOUND) + +FIND_PATH(LIBEV ev.h + HINTS /usr/local /usr/opt/local + ENV LIBEV_INCLUDE_DIR) + +if (LIBEV) + # Just compile and link with libev + ADD_EXECUTABLE(example-libev example-libev.c) + TARGET_LINK_LIBRARIES(example-libev hiredis ev) +ENDIF() + +FIND_PATH(LIBEVENT event.h) +if (LIBEVENT) + ADD_EXECUTABLE(example-libevent example-libevent) + TARGET_LINK_LIBRARIES(example-libevent hiredis event) +ENDIF() + +FIND_PATH(LIBUV uv.h) +IF (LIBUV) + ADD_EXECUTABLE(example-libuv example-libuv.c) + TARGET_LINK_LIBRARIES(example-libuv hiredis uv) +ENDIF() + +IF (APPLE) + FIND_LIBRARY(CF CoreFoundation) + ADD_EXECUTABLE(example-macosx example-macosx.c) + TARGET_LINK_LIBRARIES(example-macosx hiredis ${CF}) +ENDIF() + +IF (ENABLE_SSL) + ADD_EXECUTABLE(example-ssl example-ssl.c) + TARGET_LINK_LIBRARIES(example-ssl hiredis hiredis_ssl) +ENDIF() + +ADD_EXECUTABLE(example example.c) +TARGET_LINK_LIBRARIES(example hiredis) + +ADD_EXECUTABLE(example-push example-push.c) +TARGET_LINK_LIBRARIES(example-push hiredis) diff --git a/ext/hiredis-1.0.2/examples/example-ae.c b/ext/hiredis-1.0.2/examples/example-ae.c new file mode 100644 index 0000000..8efa730 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-ae.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include + +#include +#include +#include + +/* Put event loop in the global scope, so it can be explicitly stopped */ +static aeEventLoop *loop; + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + aeStop(loop); + return; + } + + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + aeStop(loop); + return; + } + + printf("Disconnected...\n"); + aeStop(loop); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + loop = aeCreateEventLoop(64); + redisAeAttach(loop, c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + aeMain(loop); + return 0; +} + diff --git a/ext/hiredis-1.0.2/examples/example-glib.c b/ext/hiredis-1.0.2/examples/example-glib.c new file mode 100644 index 0000000..d6e10f8 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-glib.c @@ -0,0 +1,73 @@ +#include + +#include +#include +#include + +static GMainLoop *mainloop; + +static void +connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, + int status) +{ + if (status != REDIS_OK) { + g_printerr("Failed to connect: %s\n", ac->errstr); + g_main_loop_quit(mainloop); + } else { + g_printerr("Connected...\n"); + } +} + +static void +disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, + int status) +{ + if (status != REDIS_OK) { + g_error("Failed to disconnect: %s", ac->errstr); + } else { + g_printerr("Disconnected...\n"); + g_main_loop_quit(mainloop); + } +} + +static void +command_cb(redisAsyncContext *ac, + gpointer r, + gpointer user_data G_GNUC_UNUSED) +{ + redisReply *reply = r; + + if (reply) { + g_print("REPLY: %s\n", reply->str); + } + + redisAsyncDisconnect(ac); +} + +gint +main (gint argc G_GNUC_UNUSED, + gchar *argv[] G_GNUC_UNUSED) +{ + redisAsyncContext *ac; + GMainContext *context = NULL; + GSource *source; + + ac = redisAsyncConnect("127.0.0.1", 6379); + if (ac->err) { + g_printerr("%s\n", ac->errstr); + exit(EXIT_FAILURE); + } + + source = redis_source_new(ac); + mainloop = g_main_loop_new(context, FALSE); + g_source_attach(source, context); + + redisAsyncSetConnectCallback(ac, connect_cb); + redisAsyncSetDisconnectCallback(ac, disconnect_cb); + redisAsyncCommand(ac, command_cb, NULL, "SET key 1234"); + redisAsyncCommand(ac, command_cb, NULL, "GET key"); + + g_main_loop_run(mainloop); + + return EXIT_SUCCESS; +} diff --git a/ext/hiredis-1.0.2/examples/example-ivykis.c b/ext/hiredis-1.0.2/examples/example-ivykis.c new file mode 100644 index 0000000..f57dc38 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-ivykis.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + + iv_init(); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisIvykisAttach(c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + + iv_main(); + + iv_deinit(); + + return 0; +} diff --git a/ext/hiredis-1.0.2/examples/example-libev.c b/ext/hiredis-1.0.2/examples/example-libev.c new file mode 100644 index 0000000..ec47430 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-libev.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibevAttach(EV_DEFAULT_ c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + ev_loop(EV_DEFAULT_ 0); + return 0; +} diff --git a/ext/hiredis-1.0.2/examples/example-libevent-ssl.c b/ext/hiredis-1.0.2/examples/example-libevent-ssl.c new file mode 100644 index 0000000..7d99af1 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-libevent-ssl.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + + struct event_base *base = event_base_new(); + if (argc < 5) { + fprintf(stderr, + "Usage: %s [ca]\n", argv[0]); + exit(1); + } + + const char *value = argv[1]; + size_t nvalue = strlen(value); + + const char *hostname = argv[2]; + int port = atoi(argv[3]); + + const char *cert = argv[4]; + const char *certKey = argv[5]; + const char *caCert = argc > 5 ? argv[6] : NULL; + + redisSSLContext *ssl; + redisSSLContextError ssl_error; + + redisInitOpenSSL(); + + ssl = redisCreateSSLContext(caCert, NULL, + cert, certKey, NULL, &ssl_error); + if (!ssl) { + printf("Error: %s\n", redisSSLContextGetError(ssl_error)); + return 1; + } + + redisAsyncContext *c = redisAsyncConnect(hostname, port); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + if (redisInitiateSSLWithContext(&c->c, ssl) != REDIS_OK) { + printf("SSL Error!\n"); + exit(1); + } + + redisLibeventAttach(c,base); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", value, nvalue); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + event_base_dispatch(base); + + redisFreeSSLContext(ssl); + return 0; +} diff --git a/ext/hiredis-1.0.2/examples/example-libevent.c b/ext/hiredis-1.0.2/examples/example-libevent.c new file mode 100644 index 0000000..49bddd0 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-libevent.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) { + if (c->errstr) { + printf("errstr: %s\n", c->errstr); + } + return; + } + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + + struct event_base *base = event_base_new(); + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); + struct timeval tv = {0}; + tv.tv_sec = 1; + options.connect_timeout = &tv; + + + redisAsyncContext *c = redisAsyncConnectWithOptions(&options); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibeventAttach(c,base); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + event_base_dispatch(base); + return 0; +} diff --git a/ext/hiredis-1.0.2/examples/example-libuv.c b/ext/hiredis-1.0.2/examples/example-libuv.c new file mode 100644 index 0000000..cbde452 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-libuv.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + + uv_loop_t* loop = uv_default_loop(); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibuvAttach(c,loop); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} diff --git a/ext/hiredis-1.0.2/examples/example-macosx.c b/ext/hiredis-1.0.2/examples/example-macosx.c new file mode 100644 index 0000000..bc84ed5 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-macosx.c @@ -0,0 +1,66 @@ +// +// Created by Дмитрий Бахвалов on 13.07.15. +// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. +// + +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + CFRunLoopStop(CFRunLoopGetCurrent()); + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + CFRunLoopRef loop = CFRunLoopGetCurrent(); + if( !loop ) { + printf("Error: Cannot get current run loop\n"); + return 1; + } + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisMacOSAttach(c, loop); + + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + + CFRunLoopRun(); + + return 0; +} + diff --git a/ext/hiredis-1.0.2/examples/example-push.c b/ext/hiredis-1.0.2/examples/example-push.c new file mode 100644 index 0000000..2d4ab4d --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-push.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include + +#define KEY_COUNT 5 + +#define panicAbort(fmt, ...) \ + do { \ + fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__); \ + exit(-1); \ + } while (0) + +static void assertReplyAndFree(redisContext *context, redisReply *reply, int type) { + if (reply == NULL) + panicAbort("NULL reply from server (error: %s)", context->errstr); + + if (reply->type != type) { + if (reply->type == REDIS_REPLY_ERROR) + fprintf(stderr, "Redis Error: %s\n", reply->str); + + panicAbort("Expected reply type %d but got type %d", type, reply->type); + } + + freeReplyObject(reply); +} + +/* Switch to the RESP3 protocol and enable client tracking */ +static void enableClientTracking(redisContext *c) { + redisReply *reply = redisCommand(c, "HELLO 3"); + if (reply == NULL || c->err) { + panicAbort("NULL reply or server error (error: %s)", c->errstr); + } + + if (reply->type != REDIS_REPLY_MAP) { + fprintf(stderr, "Error: Can't send HELLO 3 command. Are you sure you're "); + fprintf(stderr, "connected to redis-server >= 6.0.0?\nRedis error: %s\n", + reply->type == REDIS_REPLY_ERROR ? reply->str : "(unknown)"); + exit(-1); + } + + freeReplyObject(reply); + + /* Enable client tracking */ + reply = redisCommand(c, "CLIENT TRACKING ON"); + assertReplyAndFree(c, reply, REDIS_REPLY_STATUS); +} + +void pushReplyHandler(void *privdata, void *r) { + redisReply *reply = r; + int *invalidations = privdata; + + /* Sanity check on the invalidation reply */ + if (reply->type != REDIS_REPLY_PUSH || reply->elements != 2 || + reply->element[1]->type != REDIS_REPLY_ARRAY || + reply->element[1]->element[0]->type != REDIS_REPLY_STRING) + { + panicAbort("%s", "Can't parse PUSH message!"); + } + + /* Increment our invalidation count */ + *invalidations += 1; + + printf("pushReplyHandler(): INVALIDATE '%s' (invalidation count: %d)\n", + reply->element[1]->element[0]->str, *invalidations); + + freeReplyObject(reply); +} + +/* We aren't actually freeing anything here, but it is included to show that we can + * have hiredis call our data destructor when freeing the context */ +void privdata_dtor(void *privdata) { + unsigned int *icount = privdata; + printf("privdata_dtor(): In context privdata dtor (invalidations: %u)\n", *icount); +} + +int main(int argc, char **argv) { + unsigned int j, invalidations = 0; + redisContext *c; + redisReply *reply; + + const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; + int port = (argc > 2) ? atoi(argv[2]) : 6379; + + redisOptions o = {0}; + REDIS_OPTIONS_SET_TCP(&o, hostname, port); + + /* Set our context privdata to the address of our invalidation counter. Each + * time our PUSH handler is called, hiredis will pass the privdata for context. + * + * This could also be done after we create the context like so: + * + * c->privdata = &invalidations; + * c->free_privdata = privdata_dtor; + */ + REDIS_OPTIONS_SET_PRIVDATA(&o, &invalidations, privdata_dtor); + + /* Set our custom PUSH message handler */ + o.push_cb = pushReplyHandler; + + c = redisConnectWithOptions(&o); + if (c == NULL || c->err) + panicAbort("Connection error: %s", c ? c->errstr : "OOM"); + + /* Enable RESP3 and turn on client tracking */ + enableClientTracking(c); + + /* Set some keys and then read them back. Once we do that, Redis will deliver + * invalidation push messages whenever the key is modified */ + for (j = 0; j < KEY_COUNT; j++) { + reply = redisCommand(c, "SET key:%d initial:%d", j, j); + assertReplyAndFree(c, reply, REDIS_REPLY_STATUS); + + reply = redisCommand(c, "GET key:%d", j); + assertReplyAndFree(c, reply, REDIS_REPLY_STRING); + } + + /* Trigger invalidation messages by updating keys we just read */ + for (j = 0; j < KEY_COUNT; j++) { + printf(" main(): SET key:%d update:%d\n", j, j); + reply = redisCommand(c, "SET key:%d update:%d", j, j); + assertReplyAndFree(c, reply, REDIS_REPLY_STATUS); + printf(" main(): SET REPLY OK\n"); + } + + printf("\nTotal detected invalidations: %d, expected: %d\n", invalidations, KEY_COUNT); + + /* PING server */ + redisFree(c); +} diff --git a/ext/hiredis-1.0.2/examples/example-qt.cpp b/ext/hiredis-1.0.2/examples/example-qt.cpp new file mode 100644 index 0000000..f524c3f --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-qt.cpp @@ -0,0 +1,46 @@ +#include +using namespace std; + +#include +#include + +#include "example-qt.h" + +void getCallback(redisAsyncContext *, void * r, void * privdata) { + + redisReply * reply = static_cast(r); + ExampleQt * ex = static_cast(privdata); + if (reply == nullptr || ex == nullptr) return; + + cout << "key: " << reply->str << endl; + + ex->finish(); +} + +void ExampleQt::run() { + + m_ctx = redisAsyncConnect("localhost", 6379); + + if (m_ctx->err) { + cerr << "Error: " << m_ctx->errstr << endl; + redisAsyncFree(m_ctx); + emit finished(); + } + + m_adapter.setContext(m_ctx); + + redisAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value); + redisAsyncCommand(m_ctx, getCallback, this, "GET key"); +} + +int main (int argc, char **argv) { + + QCoreApplication app(argc, argv); + + ExampleQt example(argv[argc-1]); + + QObject::connect(&example, SIGNAL(finished()), &app, SLOT(quit())); + QTimer::singleShot(0, &example, SLOT(run())); + + return app.exec(); +} diff --git a/ext/hiredis-1.0.2/examples/example-qt.h b/ext/hiredis-1.0.2/examples/example-qt.h new file mode 100644 index 0000000..374f476 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-qt.h @@ -0,0 +1,32 @@ +#ifndef __HIREDIS_EXAMPLE_QT_H +#define __HIREDIS_EXAMPLE_QT_H + +#include + +class ExampleQt : public QObject { + + Q_OBJECT + + public: + ExampleQt(const char * value, QObject * parent = 0) + : QObject(parent), m_value(value) {} + + signals: + void finished(); + + public slots: + void run(); + + private: + void finish() { emit finished(); } + + private: + const char * m_value; + redisAsyncContext * m_ctx; + RedisQtAdapter m_adapter; + + friend + void getCallback(redisAsyncContext *, void *, void *); +}; + +#endif /* !__HIREDIS_EXAMPLE_QT_H */ diff --git a/ext/hiredis-1.0.2/examples/example-ssl.c b/ext/hiredis-1.0.2/examples/example-ssl.c new file mode 100644 index 0000000..c754177 --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example-ssl.c @@ -0,0 +1,110 @@ +#include +#include +#include + +#include +#include +#include + +int main(int argc, char **argv) { + unsigned int j; + redisSSLContext *ssl; + redisSSLContextError ssl_error; + redisContext *c; + redisReply *reply; + if (argc < 4) { + printf("Usage: %s [ca]\n", argv[0]); + exit(1); + } + const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; + int port = atoi(argv[2]); + const char *cert = argv[3]; + const char *key = argv[4]; + const char *ca = argc > 4 ? argv[5] : NULL; + + redisInitOpenSSL(); + ssl = redisCreateSSLContext(ca, NULL, cert, key, NULL, &ssl_error); + if (!ssl) { + printf("SSL Context error: %s\n", + redisSSLContextGetError(ssl_error)); + exit(1); + } + + struct timeval tv = { 1, 500000 }; // 1.5 seconds + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, hostname, port); + options.connect_timeout = &tv; + c = redisConnectWithOptions(&options); + + if (c == NULL || c->err) { + if (c) { + printf("Connection error: %s\n", c->errstr); + redisFree(c); + } else { + printf("Connection error: can't allocate redis context\n"); + } + exit(1); + } + + if (redisInitiateSSLWithContext(c, ssl) != REDIS_OK) { + printf("Couldn't initialize SSL!\n"); + printf("Error: %s\n", c->errstr); + redisFree(c); + exit(1); + } + + /* PING server */ + reply = redisCommand(c,"PING"); + printf("PING: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key */ + reply = redisCommand(c,"SET %s %s", "foo", "hello world"); + printf("SET: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key using binary safe API */ + reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); + printf("SET (binary API): %s\n", reply->str); + freeReplyObject(reply); + + /* Try a GET and two INCR */ + reply = redisCommand(c,"GET foo"); + printf("GET foo: %s\n", reply->str); + freeReplyObject(reply); + + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + /* again ... */ + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + + /* Create a list of numbers, from 0 to 9 */ + reply = redisCommand(c,"DEL mylist"); + freeReplyObject(reply); + for (j = 0; j < 10; j++) { + char buf[64]; + + snprintf(buf,64,"%u",j); + reply = redisCommand(c,"LPUSH mylist element-%s", buf); + freeReplyObject(reply); + } + + /* Let's check what we have inside the list */ + reply = redisCommand(c,"LRANGE mylist 0 -1"); + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + printf("%u) %s\n", j, reply->element[j]->str); + } + } + freeReplyObject(reply); + + /* Disconnects and frees the context */ + redisFree(c); + + redisFreeSSLContext(ssl); + + return 0; +} diff --git a/ext/hiredis-1.0.2/examples/example.c b/ext/hiredis-1.0.2/examples/example.c new file mode 100644 index 0000000..15dacbd --- /dev/null +++ b/ext/hiredis-1.0.2/examples/example.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + unsigned int j, isunix = 0; + redisContext *c; + redisReply *reply; + const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; + + if (argc > 2) { + if (*argv[2] == 'u' || *argv[2] == 'U') { + isunix = 1; + /* in this case, host is the path to the unix socket */ + printf("Will connect to unix socket @%s\n", hostname); + } + } + + int port = (argc > 2) ? atoi(argv[2]) : 6379; + + struct timeval timeout = { 1, 500000 }; // 1.5 seconds + if (isunix) { + c = redisConnectUnixWithTimeout(hostname, timeout); + } else { + c = redisConnectWithTimeout(hostname, port, timeout); + } + if (c == NULL || c->err) { + if (c) { + printf("Connection error: %s\n", c->errstr); + redisFree(c); + } else { + printf("Connection error: can't allocate redis context\n"); + } + exit(1); + } + + /* PING server */ + reply = redisCommand(c,"PING"); + printf("PING: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key */ + reply = redisCommand(c,"SET %s %s", "foo", "hello world"); + printf("SET: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key using binary safe API */ + reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); + printf("SET (binary API): %s\n", reply->str); + freeReplyObject(reply); + + /* Try a GET and two INCR */ + reply = redisCommand(c,"GET foo"); + printf("GET foo: %s\n", reply->str); + freeReplyObject(reply); + + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + /* again ... */ + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + + /* Create a list of numbers, from 0 to 9 */ + reply = redisCommand(c,"DEL mylist"); + freeReplyObject(reply); + for (j = 0; j < 10; j++) { + char buf[64]; + + snprintf(buf,64,"%u",j); + reply = redisCommand(c,"LPUSH mylist element-%s", buf); + freeReplyObject(reply); + } + + /* Let's check what we have inside the list */ + reply = redisCommand(c,"LRANGE mylist 0 -1"); + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + printf("%u) %s\n", j, reply->element[j]->str); + } + } + freeReplyObject(reply); + + /* Disconnects and frees the context */ + redisFree(c); + + return 0; +} diff --git a/ext/hiredis-1.0.2/fmacros.h b/ext/hiredis-1.0.2/fmacros.h new file mode 100644 index 0000000..3227faa --- /dev/null +++ b/ext/hiredis-1.0.2/fmacros.h @@ -0,0 +1,12 @@ +#ifndef __HIREDIS_FMACRO_H +#define __HIREDIS_FMACRO_H + +#define _XOPEN_SOURCE 600 +#define _POSIX_C_SOURCE 200112L + +#if defined(__APPLE__) && defined(__MACH__) +/* Enable TCP_KEEPALIVE */ +#define _DARWIN_C_SOURCE +#endif + +#endif diff --git a/ext/hiredis-1.0.2/hiredis-config.cmake.in b/ext/hiredis-1.0.2/hiredis-config.cmake.in new file mode 100644 index 0000000..98851dc --- /dev/null +++ b/ext/hiredis-1.0.2/hiredis-config.cmake.in @@ -0,0 +1,13 @@ +@PACKAGE_INIT@ + +set_and_check(hiredis_INCLUDEDIR "@PACKAGE_INCLUDE_INSTALL_DIR@") + +IF (NOT TARGET hiredis::hiredis) + INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis-targets.cmake) +ENDIF() + +SET(hiredis_LIBRARIES hiredis::hiredis) +SET(hiredis_INCLUDE_DIRS ${hiredis_INCLUDEDIR}) + +check_required_components(hiredis) + diff --git a/ext/hiredis-1.0.2/hiredis.c b/ext/hiredis-1.0.2/hiredis.c new file mode 100644 index 0000000..ab0e398 --- /dev/null +++ b/ext/hiredis-1.0.2/hiredis.c @@ -0,0 +1,1174 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include +#include +#include +#include +#include + +#include "hiredis.h" +#include "net.h" +#include "sds.h" +#include "async.h" +#include "win32.h" + +extern int redisContextUpdateConnectTimeout(redisContext *c, const struct timeval *timeout); +extern int redisContextUpdateCommandTimeout(redisContext *c, const struct timeval *timeout); + +static redisContextFuncs redisContextDefaultFuncs = { + .free_privctx = NULL, + .async_read = redisAsyncRead, + .async_write = redisAsyncWrite, + .read = redisNetRead, + .write = redisNetWrite +}; + +static redisReply *createReplyObject(int type); +static void *createStringObject(const redisReadTask *task, char *str, size_t len); +static void *createArrayObject(const redisReadTask *task, size_t elements); +static void *createIntegerObject(const redisReadTask *task, long long value); +static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len); +static void *createNilObject(const redisReadTask *task); +static void *createBoolObject(const redisReadTask *task, int bval); + +/* Default set of functions to build the reply. Keep in mind that such a + * function returning NULL is interpreted as OOM. */ +static redisReplyObjectFunctions defaultFunctions = { + createStringObject, + createArrayObject, + createIntegerObject, + createDoubleObject, + createNilObject, + createBoolObject, + freeReplyObject +}; + +/* Create a reply object */ +static redisReply *createReplyObject(int type) { + redisReply *r = hi_calloc(1,sizeof(*r)); + + if (r == NULL) + return NULL; + + r->type = type; + return r; +} + +/* Free a reply object */ +void freeReplyObject(void *reply) { + redisReply *r = reply; + size_t j; + + if (r == NULL) + return; + + switch(r->type) { + case REDIS_REPLY_INTEGER: + break; /* Nothing to free */ + case REDIS_REPLY_ARRAY: + case REDIS_REPLY_MAP: + case REDIS_REPLY_SET: + case REDIS_REPLY_PUSH: + if (r->element != NULL) { + for (j = 0; j < r->elements; j++) + freeReplyObject(r->element[j]); + hi_free(r->element); + } + break; + case REDIS_REPLY_ERROR: + case REDIS_REPLY_STATUS: + case REDIS_REPLY_STRING: + case REDIS_REPLY_DOUBLE: + case REDIS_REPLY_VERB: + hi_free(r->str); + break; + } + hi_free(r); +} + +static void *createStringObject(const redisReadTask *task, char *str, size_t len) { + redisReply *r, *parent; + char *buf; + + r = createReplyObject(task->type); + if (r == NULL) + return NULL; + + assert(task->type == REDIS_REPLY_ERROR || + task->type == REDIS_REPLY_STATUS || + task->type == REDIS_REPLY_STRING || + task->type == REDIS_REPLY_VERB); + + /* Copy string value */ + if (task->type == REDIS_REPLY_VERB) { + buf = hi_malloc(len-4+1); /* Skip 4 bytes of verbatim type header. */ + if (buf == NULL) goto oom; + + memcpy(r->vtype,str,3); + r->vtype[3] = '\0'; + memcpy(buf,str+4,len-4); + buf[len-4] = '\0'; + r->len = len - 4; + } else { + buf = hi_malloc(len+1); + if (buf == NULL) goto oom; + + memcpy(buf,str,len); + buf[len] = '\0'; + r->len = len; + } + r->str = buf; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET || + parent->type == REDIS_REPLY_PUSH); + parent->element[task->idx] = r; + } + return r; + +oom: + freeReplyObject(r); + return NULL; +} + +static void *createArrayObject(const redisReadTask *task, size_t elements) { + redisReply *r, *parent; + + r = createReplyObject(task->type); + if (r == NULL) + return NULL; + + if (elements > 0) { + if (SIZE_MAX / sizeof(redisReply*) < elements) return NULL; /* Don't overflow */ + r->element = hi_calloc(elements,sizeof(redisReply*)); + if (r->element == NULL) { + freeReplyObject(r); + return NULL; + } + } + + r->elements = elements; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET || + parent->type == REDIS_REPLY_PUSH); + parent->element[task->idx] = r; + } + return r; +} + +static void *createIntegerObject(const redisReadTask *task, long long value) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_INTEGER); + if (r == NULL) + return NULL; + + r->integer = value; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET || + parent->type == REDIS_REPLY_PUSH); + parent->element[task->idx] = r; + } + return r; +} + +static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_DOUBLE); + if (r == NULL) + return NULL; + + r->dval = value; + r->str = hi_malloc(len+1); + if (r->str == NULL) { + freeReplyObject(r); + return NULL; + } + + /* The double reply also has the original protocol string representing a + * double as a null terminated string. This way the caller does not need + * to format back for string conversion, especially since Redis does efforts + * to make the string more human readable avoiding the calssical double + * decimal string conversion artifacts. */ + memcpy(r->str, str, len); + r->str[len] = '\0'; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +static void *createNilObject(const redisReadTask *task) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_NIL); + if (r == NULL) + return NULL; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +static void *createBoolObject(const redisReadTask *task, int bval) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_BOOL); + if (r == NULL) + return NULL; + + r->integer = bval != 0; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +/* Return the number of digits of 'v' when converted to string in radix 10. + * Implementation borrowed from link in redis/src/util.c:string2ll(). */ +static uint32_t countDigits(uint64_t v) { + uint32_t result = 1; + for (;;) { + if (v < 10) return result; + if (v < 100) return result + 1; + if (v < 1000) return result + 2; + if (v < 10000) return result + 3; + v /= 10000U; + result += 4; + } +} + +/* Helper that calculates the bulk length given a certain string length. */ +static size_t bulklen(size_t len) { + return 1+countDigits(len)+2+len+2; +} + +int redisvFormatCommand(char **target, const char *format, va_list ap) { + const char *c = format; + char *cmd = NULL; /* final command */ + int pos; /* position in final command */ + sds curarg, newarg; /* current argument */ + int touched = 0; /* was the current argument touched? */ + char **curargv = NULL, **newargv = NULL; + int argc = 0; + int totlen = 0; + int error_type = 0; /* 0 = no error; -1 = memory error; -2 = format error */ + int j; + + /* Abort if there is not target to set */ + if (target == NULL) + return -1; + + /* Build the command string accordingly to protocol */ + curarg = sdsempty(); + if (curarg == NULL) + return -1; + + while(*c != '\0') { + if (*c != '%' || c[1] == '\0') { + if (*c == ' ') { + if (touched) { + newargv = hi_realloc(curargv,sizeof(char*)*(argc+1)); + if (newargv == NULL) goto memory_err; + curargv = newargv; + curargv[argc++] = curarg; + totlen += bulklen(sdslen(curarg)); + + /* curarg is put in argv so it can be overwritten. */ + curarg = sdsempty(); + if (curarg == NULL) goto memory_err; + touched = 0; + } + } else { + newarg = sdscatlen(curarg,c,1); + if (newarg == NULL) goto memory_err; + curarg = newarg; + touched = 1; + } + } else { + char *arg; + size_t size; + + /* Set newarg so it can be checked even if it is not touched. */ + newarg = curarg; + + switch(c[1]) { + case 's': + arg = va_arg(ap,char*); + size = strlen(arg); + if (size > 0) + newarg = sdscatlen(curarg,arg,size); + break; + case 'b': + arg = va_arg(ap,char*); + size = va_arg(ap,size_t); + if (size > 0) + newarg = sdscatlen(curarg,arg,size); + break; + case '%': + newarg = sdscat(curarg,"%"); + break; + default: + /* Try to detect printf format */ + { + static const char intfmts[] = "diouxX"; + static const char flags[] = "#0-+ "; + char _format[16]; + const char *_p = c+1; + size_t _l = 0; + va_list _cpy; + + /* Flags */ + while (*_p != '\0' && strchr(flags,*_p) != NULL) _p++; + + /* Field width */ + while (*_p != '\0' && isdigit(*_p)) _p++; + + /* Precision */ + if (*_p == '.') { + _p++; + while (*_p != '\0' && isdigit(*_p)) _p++; + } + + /* Copy va_list before consuming with va_arg */ + va_copy(_cpy,ap); + + /* Integer conversion (without modifiers) */ + if (strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); + goto fmt_valid; + } + + /* Double conversion (without modifiers) */ + if (strchr("eEfFgGaA",*_p) != NULL) { + va_arg(ap,double); + goto fmt_valid; + } + + /* Size: char */ + if (_p[0] == 'h' && _p[1] == 'h') { + _p += 2; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); /* char gets promoted to int */ + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: short */ + if (_p[0] == 'h') { + _p += 1; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); /* short gets promoted to int */ + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: long long */ + if (_p[0] == 'l' && _p[1] == 'l') { + _p += 2; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,long long); + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: long */ + if (_p[0] == 'l') { + _p += 1; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,long); + goto fmt_valid; + } + goto fmt_invalid; + } + + fmt_invalid: + va_end(_cpy); + goto format_err; + + fmt_valid: + _l = (_p+1)-c; + if (_l < sizeof(_format)-2) { + memcpy(_format,c,_l); + _format[_l] = '\0'; + newarg = sdscatvprintf(curarg,_format,_cpy); + + /* Update current position (note: outer blocks + * increment c twice so compensate here) */ + c = _p-1; + } + + va_end(_cpy); + break; + } + } + + if (newarg == NULL) goto memory_err; + curarg = newarg; + + touched = 1; + c++; + } + c++; + } + + /* Add the last argument if needed */ + if (touched) { + newargv = hi_realloc(curargv,sizeof(char*)*(argc+1)); + if (newargv == NULL) goto memory_err; + curargv = newargv; + curargv[argc++] = curarg; + totlen += bulklen(sdslen(curarg)); + } else { + sdsfree(curarg); + } + + /* Clear curarg because it was put in curargv or was free'd. */ + curarg = NULL; + + /* Add bytes needed to hold multi bulk count */ + totlen += 1+countDigits(argc)+2; + + /* Build the command at protocol level */ + cmd = hi_malloc(totlen+1); + if (cmd == NULL) goto memory_err; + + pos = sprintf(cmd,"*%d\r\n",argc); + for (j = 0; j < argc; j++) { + pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j])); + memcpy(cmd+pos,curargv[j],sdslen(curargv[j])); + pos += sdslen(curargv[j]); + sdsfree(curargv[j]); + cmd[pos++] = '\r'; + cmd[pos++] = '\n'; + } + assert(pos == totlen); + cmd[pos] = '\0'; + + hi_free(curargv); + *target = cmd; + return totlen; + +format_err: + error_type = -2; + goto cleanup; + +memory_err: + error_type = -1; + goto cleanup; + +cleanup: + if (curargv) { + while(argc--) + sdsfree(curargv[argc]); + hi_free(curargv); + } + + sdsfree(curarg); + hi_free(cmd); + + return error_type; +} + +/* Format a command according to the Redis protocol. This function + * takes a format similar to printf: + * + * %s represents a C null terminated string you want to interpolate + * %b represents a binary safe string + * + * When using %b you need to provide both the pointer to the string + * and the length in bytes as a size_t. Examples: + * + * len = redisFormatCommand(target, "GET %s", mykey); + * len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen); + */ +int redisFormatCommand(char **target, const char *format, ...) { + va_list ap; + int len; + va_start(ap,format); + len = redisvFormatCommand(target,format,ap); + va_end(ap); + + /* The API says "-1" means bad result, but we now also return "-2" in some + * cases. Force the return value to always be -1. */ + if (len < 0) + len = -1; + + return len; +} + +/* Format a command according to the Redis protocol using an sds string and + * sdscatfmt for the processing of arguments. This function takes the + * number of arguments, an array with arguments and an array with their + * lengths. If the latter is set to NULL, strlen will be used to compute the + * argument lengths. + */ +int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv, + const size_t *argvlen) +{ + sds cmd, aux; + unsigned long long totlen; + int j; + size_t len; + + /* Abort on a NULL target */ + if (target == NULL) + return -1; + + /* Calculate our total size */ + totlen = 1+countDigits(argc)+2; + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + totlen += bulklen(len); + } + + /* Use an SDS string for command construction */ + cmd = sdsempty(); + if (cmd == NULL) + return -1; + + /* We already know how much storage we need */ + aux = sdsMakeRoomFor(cmd, totlen); + if (aux == NULL) { + sdsfree(cmd); + return -1; + } + + cmd = aux; + + /* Construct command */ + cmd = sdscatfmt(cmd, "*%i\r\n", argc); + for (j=0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + cmd = sdscatfmt(cmd, "$%u\r\n", len); + cmd = sdscatlen(cmd, argv[j], len); + cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1); + } + + assert(sdslen(cmd)==totlen); + + *target = cmd; + return totlen; +} + +void redisFreeSdsCommand(sds cmd) { + sdsfree(cmd); +} + +/* Format a command according to the Redis protocol. This function takes the + * number of arguments, an array with arguments and an array with their + * lengths. If the latter is set to NULL, strlen will be used to compute the + * argument lengths. + */ +int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) { + char *cmd = NULL; /* final command */ + int pos; /* position in final command */ + size_t len; + int totlen, j; + + /* Abort on a NULL target */ + if (target == NULL) + return -1; + + /* Calculate number of bytes needed for the command */ + totlen = 1+countDigits(argc)+2; + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + totlen += bulklen(len); + } + + /* Build the command at protocol level */ + cmd = hi_malloc(totlen+1); + if (cmd == NULL) + return -1; + + pos = sprintf(cmd,"*%d\r\n",argc); + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + pos += sprintf(cmd+pos,"$%zu\r\n",len); + memcpy(cmd+pos,argv[j],len); + pos += len; + cmd[pos++] = '\r'; + cmd[pos++] = '\n'; + } + assert(pos == totlen); + cmd[pos] = '\0'; + + *target = cmd; + return totlen; +} + +void redisFreeCommand(char *cmd) { + hi_free(cmd); +} + +void __redisSetError(redisContext *c, int type, const char *str) { + size_t len; + + c->err = type; + if (str != NULL) { + len = strlen(str); + len = len < (sizeof(c->errstr)-1) ? len : (sizeof(c->errstr)-1); + memcpy(c->errstr,str,len); + c->errstr[len] = '\0'; + } else { + /* Only REDIS_ERR_IO may lack a description! */ + assert(type == REDIS_ERR_IO); + strerror_r(errno, c->errstr, sizeof(c->errstr)); + } +} + +redisReader *redisReaderCreate(void) { + return redisReaderCreateWithFunctions(&defaultFunctions); +} + +static void redisPushAutoFree(void *privdata, void *reply) { + (void)privdata; + freeReplyObject(reply); +} + +static redisContext *redisContextInit(void) { + redisContext *c; + + c = hi_calloc(1, sizeof(*c)); + if (c == NULL) + return NULL; + + c->funcs = &redisContextDefaultFuncs; + + c->obuf = sdsempty(); + c->reader = redisReaderCreate(); + c->fd = REDIS_INVALID_FD; + + if (c->obuf == NULL || c->reader == NULL) { + redisFree(c); + return NULL; + } + + return c; +} + +void redisFree(redisContext *c) { + if (c == NULL) + return; + redisNetClose(c); + + sdsfree(c->obuf); + redisReaderFree(c->reader); + hi_free(c->tcp.host); + hi_free(c->tcp.source_addr); + hi_free(c->unix_sock.path); + hi_free(c->connect_timeout); + hi_free(c->command_timeout); + hi_free(c->saddr); + + if (c->privdata && c->free_privdata) + c->free_privdata(c->privdata); + + if (c->funcs->free_privctx) + c->funcs->free_privctx(c->privctx); + + memset(c, 0xff, sizeof(*c)); + hi_free(c); +} + +redisFD redisFreeKeepFd(redisContext *c) { + redisFD fd = c->fd; + c->fd = REDIS_INVALID_FD; + redisFree(c); + return fd; +} + +int redisReconnect(redisContext *c) { + c->err = 0; + memset(c->errstr, '\0', strlen(c->errstr)); + + if (c->privctx && c->funcs->free_privctx) { + c->funcs->free_privctx(c->privctx); + c->privctx = NULL; + } + + redisNetClose(c); + + sdsfree(c->obuf); + redisReaderFree(c->reader); + + c->obuf = sdsempty(); + c->reader = redisReaderCreate(); + + if (c->obuf == NULL || c->reader == NULL) { + __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); + return REDIS_ERR; + } + + int ret = REDIS_ERR; + if (c->connection_type == REDIS_CONN_TCP) { + ret = redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port, + c->connect_timeout, c->tcp.source_addr); + } else if (c->connection_type == REDIS_CONN_UNIX) { + ret = redisContextConnectUnix(c, c->unix_sock.path, c->connect_timeout); + } else { + /* Something bad happened here and shouldn't have. There isn't + enough information in the context to reconnect. */ + __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect"); + ret = REDIS_ERR; + } + + if (c->command_timeout != NULL && (c->flags & REDIS_BLOCK) && c->fd != REDIS_INVALID_FD) { + redisContextSetTimeout(c, *c->command_timeout); + } + + return ret; +} + +redisContext *redisConnectWithOptions(const redisOptions *options) { + redisContext *c = redisContextInit(); + if (c == NULL) { + return NULL; + } + if (!(options->options & REDIS_OPT_NONBLOCK)) { + c->flags |= REDIS_BLOCK; + } + if (options->options & REDIS_OPT_REUSEADDR) { + c->flags |= REDIS_REUSEADDR; + } + if (options->options & REDIS_OPT_NOAUTOFREE) { + c->flags |= REDIS_NO_AUTO_FREE; + } + + /* Set any user supplied RESP3 PUSH handler or use freeReplyObject + * as a default unless specifically flagged that we don't want one. */ + if (options->push_cb != NULL) + redisSetPushCallback(c, options->push_cb); + else if (!(options->options & REDIS_OPT_NO_PUSH_AUTOFREE)) + redisSetPushCallback(c, redisPushAutoFree); + + c->privdata = options->privdata; + c->free_privdata = options->free_privdata; + + if (redisContextUpdateConnectTimeout(c, options->connect_timeout) != REDIS_OK || + redisContextUpdateCommandTimeout(c, options->command_timeout) != REDIS_OK) { + __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); + return c; + } + + if (options->type == REDIS_CONN_TCP) { + redisContextConnectBindTcp(c, options->endpoint.tcp.ip, + options->endpoint.tcp.port, options->connect_timeout, + options->endpoint.tcp.source_addr); + } else if (options->type == REDIS_CONN_UNIX) { + redisContextConnectUnix(c, options->endpoint.unix_socket, + options->connect_timeout); + } else if (options->type == REDIS_CONN_USERFD) { + c->fd = options->endpoint.fd; + c->flags |= REDIS_CONNECTED; + } else { + // Unknown type - FIXME - FREE + return NULL; + } + + if (options->command_timeout != NULL && (c->flags & REDIS_BLOCK) && c->fd != REDIS_INVALID_FD) { + redisContextSetTimeout(c, *options->command_timeout); + } + + return c; +} + +/* Connect to a Redis instance. On error the field error in the returned + * context will be set to the return value of the error function. + * When no set of reply functions is given, the default set will be used. */ +redisContext *redisConnect(const char *ip, int port) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.connect_timeout = &tv; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectNonBlock(const char *ip, int port) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.options |= REDIS_OPT_NONBLOCK; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.endpoint.tcp.source_addr = source_addr; + options.options |= REDIS_OPT_NONBLOCK; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.endpoint.tcp.source_addr = source_addr; + options.options |= REDIS_OPT_NONBLOCK|REDIS_OPT_REUSEADDR; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectUnix(const char *path) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_UNIX(&options, path); + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_UNIX(&options, path); + options.connect_timeout = &tv; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectUnixNonBlock(const char *path) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_UNIX(&options, path); + options.options |= REDIS_OPT_NONBLOCK; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectFd(redisFD fd) { + redisOptions options = {0}; + options.type = REDIS_CONN_USERFD; + options.endpoint.fd = fd; + return redisConnectWithOptions(&options); +} + +/* Set read/write timeout on a blocking socket. */ +int redisSetTimeout(redisContext *c, const struct timeval tv) { + if (c->flags & REDIS_BLOCK) + return redisContextSetTimeout(c,tv); + return REDIS_ERR; +} + +/* Enable connection KeepAlive. */ +int redisEnableKeepAlive(redisContext *c) { + if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK) + return REDIS_ERR; + return REDIS_OK; +} + +/* Set a user provided RESP3 PUSH handler and return any old one set. */ +redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn) { + redisPushFn *old = c->push_cb; + c->push_cb = fn; + return old; +} + +/* Use this function to handle a read event on the descriptor. It will try + * and read some bytes from the socket and feed them to the reply parser. + * + * After this function is called, you may use redisGetReplyFromReader to + * see if there is a reply available. */ +int redisBufferRead(redisContext *c) { + char buf[1024*16]; + int nread; + + /* Return early when the context has seen an error. */ + if (c->err) + return REDIS_ERR; + + nread = c->funcs->read(c, buf, sizeof(buf)); + if (nread > 0) { + if (redisReaderFeed(c->reader, buf, nread) != REDIS_OK) { + __redisSetError(c, c->reader->err, c->reader->errstr); + return REDIS_ERR; + } else { + } + } else if (nread < 0) { + return REDIS_ERR; + } + return REDIS_OK; +} + +/* Write the output buffer to the socket. + * + * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was + * successfully written to the socket. When the buffer is empty after the + * write operation, "done" is set to 1 (if given). + * + * Returns REDIS_ERR if an error occurred trying to write and sets + * c->errstr to hold the appropriate error string. + */ +int redisBufferWrite(redisContext *c, int *done) { + + /* Return early when the context has seen an error. */ + if (c->err) + return REDIS_ERR; + + if (sdslen(c->obuf) > 0) { + ssize_t nwritten = c->funcs->write(c); + if (nwritten < 0) { + return REDIS_ERR; + } else if (nwritten > 0) { + if (nwritten == (ssize_t)sdslen(c->obuf)) { + sdsfree(c->obuf); + c->obuf = sdsempty(); + if (c->obuf == NULL) + goto oom; + } else { + if (sdsrange(c->obuf,nwritten,-1) < 0) goto oom; + } + } + } + if (done != NULL) *done = (sdslen(c->obuf) == 0); + return REDIS_OK; + +oom: + __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); + return REDIS_ERR; +} + +/* Internal helper function to try and get a reply from the reader, + * or set an error in the context otherwise. */ +int redisGetReplyFromReader(redisContext *c, void **reply) { + if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) { + __redisSetError(c,c->reader->err,c->reader->errstr); + return REDIS_ERR; + } + + return REDIS_OK; +} + +/* Internal helper that returns 1 if the reply was a RESP3 PUSH + * message and we handled it with a user-provided callback. */ +static int redisHandledPushReply(redisContext *c, void *reply) { + if (reply && c->push_cb && redisIsPushReply(reply)) { + c->push_cb(c->privdata, reply); + return 1; + } + + return 0; +} + +int redisGetReply(redisContext *c, void **reply) { + int wdone = 0; + void *aux = NULL; + + /* Try to read pending replies */ + if (redisGetReplyFromReader(c,&aux) == REDIS_ERR) + return REDIS_ERR; + + /* For the blocking context, flush output buffer and read reply */ + if (aux == NULL && c->flags & REDIS_BLOCK) { + /* Write until done */ + do { + if (redisBufferWrite(c,&wdone) == REDIS_ERR) + return REDIS_ERR; + } while (!wdone); + + /* Read until there is a reply */ + do { + if (redisBufferRead(c) == REDIS_ERR) + return REDIS_ERR; + + /* We loop here in case the user has specified a RESP3 + * PUSH handler (e.g. for client tracking). */ + do { + if (redisGetReplyFromReader(c,&aux) == REDIS_ERR) + return REDIS_ERR; + } while (redisHandledPushReply(c, aux)); + } while (aux == NULL); + } + + /* Set reply or free it if we were passed NULL */ + if (reply != NULL) { + *reply = aux; + } else { + freeReplyObject(aux); + } + + return REDIS_OK; +} + + +/* Helper function for the redisAppendCommand* family of functions. + * + * Write a formatted command to the output buffer. When this family + * is used, you need to call redisGetReply yourself to retrieve + * the reply (or replies in pub/sub). + */ +int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) { + sds newbuf; + + newbuf = sdscatlen(c->obuf,cmd,len); + if (newbuf == NULL) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } + + c->obuf = newbuf; + return REDIS_OK; +} + +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) { + + if (__redisAppendCommand(c, cmd, len) != REDIS_OK) { + return REDIS_ERR; + } + + return REDIS_OK; +} + +int redisvAppendCommand(redisContext *c, const char *format, va_list ap) { + char *cmd; + int len; + + len = redisvFormatCommand(&cmd,format,ap); + if (len == -1) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } else if (len == -2) { + __redisSetError(c,REDIS_ERR_OTHER,"Invalid format string"); + return REDIS_ERR; + } + + if (__redisAppendCommand(c,cmd,len) != REDIS_OK) { + hi_free(cmd); + return REDIS_ERR; + } + + hi_free(cmd); + return REDIS_OK; +} + +int redisAppendCommand(redisContext *c, const char *format, ...) { + va_list ap; + int ret; + + va_start(ap,format); + ret = redisvAppendCommand(c,format,ap); + va_end(ap); + return ret; +} + +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { + sds cmd; + int len; + + len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); + if (len == -1) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } + + if (__redisAppendCommand(c,cmd,len) != REDIS_OK) { + sdsfree(cmd); + return REDIS_ERR; + } + + sdsfree(cmd); + return REDIS_OK; +} + +/* Helper function for the redisCommand* family of functions. + * + * Write a formatted command to the output buffer. If the given context is + * blocking, immediately read the reply into the "reply" pointer. When the + * context is non-blocking, the "reply" pointer will not be used and the + * command is simply appended to the write buffer. + * + * Returns the reply when a reply was successfully retrieved. Returns NULL + * otherwise. When NULL is returned in a blocking context, the error field + * in the context will be set. + */ +static void *__redisBlockForReply(redisContext *c) { + void *reply; + + if (c->flags & REDIS_BLOCK) { + if (redisGetReply(c,&reply) != REDIS_OK) + return NULL; + return reply; + } + return NULL; +} + +void *redisvCommand(redisContext *c, const char *format, va_list ap) { + if (redisvAppendCommand(c,format,ap) != REDIS_OK) + return NULL; + return __redisBlockForReply(c); +} + +void *redisCommand(redisContext *c, const char *format, ...) { + va_list ap; + va_start(ap,format); + void *reply = redisvCommand(c,format,ap); + va_end(ap); + return reply; +} + +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { + if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK) + return NULL; + return __redisBlockForReply(c); +} diff --git a/ext/hiredis-1.0.2/hiredis.h b/ext/hiredis-1.0.2/hiredis.h new file mode 100644 index 0000000..3bc46d9 --- /dev/null +++ b/ext/hiredis-1.0.2/hiredis.h @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_H +#define __HIREDIS_H +#include "read.h" +#include /* for va_list */ +#ifndef _MSC_VER +#include /* for struct timeval */ +#else +struct timeval; /* forward declaration */ +typedef long long ssize_t; +#endif +#include /* uintXX_t, etc */ +#include "sds.h" /* for sds */ +#include "alloc.h" /* for allocation wrappers */ + +#define HIREDIS_MAJOR 1 +#define HIREDIS_MINOR 0 +#define HIREDIS_PATCH 2 +#define HIREDIS_SONAME 1.0.0 + +/* Connection type can be blocking or non-blocking and is set in the + * least significant bit of the flags field in redisContext. */ +#define REDIS_BLOCK 0x1 + +/* Connection may be disconnected before being free'd. The second bit + * in the flags field is set when the context is connected. */ +#define REDIS_CONNECTED 0x2 + +/* The async API might try to disconnect cleanly and flush the output + * buffer and read all subsequent replies before disconnecting. + * This flag means no new commands can come in and the connection + * should be terminated once all replies have been read. */ +#define REDIS_DISCONNECTING 0x4 + +/* Flag specific to the async API which means that the context should be clean + * up as soon as possible. */ +#define REDIS_FREEING 0x8 + +/* Flag that is set when an async callback is executed. */ +#define REDIS_IN_CALLBACK 0x10 + +/* Flag that is set when the async context has one or more subscriptions. */ +#define REDIS_SUBSCRIBED 0x20 + +/* Flag that is set when monitor mode is active */ +#define REDIS_MONITORING 0x40 + +/* Flag that is set when we should set SO_REUSEADDR before calling bind() */ +#define REDIS_REUSEADDR 0x80 + +/** + * Flag that indicates the user does not want the context to + * be automatically freed upon error + */ +#define REDIS_NO_AUTO_FREE 0x200 + +#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ + +/* number of times we retry to connect in the case of EADDRNOTAVAIL and + * SO_REUSEADDR is being used. */ +#define REDIS_CONNECT_RETRIES 10 + +/* Forward declarations for structs defined elsewhere */ +struct redisAsyncContext; +struct redisContext; + +/* RESP3 push helpers and callback prototypes */ +#define redisIsPushReply(r) (((redisReply*)(r))->type == REDIS_REPLY_PUSH) +typedef void (redisPushFn)(void *, void *); +typedef void (redisAsyncPushFn)(struct redisAsyncContext *, void *); + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the reply object returned by redisCommand() */ +typedef struct redisReply { + int type; /* REDIS_REPLY_* */ + long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ + double dval; /* The double when type is REDIS_REPLY_DOUBLE */ + size_t len; /* Length of string */ + char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING + REDIS_REPLY_VERB, and REDIS_REPLY_DOUBLE (in additional to dval). */ + char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null + terminated 3 character content type, such as "txt". */ + size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ + struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ +} redisReply; + +redisReader *redisReaderCreate(void); + +/* Function to free the reply objects hiredis returns by default. */ +void freeReplyObject(void *reply); + +/* Functions to format a command according to the protocol. */ +int redisvFormatCommand(char **target, const char *format, va_list ap); +int redisFormatCommand(char **target, const char *format, ...); +int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); +int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); +void redisFreeCommand(char *cmd); +void redisFreeSdsCommand(sds cmd); + +enum redisConnectionType { + REDIS_CONN_TCP, + REDIS_CONN_UNIX, + REDIS_CONN_USERFD +}; + +struct redisSsl; + +#define REDIS_OPT_NONBLOCK 0x01 +#define REDIS_OPT_REUSEADDR 0x02 + +/** + * Don't automatically free the async object on a connection failure, + * or other implicit conditions. Only free on an explicit call to disconnect() or free() + */ +#define REDIS_OPT_NOAUTOFREE 0x04 + +/* Don't automatically intercept and free RESP3 PUSH replies. */ +#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08 + +/* In Unix systems a file descriptor is a regular signed int, with -1 + * representing an invalid descriptor. In Windows it is a SOCKET + * (32- or 64-bit unsigned integer depending on the architecture), where + * all bits set (~0) is INVALID_SOCKET. */ +#ifndef _WIN32 +typedef int redisFD; +#define REDIS_INVALID_FD -1 +#else +#ifdef _WIN64 +typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */ +#else +typedef unsigned long redisFD; /* SOCKET = 32-bit UINT_PTR */ +#endif +#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */ +#endif + +typedef struct { + /* + * the type of connection to use. This also indicates which + * `endpoint` member field to use + */ + int type; + /* bit field of REDIS_OPT_xxx */ + int options; + /* timeout value for connect operation. If NULL, no timeout is used */ + const struct timeval *connect_timeout; + /* timeout value for commands. If NULL, no timeout is used. This can be + * updated at runtime with redisSetTimeout/redisAsyncSetTimeout. */ + const struct timeval *command_timeout; + union { + /** use this field for tcp/ip connections */ + struct { + const char *source_addr; + const char *ip; + int port; + } tcp; + /** use this field for unix domain sockets */ + const char *unix_socket; + /** + * use this field to have hiredis operate an already-open + * file descriptor */ + redisFD fd; + } endpoint; + + /* Optional user defined data/destructor */ + void *privdata; + void (*free_privdata)(void *); + + /* A user defined PUSH message callback */ + redisPushFn *push_cb; + redisAsyncPushFn *async_push_cb; +} redisOptions; + +/** + * Helper macros to initialize options to their specified fields. + */ +#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \ + (opts)->type = REDIS_CONN_TCP; \ + (opts)->endpoint.tcp.ip = ip_; \ + (opts)->endpoint.tcp.port = port_; + +#define REDIS_OPTIONS_SET_UNIX(opts, path) \ + (opts)->type = REDIS_CONN_UNIX; \ + (opts)->endpoint.unix_socket = path; + +#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) \ + (opts)->privdata = data; \ + (opts)->free_privdata = dtor; \ + +typedef struct redisContextFuncs { + void (*free_privctx)(void *); + void (*async_read)(struct redisAsyncContext *); + void (*async_write)(struct redisAsyncContext *); + ssize_t (*read)(struct redisContext *, char *, size_t); + ssize_t (*write)(struct redisContext *); +} redisContextFuncs; + +/* Context for a connection to Redis */ +typedef struct redisContext { + const redisContextFuncs *funcs; /* Function table */ + + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + redisFD fd; + int flags; + char *obuf; /* Write buffer */ + redisReader *reader; /* Protocol reader */ + + enum redisConnectionType connection_type; + struct timeval *connect_timeout; + struct timeval *command_timeout; + + struct { + char *host; + char *source_addr; + int port; + } tcp; + + struct { + char *path; + } unix_sock; + + /* For non-blocking connect */ + struct sockadr *saddr; + size_t addrlen; + + /* Optional data and corresponding destructor users can use to provide + * context to a given redisContext. Not used by hiredis. */ + void *privdata; + void (*free_privdata)(void *); + + /* Internal context pointer presently used by hiredis to manage + * SSL connections. */ + void *privctx; + + /* An optional RESP3 PUSH handler */ + redisPushFn *push_cb; +} redisContext; + +redisContext *redisConnectWithOptions(const redisOptions *options); +redisContext *redisConnect(const char *ip, int port); +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); +redisContext *redisConnectNonBlock(const char *ip, int port); +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectUnix(const char *path); +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); +redisContext *redisConnectUnixNonBlock(const char *path); +redisContext *redisConnectFd(redisFD fd); + +/** + * Reconnect the given context using the saved information. + * + * This re-uses the exact same connect options as in the initial connection. + * host, ip (or path), timeout and bind address are reused, + * flags are used unmodified from the existing context. + * + * Returns REDIS_OK on successful connect or REDIS_ERR otherwise. + */ +int redisReconnect(redisContext *c); + +redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn); +int redisSetTimeout(redisContext *c, const struct timeval tv); +int redisEnableKeepAlive(redisContext *c); +void redisFree(redisContext *c); +redisFD redisFreeKeepFd(redisContext *c); +int redisBufferRead(redisContext *c); +int redisBufferWrite(redisContext *c, int *done); + +/* In a blocking context, this function first checks if there are unconsumed + * replies to return and returns one if so. Otherwise, it flushes the output + * buffer to the socket and reads until it has a reply. In a non-blocking + * context, it will return unconsumed replies until there are no more. */ +int redisGetReply(redisContext *c, void **reply); +int redisGetReplyFromReader(redisContext *c, void **reply); + +/* Write a formatted command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); + +/* Write a command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisvAppendCommand(redisContext *c, const char *format, va_list ap); +int redisAppendCommand(redisContext *c, const char *format, ...); +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +/* Issue a command to Redis. In a blocking context, it is identical to calling + * redisAppendCommand, followed by redisGetReply. The function will return + * NULL if there was an error in performing the request, otherwise it will + * return the reply. In a non-blocking context, it is identical to calling + * only redisAppendCommand and will always return NULL. */ +void *redisvCommand(redisContext *c, const char *format, va_list ap); +void *redisCommand(redisContext *c, const char *format, ...); +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-1.0.2/hiredis.pc.in b/ext/hiredis-1.0.2/hiredis.pc.in new file mode 100644 index 0000000..91b7731 --- /dev/null +++ b/ext/hiredis-1.0.2/hiredis.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +install_libdir=@CMAKE_INSTALL_LIBDIR@ +exec_prefix=${prefix} +libdir=${exec_prefix}/${install_libdir} +includedir=${prefix}/include +pkgincludedir=${includedir}/hiredis + +Name: hiredis +Description: Minimalistic C client library for Redis. +Version: @PROJECT_VERSION@ +Libs: -L${libdir} -lhiredis +Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64 diff --git a/ext/hiredis-1.0.2/hiredis_ssl-config.cmake.in b/ext/hiredis-1.0.2/hiredis_ssl-config.cmake.in new file mode 100644 index 0000000..9a283df --- /dev/null +++ b/ext/hiredis-1.0.2/hiredis_ssl-config.cmake.in @@ -0,0 +1,13 @@ +@PACKAGE_INIT@ + +set_and_check(hiredis_ssl_INCLUDEDIR "@PACKAGE_INCLUDE_INSTALL_DIR@") + +IF (NOT TARGET hiredis::hiredis_ssl) + INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis_ssl-targets.cmake) +ENDIF() + +SET(hiredis_ssl_LIBRARIES hiredis::hiredis_ssl) +SET(hiredis_ssl_INCLUDE_DIRS ${hiredis_ssl_INCLUDEDIR}) + +check_required_components(hiredis_ssl) + diff --git a/ext/hiredis-1.0.2/hiredis_ssl.h b/ext/hiredis-1.0.2/hiredis_ssl.h new file mode 100644 index 0000000..604efe0 --- /dev/null +++ b/ext/hiredis-1.0.2/hiredis_ssl.h @@ -0,0 +1,127 @@ + +/* + * Copyright (c) 2019, Redis Labs + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_SSL_H +#define __HIREDIS_SSL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the underlying struct for SSL in ssl.h, which is not included to + * keep build dependencies short here. + */ +struct ssl_st; + +/* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly + * calling OpenSSL. + */ +typedef struct redisSSLContext redisSSLContext; + +/** + * Initialization errors that redisCreateSSLContext() may return. + */ + +typedef enum { + REDIS_SSL_CTX_NONE = 0, /* No Error */ + REDIS_SSL_CTX_CREATE_FAILED, /* Failed to create OpenSSL SSL_CTX */ + REDIS_SSL_CTX_CERT_KEY_REQUIRED, /* Client cert and key must both be specified or skipped */ + REDIS_SSL_CTX_CA_CERT_LOAD_FAILED, /* Failed to load CA Certificate or CA Path */ + REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED, /* Failed to load client certificate */ + REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED /* Failed to load private key */ +} redisSSLContextError; + +/** + * Return the error message corresponding with the specified error code. + */ + +const char *redisSSLContextGetError(redisSSLContextError error); + +/** + * Helper function to initialize the OpenSSL library. + * + * OpenSSL requires one-time initialization before it can be used. Callers should + * call this function only once, and only if OpenSSL is not directly initialized + * elsewhere. + */ +int redisInitOpenSSL(void); + +/** + * Helper function to initialize an OpenSSL context that can be used + * to initiate SSL connections. + * + * cacert_filename is an optional name of a CA certificate/bundle file to load + * and use for validation. + * + * capath is an optional directory path where trusted CA certificate files are + * stored in an OpenSSL-compatible structure. + * + * cert_filename and private_key_filename are optional names of a client side + * certificate and private key files to use for authentication. They need to + * be both specified or omitted. + * + * server_name is an optional and will be used as a server name indication + * (SNI) TLS extension. + * + * If error is non-null, it will be populated in case the context creation fails + * (returning a NULL). + */ + +redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath, + const char *cert_filename, const char *private_key_filename, + const char *server_name, redisSSLContextError *error); + +/** + * Free a previously created OpenSSL context. + */ +void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx); + +/** + * Initiate SSL on an existing redisContext. + * + * This is similar to redisInitiateSSL() but does not require the caller + * to directly interact with OpenSSL, and instead uses a redisSSLContext + * previously created using redisCreateSSLContext(). + */ + +int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx); + +/** + * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object. + */ + +int redisInitiateSSL(redisContext *c, struct ssl_st *ssl); + +#ifdef __cplusplus +} +#endif + +#endif /* __HIREDIS_SSL_H */ diff --git a/ext/hiredis-1.0.2/hiredis_ssl.pc.in b/ext/hiredis-1.0.2/hiredis_ssl.pc.in new file mode 100644 index 0000000..588a978 --- /dev/null +++ b/ext/hiredis-1.0.2/hiredis_ssl.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include +pkgincludedir=${includedir}/hiredis + +Name: hiredis_ssl +Description: SSL Support for hiredis. +Version: @PROJECT_VERSION@ +Requires: hiredis +Libs: -L${libdir} -lhiredis_ssl +Libs.private: -lssl -lcrypto diff --git a/ext/hiredis-1.0.2/include/hiredis/alloc.h b/ext/hiredis-1.0.2/include/hiredis/alloc.h new file mode 100644 index 0000000..34a05f4 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/alloc.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HIREDIS_ALLOC_H +#define HIREDIS_ALLOC_H + +#include /* for size_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure pointing to our actually configured allocators */ +typedef struct hiredisAllocFuncs { + void *(*mallocFn)(size_t); + void *(*callocFn)(size_t,size_t); + void *(*reallocFn)(void*,size_t); + char *(*strdupFn)(const char*); + void (*freeFn)(void*); +} hiredisAllocFuncs; + +hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *ha); +void hiredisResetAllocators(void); + +#ifndef _WIN32 + +/* Hiredis' configured allocator function pointer struct */ +extern hiredisAllocFuncs hiredisAllocFns; + +static inline void *hi_malloc(size_t size) { + return hiredisAllocFns.mallocFn(size); +} + +static inline void *hi_calloc(size_t nmemb, size_t size) { + return hiredisAllocFns.callocFn(nmemb, size); +} + +static inline void *hi_realloc(void *ptr, size_t size) { + return hiredisAllocFns.reallocFn(ptr, size); +} + +static inline char *hi_strdup(const char *str) { + return hiredisAllocFns.strdupFn(str); +} + +static inline void hi_free(void *ptr) { + hiredisAllocFns.freeFn(ptr); +} + +#else + +void *hi_malloc(size_t size); +void *hi_calloc(size_t nmemb, size_t size); +void *hi_realloc(void *ptr, size_t size); +char *hi_strdup(const char *str); +void hi_free(void *ptr); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* HIREDIS_ALLOC_H */ diff --git a/ext/hiredis-1.0.2/include/hiredis/async.h b/ext/hiredis-1.0.2/include/hiredis/async.h new file mode 100644 index 0000000..b1d2cb2 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/async.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_ASYNC_H +#define __HIREDIS_ASYNC_H +#include "hiredis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ +struct dict; /* dictionary header is included in async.c */ + +/* Reply callback prototype and container */ +typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); +typedef struct redisCallback { + struct redisCallback *next; /* simple singly linked list */ + redisCallbackFn *fn; + int pending_subs; + void *privdata; +} redisCallback; + +/* List of callbacks for either regular replies or pub/sub */ +typedef struct redisCallbackList { + redisCallback *head, *tail; +} redisCallbackList; + +/* Connection callback prototypes */ +typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); +typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); +typedef void(redisTimerCallback)(void *timer, void *privdata); + +/* Context for an async connection to Redis */ +typedef struct redisAsyncContext { + /* Hold the regular context, so it can be realloc'ed. */ + redisContext c; + + /* Setup error flags so they can be used directly. */ + int err; + char *errstr; + + /* Not used by hiredis */ + void *data; + void (*dataCleanup)(void *privdata); + + /* Event library data and hooks */ + struct { + void *data; + + /* Hooks that are called when the library expects to start + * reading/writing. These functions should be idempotent. */ + void (*addRead)(void *privdata); + void (*delRead)(void *privdata); + void (*addWrite)(void *privdata); + void (*delWrite)(void *privdata); + void (*cleanup)(void *privdata); + void (*scheduleTimer)(void *privdata, struct timeval tv); + } ev; + + /* Called when either the connection is terminated due to an error or per + * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ + redisDisconnectCallback *onDisconnect; + + /* Called when the first write event was received. */ + redisConnectCallback *onConnect; + + /* Regular command callbacks */ + redisCallbackList replies; + + /* Address used for connect() */ + struct sockaddr *saddr; + size_t addrlen; + + /* Subscription callbacks */ + struct { + redisCallbackList invalid; + struct dict *channels; + struct dict *patterns; + } sub; + + /* Any configured RESP3 PUSH handler */ + redisAsyncPushFn *push_cb; +} redisAsyncContext; + +/* Functions that proxy to hiredis */ +redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options); +redisAsyncContext *redisAsyncConnect(const char *ip, int port); +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr); +redisAsyncContext *redisAsyncConnectUnix(const char *path); +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); + +redisAsyncPushFn *redisAsyncSetPushCallback(redisAsyncContext *ac, redisAsyncPushFn *fn); +int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv); +void redisAsyncDisconnect(redisAsyncContext *ac); +void redisAsyncFree(redisAsyncContext *ac); + +/* Handle read/write events */ +void redisAsyncHandleRead(redisAsyncContext *ac); +void redisAsyncHandleWrite(redisAsyncContext *ac); +void redisAsyncHandleTimeout(redisAsyncContext *ac); +void redisAsyncRead(redisAsyncContext *ac); +void redisAsyncWrite(redisAsyncContext *ac); + +/* Command functions for an async context. Write the command to the + * output buffer and register the provided callback. */ +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-1.0.2/include/hiredis/async_private.h b/ext/hiredis-1.0.2/include/hiredis/async_private.h new file mode 100644 index 0000000..b9d23ff --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/async_private.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_ASYNC_PRIVATE_H +#define __HIREDIS_ASYNC_PRIVATE_H + +#define _EL_ADD_READ(ctx) \ + do { \ + refreshTimeout(ctx); \ + if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \ + } while (0) +#define _EL_DEL_READ(ctx) do { \ + if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \ + } while(0) +#define _EL_ADD_WRITE(ctx) \ + do { \ + refreshTimeout(ctx); \ + if ((ctx)->ev.addWrite) (ctx)->ev.addWrite((ctx)->ev.data); \ + } while (0) +#define _EL_DEL_WRITE(ctx) do { \ + if ((ctx)->ev.delWrite) (ctx)->ev.delWrite((ctx)->ev.data); \ + } while(0) +#define _EL_CLEANUP(ctx) do { \ + if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \ + ctx->ev.cleanup = NULL; \ + } while(0); + +static inline void refreshTimeout(redisAsyncContext *ctx) { + #define REDIS_TIMER_ISSET(tvp) \ + (tvp && ((tvp)->tv_sec || (tvp)->tv_usec)) + + #define REDIS_EL_TIMER(ac, tvp) \ + if ((ac)->ev.scheduleTimer && REDIS_TIMER_ISSET(tvp)) { \ + (ac)->ev.scheduleTimer((ac)->ev.data, *(tvp)); \ + } + + if (ctx->c.flags & REDIS_CONNECTED) { + REDIS_EL_TIMER(ctx, ctx->c.command_timeout); + } else { + REDIS_EL_TIMER(ctx, ctx->c.connect_timeout); + } +} + +void __redisAsyncDisconnect(redisAsyncContext *ac); +void redisProcessCallbacks(redisAsyncContext *ac); + +#endif /* __HIREDIS_ASYNC_PRIVATE_H */ diff --git a/ext/hiredis-1.0.2/include/hiredis/dict.h b/ext/hiredis-1.0.2/include/hiredis/dict.h new file mode 100644 index 0000000..95fcd28 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/dict.h @@ -0,0 +1,126 @@ +/* Hash table implementation. + * + * This file implements in memory hash tables with insert/del/replace/find/ + * get-random-element operations. Hash tables will auto resize if needed + * tables of power of two in size are used, collisions are handled by + * chaining. See the source code for more information... :) + * + * Copyright (c) 2006-2010, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DICT_H +#define __DICT_H + +#define DICT_OK 0 +#define DICT_ERR 1 + +/* Unused arguments generate annoying warnings... */ +#define DICT_NOTUSED(V) ((void) V) + +typedef struct dictEntry { + void *key; + void *val; + struct dictEntry *next; +} dictEntry; + +typedef struct dictType { + unsigned int (*hashFunction)(const void *key); + void *(*keyDup)(void *privdata, const void *key); + void *(*valDup)(void *privdata, const void *obj); + int (*keyCompare)(void *privdata, const void *key1, const void *key2); + void (*keyDestructor)(void *privdata, void *key); + void (*valDestructor)(void *privdata, void *obj); +} dictType; + +typedef struct dict { + dictEntry **table; + dictType *type; + unsigned long size; + unsigned long sizemask; + unsigned long used; + void *privdata; +} dict; + +typedef struct dictIterator { + dict *ht; + int index; + dictEntry *entry, *nextEntry; +} dictIterator; + +/* This is the initial size of every hash table */ +#define DICT_HT_INITIAL_SIZE 4 + +/* ------------------------------- Macros ------------------------------------*/ +#define dictFreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->val) + +#define dictSetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ + else \ + entry->val = (_val_); \ +} while(0) + +#define dictFreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define dictSetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ + else \ + entry->key = (_key_); \ +} while(0) + +#define dictCompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ + (key1) == (key2)) + +#define dictHashKey(ht, key) (ht)->type->hashFunction(key) + +#define dictGetEntryKey(he) ((he)->key) +#define dictGetEntryVal(he) ((he)->val) +#define dictSlots(ht) ((ht)->size) +#define dictSize(ht) ((ht)->used) + +/* API */ +static unsigned int dictGenHashFunction(const unsigned char *buf, int len); +static dict *dictCreate(dictType *type, void *privDataPtr); +static int dictExpand(dict *ht, unsigned long size); +static int dictAdd(dict *ht, void *key, void *val); +static int dictReplace(dict *ht, void *key, void *val); +static int dictDelete(dict *ht, const void *key); +static void dictRelease(dict *ht); +static dictEntry * dictFind(dict *ht, const void *key); +static dictIterator *dictGetIterator(dict *ht); +static dictEntry *dictNext(dictIterator *iter); +static void dictReleaseIterator(dictIterator *iter); + +#endif /* __DICT_H */ diff --git a/ext/hiredis-1.0.2/include/hiredis/fmacros.h b/ext/hiredis-1.0.2/include/hiredis/fmacros.h new file mode 100644 index 0000000..3227faa --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/fmacros.h @@ -0,0 +1,12 @@ +#ifndef __HIREDIS_FMACRO_H +#define __HIREDIS_FMACRO_H + +#define _XOPEN_SOURCE 600 +#define _POSIX_C_SOURCE 200112L + +#if defined(__APPLE__) && defined(__MACH__) +/* Enable TCP_KEEPALIVE */ +#define _DARWIN_C_SOURCE +#endif + +#endif diff --git a/ext/hiredis-1.0.2/include/hiredis/hiredis.h b/ext/hiredis-1.0.2/include/hiredis/hiredis.h new file mode 100644 index 0000000..3bc46d9 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/hiredis.h @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_H +#define __HIREDIS_H +#include "read.h" +#include /* for va_list */ +#ifndef _MSC_VER +#include /* for struct timeval */ +#else +struct timeval; /* forward declaration */ +typedef long long ssize_t; +#endif +#include /* uintXX_t, etc */ +#include "sds.h" /* for sds */ +#include "alloc.h" /* for allocation wrappers */ + +#define HIREDIS_MAJOR 1 +#define HIREDIS_MINOR 0 +#define HIREDIS_PATCH 2 +#define HIREDIS_SONAME 1.0.0 + +/* Connection type can be blocking or non-blocking and is set in the + * least significant bit of the flags field in redisContext. */ +#define REDIS_BLOCK 0x1 + +/* Connection may be disconnected before being free'd. The second bit + * in the flags field is set when the context is connected. */ +#define REDIS_CONNECTED 0x2 + +/* The async API might try to disconnect cleanly and flush the output + * buffer and read all subsequent replies before disconnecting. + * This flag means no new commands can come in and the connection + * should be terminated once all replies have been read. */ +#define REDIS_DISCONNECTING 0x4 + +/* Flag specific to the async API which means that the context should be clean + * up as soon as possible. */ +#define REDIS_FREEING 0x8 + +/* Flag that is set when an async callback is executed. */ +#define REDIS_IN_CALLBACK 0x10 + +/* Flag that is set when the async context has one or more subscriptions. */ +#define REDIS_SUBSCRIBED 0x20 + +/* Flag that is set when monitor mode is active */ +#define REDIS_MONITORING 0x40 + +/* Flag that is set when we should set SO_REUSEADDR before calling bind() */ +#define REDIS_REUSEADDR 0x80 + +/** + * Flag that indicates the user does not want the context to + * be automatically freed upon error + */ +#define REDIS_NO_AUTO_FREE 0x200 + +#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ + +/* number of times we retry to connect in the case of EADDRNOTAVAIL and + * SO_REUSEADDR is being used. */ +#define REDIS_CONNECT_RETRIES 10 + +/* Forward declarations for structs defined elsewhere */ +struct redisAsyncContext; +struct redisContext; + +/* RESP3 push helpers and callback prototypes */ +#define redisIsPushReply(r) (((redisReply*)(r))->type == REDIS_REPLY_PUSH) +typedef void (redisPushFn)(void *, void *); +typedef void (redisAsyncPushFn)(struct redisAsyncContext *, void *); + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the reply object returned by redisCommand() */ +typedef struct redisReply { + int type; /* REDIS_REPLY_* */ + long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ + double dval; /* The double when type is REDIS_REPLY_DOUBLE */ + size_t len; /* Length of string */ + char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING + REDIS_REPLY_VERB, and REDIS_REPLY_DOUBLE (in additional to dval). */ + char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null + terminated 3 character content type, such as "txt". */ + size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ + struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ +} redisReply; + +redisReader *redisReaderCreate(void); + +/* Function to free the reply objects hiredis returns by default. */ +void freeReplyObject(void *reply); + +/* Functions to format a command according to the protocol. */ +int redisvFormatCommand(char **target, const char *format, va_list ap); +int redisFormatCommand(char **target, const char *format, ...); +int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); +int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); +void redisFreeCommand(char *cmd); +void redisFreeSdsCommand(sds cmd); + +enum redisConnectionType { + REDIS_CONN_TCP, + REDIS_CONN_UNIX, + REDIS_CONN_USERFD +}; + +struct redisSsl; + +#define REDIS_OPT_NONBLOCK 0x01 +#define REDIS_OPT_REUSEADDR 0x02 + +/** + * Don't automatically free the async object on a connection failure, + * or other implicit conditions. Only free on an explicit call to disconnect() or free() + */ +#define REDIS_OPT_NOAUTOFREE 0x04 + +/* Don't automatically intercept and free RESP3 PUSH replies. */ +#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08 + +/* In Unix systems a file descriptor is a regular signed int, with -1 + * representing an invalid descriptor. In Windows it is a SOCKET + * (32- or 64-bit unsigned integer depending on the architecture), where + * all bits set (~0) is INVALID_SOCKET. */ +#ifndef _WIN32 +typedef int redisFD; +#define REDIS_INVALID_FD -1 +#else +#ifdef _WIN64 +typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */ +#else +typedef unsigned long redisFD; /* SOCKET = 32-bit UINT_PTR */ +#endif +#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */ +#endif + +typedef struct { + /* + * the type of connection to use. This also indicates which + * `endpoint` member field to use + */ + int type; + /* bit field of REDIS_OPT_xxx */ + int options; + /* timeout value for connect operation. If NULL, no timeout is used */ + const struct timeval *connect_timeout; + /* timeout value for commands. If NULL, no timeout is used. This can be + * updated at runtime with redisSetTimeout/redisAsyncSetTimeout. */ + const struct timeval *command_timeout; + union { + /** use this field for tcp/ip connections */ + struct { + const char *source_addr; + const char *ip; + int port; + } tcp; + /** use this field for unix domain sockets */ + const char *unix_socket; + /** + * use this field to have hiredis operate an already-open + * file descriptor */ + redisFD fd; + } endpoint; + + /* Optional user defined data/destructor */ + void *privdata; + void (*free_privdata)(void *); + + /* A user defined PUSH message callback */ + redisPushFn *push_cb; + redisAsyncPushFn *async_push_cb; +} redisOptions; + +/** + * Helper macros to initialize options to their specified fields. + */ +#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \ + (opts)->type = REDIS_CONN_TCP; \ + (opts)->endpoint.tcp.ip = ip_; \ + (opts)->endpoint.tcp.port = port_; + +#define REDIS_OPTIONS_SET_UNIX(opts, path) \ + (opts)->type = REDIS_CONN_UNIX; \ + (opts)->endpoint.unix_socket = path; + +#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) \ + (opts)->privdata = data; \ + (opts)->free_privdata = dtor; \ + +typedef struct redisContextFuncs { + void (*free_privctx)(void *); + void (*async_read)(struct redisAsyncContext *); + void (*async_write)(struct redisAsyncContext *); + ssize_t (*read)(struct redisContext *, char *, size_t); + ssize_t (*write)(struct redisContext *); +} redisContextFuncs; + +/* Context for a connection to Redis */ +typedef struct redisContext { + const redisContextFuncs *funcs; /* Function table */ + + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + redisFD fd; + int flags; + char *obuf; /* Write buffer */ + redisReader *reader; /* Protocol reader */ + + enum redisConnectionType connection_type; + struct timeval *connect_timeout; + struct timeval *command_timeout; + + struct { + char *host; + char *source_addr; + int port; + } tcp; + + struct { + char *path; + } unix_sock; + + /* For non-blocking connect */ + struct sockadr *saddr; + size_t addrlen; + + /* Optional data and corresponding destructor users can use to provide + * context to a given redisContext. Not used by hiredis. */ + void *privdata; + void (*free_privdata)(void *); + + /* Internal context pointer presently used by hiredis to manage + * SSL connections. */ + void *privctx; + + /* An optional RESP3 PUSH handler */ + redisPushFn *push_cb; +} redisContext; + +redisContext *redisConnectWithOptions(const redisOptions *options); +redisContext *redisConnect(const char *ip, int port); +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); +redisContext *redisConnectNonBlock(const char *ip, int port); +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectUnix(const char *path); +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); +redisContext *redisConnectUnixNonBlock(const char *path); +redisContext *redisConnectFd(redisFD fd); + +/** + * Reconnect the given context using the saved information. + * + * This re-uses the exact same connect options as in the initial connection. + * host, ip (or path), timeout and bind address are reused, + * flags are used unmodified from the existing context. + * + * Returns REDIS_OK on successful connect or REDIS_ERR otherwise. + */ +int redisReconnect(redisContext *c); + +redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn); +int redisSetTimeout(redisContext *c, const struct timeval tv); +int redisEnableKeepAlive(redisContext *c); +void redisFree(redisContext *c); +redisFD redisFreeKeepFd(redisContext *c); +int redisBufferRead(redisContext *c); +int redisBufferWrite(redisContext *c, int *done); + +/* In a blocking context, this function first checks if there are unconsumed + * replies to return and returns one if so. Otherwise, it flushes the output + * buffer to the socket and reads until it has a reply. In a non-blocking + * context, it will return unconsumed replies until there are no more. */ +int redisGetReply(redisContext *c, void **reply); +int redisGetReplyFromReader(redisContext *c, void **reply); + +/* Write a formatted command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); + +/* Write a command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisvAppendCommand(redisContext *c, const char *format, va_list ap); +int redisAppendCommand(redisContext *c, const char *format, ...); +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +/* Issue a command to Redis. In a blocking context, it is identical to calling + * redisAppendCommand, followed by redisGetReply. The function will return + * NULL if there was an error in performing the request, otherwise it will + * return the reply. In a non-blocking context, it is identical to calling + * only redisAppendCommand and will always return NULL. */ +void *redisvCommand(redisContext *c, const char *format, va_list ap); +void *redisCommand(redisContext *c, const char *format, ...); +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-1.0.2/include/hiredis/hiredis_ssl.h b/ext/hiredis-1.0.2/include/hiredis/hiredis_ssl.h new file mode 100644 index 0000000..604efe0 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/hiredis_ssl.h @@ -0,0 +1,127 @@ + +/* + * Copyright (c) 2019, Redis Labs + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_SSL_H +#define __HIREDIS_SSL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the underlying struct for SSL in ssl.h, which is not included to + * keep build dependencies short here. + */ +struct ssl_st; + +/* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly + * calling OpenSSL. + */ +typedef struct redisSSLContext redisSSLContext; + +/** + * Initialization errors that redisCreateSSLContext() may return. + */ + +typedef enum { + REDIS_SSL_CTX_NONE = 0, /* No Error */ + REDIS_SSL_CTX_CREATE_FAILED, /* Failed to create OpenSSL SSL_CTX */ + REDIS_SSL_CTX_CERT_KEY_REQUIRED, /* Client cert and key must both be specified or skipped */ + REDIS_SSL_CTX_CA_CERT_LOAD_FAILED, /* Failed to load CA Certificate or CA Path */ + REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED, /* Failed to load client certificate */ + REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED /* Failed to load private key */ +} redisSSLContextError; + +/** + * Return the error message corresponding with the specified error code. + */ + +const char *redisSSLContextGetError(redisSSLContextError error); + +/** + * Helper function to initialize the OpenSSL library. + * + * OpenSSL requires one-time initialization before it can be used. Callers should + * call this function only once, and only if OpenSSL is not directly initialized + * elsewhere. + */ +int redisInitOpenSSL(void); + +/** + * Helper function to initialize an OpenSSL context that can be used + * to initiate SSL connections. + * + * cacert_filename is an optional name of a CA certificate/bundle file to load + * and use for validation. + * + * capath is an optional directory path where trusted CA certificate files are + * stored in an OpenSSL-compatible structure. + * + * cert_filename and private_key_filename are optional names of a client side + * certificate and private key files to use for authentication. They need to + * be both specified or omitted. + * + * server_name is an optional and will be used as a server name indication + * (SNI) TLS extension. + * + * If error is non-null, it will be populated in case the context creation fails + * (returning a NULL). + */ + +redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath, + const char *cert_filename, const char *private_key_filename, + const char *server_name, redisSSLContextError *error); + +/** + * Free a previously created OpenSSL context. + */ +void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx); + +/** + * Initiate SSL on an existing redisContext. + * + * This is similar to redisInitiateSSL() but does not require the caller + * to directly interact with OpenSSL, and instead uses a redisSSLContext + * previously created using redisCreateSSLContext(). + */ + +int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx); + +/** + * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object. + */ + +int redisInitiateSSL(redisContext *c, struct ssl_st *ssl); + +#ifdef __cplusplus +} +#endif + +#endif /* __HIREDIS_SSL_H */ diff --git a/ext/hiredis-1.0.2/include/hiredis/net.h b/ext/hiredis-1.0.2/include/hiredis/net.h new file mode 100644 index 0000000..9f43283 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/net.h @@ -0,0 +1,56 @@ +/* Extracted from anet.c to work properly with Hiredis error reporting. + * + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __NET_H +#define __NET_H + +#include "hiredis.h" + +void redisNetClose(redisContext *c); +ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap); +ssize_t redisNetWrite(redisContext *c); + +int redisCheckSocketError(redisContext *c); +int redisContextSetTimeout(redisContext *c, const struct timeval tv); +int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); +int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr); +int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); +int redisKeepAlive(redisContext *c, int interval); +int redisCheckConnectDone(redisContext *c, int *completed); + +int redisSetTcpNoDelay(redisContext *c); + +#endif diff --git a/ext/hiredis-1.0.2/include/hiredis/read.h b/ext/hiredis-1.0.2/include/hiredis/read.h new file mode 100644 index 0000000..2d74d77 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/read.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __HIREDIS_READ_H +#define __HIREDIS_READ_H +#include /* for size_t */ + +#define REDIS_ERR -1 +#define REDIS_OK 0 + +/* When an error occurs, the err flag in a context is set to hold the type of + * error that occurred. REDIS_ERR_IO means there was an I/O error and you + * should use the "errno" variable to find out what is wrong. + * For other values, the "errstr" field will hold a description. */ +#define REDIS_ERR_IO 1 /* Error in read or write */ +#define REDIS_ERR_EOF 3 /* End of file */ +#define REDIS_ERR_PROTOCOL 4 /* Protocol error */ +#define REDIS_ERR_OOM 5 /* Out of memory */ +#define REDIS_ERR_TIMEOUT 6 /* Timed out */ +#define REDIS_ERR_OTHER 2 /* Everything else... */ + +#define REDIS_REPLY_STRING 1 +#define REDIS_REPLY_ARRAY 2 +#define REDIS_REPLY_INTEGER 3 +#define REDIS_REPLY_NIL 4 +#define REDIS_REPLY_STATUS 5 +#define REDIS_REPLY_ERROR 6 +#define REDIS_REPLY_DOUBLE 7 +#define REDIS_REPLY_BOOL 8 +#define REDIS_REPLY_MAP 9 +#define REDIS_REPLY_SET 10 +#define REDIS_REPLY_ATTR 11 +#define REDIS_REPLY_PUSH 12 +#define REDIS_REPLY_BIGNUM 13 +#define REDIS_REPLY_VERB 14 + +/* Default max unused reader buffer. */ +#define REDIS_READER_MAX_BUF (1024*16) + +/* Default multi-bulk element limit */ +#define REDIS_READER_MAX_ARRAY_ELEMENTS ((1LL<<32) - 1) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct redisReadTask { + int type; + long long elements; /* number of elements in multibulk container */ + int idx; /* index in parent (array) object */ + void *obj; /* holds user-generated value for a read task */ + struct redisReadTask *parent; /* parent task */ + void *privdata; /* user-settable arbitrary field */ +} redisReadTask; + +typedef struct redisReplyObjectFunctions { + void *(*createString)(const redisReadTask*, char*, size_t); + void *(*createArray)(const redisReadTask*, size_t); + void *(*createInteger)(const redisReadTask*, long long); + void *(*createDouble)(const redisReadTask*, double, char*, size_t); + void *(*createNil)(const redisReadTask*); + void *(*createBool)(const redisReadTask*, int); + void (*freeObject)(void*); +} redisReplyObjectFunctions; + +typedef struct redisReader { + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + + char *buf; /* Read buffer */ + size_t pos; /* Buffer cursor */ + size_t len; /* Buffer length */ + size_t maxbuf; /* Max length of unused buffer */ + long long maxelements; /* Max multi-bulk elements */ + + redisReadTask **task; + int tasks; + + int ridx; /* Index of current read task */ + void *reply; /* Temporary reply pointer */ + + redisReplyObjectFunctions *fn; + void *privdata; +} redisReader; + +/* Public API for the protocol parser. */ +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); +void redisReaderFree(redisReader *r); +int redisReaderFeed(redisReader *r, const char *buf, size_t len); +int redisReaderGetReply(redisReader *r, void **reply); + +#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) +#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) +#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-1.0.2/include/hiredis/sds.h b/ext/hiredis-1.0.2/include/hiredis/sds.h new file mode 100644 index 0000000..eda8833 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/sds.h @@ -0,0 +1,278 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SDS_H +#define __SDS_H + +#define SDS_MAX_PREALLOC (1024*1024) +#ifdef _MSC_VER +#define __attribute__(x) +typedef long long ssize_t; +#define SSIZE_MAX (LLONG_MAX >> 1) +#endif + +#include +#include +#include + +typedef char *sds; + +/* Note: sdshdr5 is never used, we just access the flags byte directly. + * However is here to document the layout of type 5 SDS strings. */ +struct __attribute__ ((__packed__)) sdshdr5 { + unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr8 { + uint8_t len; /* used */ + uint8_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr16 { + uint16_t len; /* used */ + uint16_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr32 { + uint32_t len; /* used */ + uint32_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr64 { + uint64_t len; /* used */ + uint64_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; + +#define SDS_TYPE_5 0 +#define SDS_TYPE_8 1 +#define SDS_TYPE_16 2 +#define SDS_TYPE_32 3 +#define SDS_TYPE_64 4 +#define SDS_TYPE_MASK 7 +#define SDS_TYPE_BITS 3 +#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))); +#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)))) +#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) + +static inline size_t sdslen(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->len; + case SDS_TYPE_16: + return SDS_HDR(16,s)->len; + case SDS_TYPE_32: + return SDS_HDR(32,s)->len; + case SDS_TYPE_64: + return SDS_HDR(64,s)->len; + } + return 0; +} + +static inline size_t sdsavail(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + return 0; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + return sh->alloc - sh->len; + } + } + return 0; +} + +static inline void sdssetlen(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + *fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS)); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len = (uint8_t)newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len = (uint16_t)newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len = (uint32_t)newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len = (uint64_t)newlen; + break; + } +} + +static inline void sdsinclen(sds s, size_t inc) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc; + *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len += (uint8_t)inc; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len += (uint16_t)inc; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len += (uint32_t)inc; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len += (uint64_t)inc; + break; + } +} + +/* sdsalloc() = sdsavail() + sdslen() */ +static inline size_t sdsalloc(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->alloc; + case SDS_TYPE_16: + return SDS_HDR(16,s)->alloc; + case SDS_TYPE_32: + return SDS_HDR(32,s)->alloc; + case SDS_TYPE_64: + return SDS_HDR(64,s)->alloc; + } + return 0; +} + +static inline void sdssetalloc(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + /* Nothing to do, this type has no total allocation info. */ + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->alloc = (uint8_t)newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->alloc = (uint16_t)newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->alloc = (uint32_t)newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->alloc = (uint64_t)newlen; + break; + } +} + +sds sdsnewlen(const void *init, size_t initlen); +sds sdsnew(const char *init); +sds sdsempty(void); +sds sdsdup(const sds s); +void sdsfree(sds s); +sds sdsgrowzero(sds s, size_t len); +sds sdscatlen(sds s, const void *t, size_t len); +sds sdscat(sds s, const char *t); +sds sdscatsds(sds s, const sds t); +sds sdscpylen(sds s, const char *t, size_t len); +sds sdscpy(sds s, const char *t); + +sds sdscatvprintf(sds s, const char *fmt, va_list ap); +#ifdef __GNUC__ +sds sdscatprintf(sds s, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +#else +sds sdscatprintf(sds s, const char *fmt, ...); +#endif + +sds sdscatfmt(sds s, char const *fmt, ...); +sds sdstrim(sds s, const char *cset); +int sdsrange(sds s, ssize_t start, ssize_t end); +void sdsupdatelen(sds s); +void sdsclear(sds s); +int sdscmp(const sds s1, const sds s2); +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count); +void sdsfreesplitres(sds *tokens, int count); +void sdstolower(sds s); +void sdstoupper(sds s); +sds sdsfromlonglong(long long value); +sds sdscatrepr(sds s, const char *p, size_t len); +sds *sdssplitargs(const char *line, int *argc); +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); +sds sdsjoin(char **argv, int argc, char *sep); +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen); + +/* Low level functions exposed to the user API */ +sds sdsMakeRoomFor(sds s, size_t addlen); +void sdsIncrLen(sds s, int incr); +sds sdsRemoveFreeSpace(sds s); +size_t sdsAllocSize(sds s); +void *sdsAllocPtr(sds s); + +/* Export the allocator used by SDS to the program using SDS. + * Sometimes the program SDS is linked to, may use a different set of + * allocators, but may want to allocate or free things that SDS will + * respectively free or allocate. */ +void *sds_malloc(size_t size); +void *sds_realloc(void *ptr, size_t size); +void sds_free(void *ptr); + +#ifdef REDIS_TEST +int sdsTest(int argc, char *argv[]); +#endif + +#endif diff --git a/ext/hiredis-1.0.2/include/hiredis/sdsalloc.h b/ext/hiredis-1.0.2/include/hiredis/sdsalloc.h new file mode 100644 index 0000000..5538dd9 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/sdsalloc.h @@ -0,0 +1,44 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* SDS allocator selection. + * + * This file is used in order to change the SDS allocator at compile time. + * Just define the following defines to what you want to use. Also add + * the include of your alternate allocator if needed (not needed in order + * to use the default libc allocator). */ + +#include "alloc.h" + +#define s_malloc hi_malloc +#define s_realloc hi_realloc +#define s_free hi_free diff --git a/ext/hiredis-1.0.2/include/hiredis/sockcompat.h b/ext/hiredis-1.0.2/include/hiredis/sockcompat.h new file mode 100644 index 0000000..85810e8 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/sockcompat.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019, Marcus Geelnard + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SOCKCOMPAT_H +#define __SOCKCOMPAT_H + +#ifndef _WIN32 +/* For POSIX systems we use the standard BSD socket API. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +/* For Windows we use winsock. */ +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 /* To get WSAPoll etc. */ +#include +#include +#include +#include + +#ifdef _MSC_VER +typedef long long ssize_t; +#endif + +/* Emulate the parts of the BSD socket API that we need (override the winsock signatures). */ +int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); +const char *win32_gai_strerror(int errcode); +void win32_freeaddrinfo(struct addrinfo *res); +SOCKET win32_socket(int domain, int type, int protocol); +int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp); +int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); +int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); +int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen); +int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen); +int win32_close(SOCKET fd); +ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags); +ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags); +typedef ULONG nfds_t; +int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout); + +#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION +#define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res) +#undef gai_strerror +#define gai_strerror(errcode) win32_gai_strerror(errcode) +#define freeaddrinfo(res) win32_freeaddrinfo(res) +#define socket(domain, type, protocol) win32_socket(domain, type, protocol) +#define ioctl(fd, request, argp) win32_ioctl(fd, request, argp) +#define bind(sockfd, addr, addrlen) win32_bind(sockfd, addr, addrlen) +#define connect(sockfd, addr, addrlen) win32_connect(sockfd, addr, addrlen) +#define getsockopt(sockfd, level, optname, optval, optlen) win32_getsockopt(sockfd, level, optname, optval, optlen) +#define setsockopt(sockfd, level, optname, optval, optlen) win32_setsockopt(sockfd, level, optname, optval, optlen) +#define close(fd) win32_close(fd) +#define recv(sockfd, buf, len, flags) win32_recv(sockfd, buf, len, flags) +#define send(sockfd, buf, len, flags) win32_send(sockfd, buf, len, flags) +#define poll(fds, nfds, timeout) win32_poll(fds, nfds, timeout) +#endif /* REDIS_SOCKCOMPAT_IMPLEMENTATION */ +#endif /* _WIN32 */ + +#endif /* __SOCKCOMPAT_H */ diff --git a/ext/hiredis-1.0.2/include/hiredis/win32.h b/ext/hiredis-1.0.2/include/hiredis/win32.h new file mode 100644 index 0000000..04289c6 --- /dev/null +++ b/ext/hiredis-1.0.2/include/hiredis/win32.h @@ -0,0 +1,56 @@ +#ifndef _WIN32_HELPER_INCLUDE +#define _WIN32_HELPER_INCLUDE +#ifdef _MSC_VER + +#include /* for struct timeval */ + +#ifndef inline +#define inline __inline +#endif + +#ifndef strcasecmp +#define strcasecmp stricmp +#endif + +#ifndef strncasecmp +#define strncasecmp strnicmp +#endif + +#ifndef va_copy +#define va_copy(d,s) ((d) = (s)) +#endif + +#ifndef snprintf +#define snprintf c99_snprintf + +__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +__inline int c99_snprintf(char* str, size_t size, const char* format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} +#endif +#endif /* _MSC_VER */ + +#ifdef _WIN32 +#define strerror_r(errno,buf,len) strerror_s(buf,len,errno) +#endif /* _WIN32 */ + +#endif /* _WIN32_HELPER_INCLUDE */ diff --git a/ext/hiredis-1.0.2/lib/ubuntu22.04/amd64/libhiredis.a b/ext/hiredis-1.0.2/lib/ubuntu22.04/amd64/libhiredis.a new file mode 100644 index 0000000000000000000000000000000000000000..af1314f019db5c13386e6fd2a518de119e778076 GIT binary patch literal 557016 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%0A&MWMq<|8VRm#4mQM}4x6%& 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

    7l613-v|i<9{@_j6;9K03 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

    v^zfv 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 RB-EGXv(8mWp9{_ZKLCSuw1fZv literal 0 HcmV?d00001 diff --git a/ext/hiredis-1.0.2/lib/ubuntu22.04/arm64/libhiredis.a b/ext/hiredis-1.0.2/lib/ubuntu22.04/arm64/libhiredis.a new file mode 100644 index 0000000000000000000000000000000000000000..081c92705dfdb5a83b5768db78d88f07d002b8c0 GIT binary patch literal 495416 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 PZ{Ys3qgU?J`^x_hY1ET< literal 0 HcmV?d00001 diff --git a/ext/hiredis-1.0.2/net.c b/ext/hiredis-1.0.2/net.c new file mode 100644 index 0000000..c6b0e5d --- /dev/null +++ b/ext/hiredis-1.0.2/net.c @@ -0,0 +1,612 @@ +/* Extracted from anet.c to work properly with Hiredis error reporting. + * + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "net.h" +#include "sds.h" +#include "sockcompat.h" +#include "win32.h" + +/* Defined in hiredis.c */ +void __redisSetError(redisContext *c, int type, const char *str); + +void redisNetClose(redisContext *c) { + if (c && c->fd != REDIS_INVALID_FD) { + close(c->fd); + c->fd = REDIS_INVALID_FD; + } +} + +ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap) { + ssize_t nread = recv(c->fd, buf, bufcap, 0); + if (nread == -1) { + if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { + /* Try again later */ + return 0; + } else if(errno == ETIMEDOUT && (c->flags & REDIS_BLOCK)) { + /* especially in windows */ + __redisSetError(c, REDIS_ERR_TIMEOUT, "recv timeout"); + return -1; + } else { + __redisSetError(c, REDIS_ERR_IO, NULL); + return -1; + } + } else if (nread == 0) { + __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection"); + return -1; + } else { + return nread; + } +} + +ssize_t redisNetWrite(redisContext *c) { + ssize_t nwritten = send(c->fd, c->obuf, sdslen(c->obuf), 0); + if (nwritten < 0) { + if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { + /* Try again later */ + } else { + __redisSetError(c, REDIS_ERR_IO, NULL); + return -1; + } + } + return nwritten; +} + +static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) { + int errorno = errno; /* snprintf() may change errno */ + char buf[128] = { 0 }; + size_t len = 0; + + if (prefix != NULL) + len = snprintf(buf,sizeof(buf),"%s: ",prefix); + strerror_r(errorno, (char *)(buf + len), sizeof(buf) - len); + __redisSetError(c,type,buf); +} + +static int redisSetReuseAddr(redisContext *c) { + int on = 1; + if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisNetClose(c); + return REDIS_ERR; + } + return REDIS_OK; +} + +static int redisCreateSocket(redisContext *c, int type) { + redisFD s; + if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + return REDIS_ERR; + } + c->fd = s; + if (type == AF_INET) { + if (redisSetReuseAddr(c) == REDIS_ERR) { + return REDIS_ERR; + } + } + return REDIS_OK; +} + +static int redisSetBlocking(redisContext *c, int blocking) { +#ifndef _WIN32 + int flags; + + /* Set the socket nonblocking. + * Note that fcntl(2) for F_GETFL and F_SETFL can't be + * interrupted by a signal. */ + if ((flags = fcntl(c->fd, F_GETFL)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); + redisNetClose(c); + return REDIS_ERR; + } + + if (blocking) + flags &= ~O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (fcntl(c->fd, F_SETFL, flags) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); + redisNetClose(c); + return REDIS_ERR; + } +#else + u_long mode = blocking ? 0 : 1; + if (ioctl(c->fd, FIONBIO, &mode) == -1) { + __redisSetErrorFromErrno(c, REDIS_ERR_IO, "ioctl(FIONBIO)"); + redisNetClose(c); + return REDIS_ERR; + } +#endif /* _WIN32 */ + return REDIS_OK; +} + +int redisKeepAlive(redisContext *c, int interval) { + int val = 1; + redisFD fd = c->fd; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){ + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = interval; + +#if defined(__APPLE__) && defined(__MACH__) + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } +#else +#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = interval/3; + if (val == 0) val = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = 3; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } +#endif +#endif + + return REDIS_OK; +} + +int redisSetTcpNoDelay(redisContext *c) { + int yes = 1; + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); + redisNetClose(c); + return REDIS_ERR; + } + return REDIS_OK; +} + +#define __MAX_MSEC (((LONG_MAX) - 999) / 1000) + +static int redisContextTimeoutMsec(redisContext *c, long *result) +{ + const struct timeval *timeout = c->connect_timeout; + long msec = -1; + + /* Only use timeout when not NULL. */ + if (timeout != NULL) { + if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { + *result = msec; + return REDIS_ERR; + } + + msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000); + + if (msec < 0 || msec > INT_MAX) { + msec = INT_MAX; + } + } + + *result = msec; + return REDIS_OK; +} + +static int redisContextWaitReady(redisContext *c, long msec) { + struct pollfd wfd[1]; + + wfd[0].fd = c->fd; + wfd[0].events = POLLOUT; + + if (errno == EINPROGRESS) { + int res; + + if ((res = poll(wfd, 1, msec)) == -1) { + __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); + redisNetClose(c); + return REDIS_ERR; + } else if (res == 0) { + errno = ETIMEDOUT; + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisNetClose(c); + return REDIS_ERR; + } + + if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) { + redisCheckSocketError(c); + return REDIS_ERR; + } + + return REDIS_OK; + } + + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisNetClose(c); + return REDIS_ERR; +} + +int redisCheckConnectDone(redisContext *c, int *completed) { + int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen); + if (rc == 0) { + *completed = 1; + return REDIS_OK; + } + switch (errno) { + case EISCONN: + *completed = 1; + return REDIS_OK; + case EALREADY: + case EINPROGRESS: + case EWOULDBLOCK: + *completed = 0; + return REDIS_OK; + default: + return REDIS_ERR; + } +} + +int redisCheckSocketError(redisContext *c) { + int err = 0, errno_saved = errno; + socklen_t errlen = sizeof(err); + + if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)"); + return REDIS_ERR; + } + + if (err == 0) { + err = errno_saved; + } + + if (err) { + errno = err; + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + return REDIS_ERR; + } + + return REDIS_OK; +} + +int redisContextSetTimeout(redisContext *c, const struct timeval tv) { + const void *to_ptr = &tv; + size_t to_sz = sizeof(tv); + + if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,to_ptr,to_sz) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)"); + return REDIS_ERR; + } + if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,to_ptr,to_sz) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)"); + return REDIS_ERR; + } + return REDIS_OK; +} + +int redisContextUpdateConnectTimeout(redisContext *c, const struct timeval *timeout) { + /* Same timeval struct, short circuit */ + if (c->connect_timeout == timeout) + return REDIS_OK; + + /* Allocate context timeval if we need to */ + if (c->connect_timeout == NULL) { + c->connect_timeout = hi_malloc(sizeof(*c->connect_timeout)); + if (c->connect_timeout == NULL) + return REDIS_ERR; + } + + memcpy(c->connect_timeout, timeout, sizeof(*c->connect_timeout)); + return REDIS_OK; +} + +int redisContextUpdateCommandTimeout(redisContext *c, const struct timeval *timeout) { + /* Same timeval struct, short circuit */ + if (c->command_timeout == timeout) + return REDIS_OK; + + /* Allocate context timeval if we need to */ + if (c->command_timeout == NULL) { + c->command_timeout = hi_malloc(sizeof(*c->command_timeout)); + if (c->command_timeout == NULL) + return REDIS_ERR; + } + + memcpy(c->command_timeout, timeout, sizeof(*c->command_timeout)); + return REDIS_OK; +} + +static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr) { + redisFD s; + int rv, n; + char _port[6]; /* strlen("65535"); */ + struct addrinfo hints, *servinfo, *bservinfo, *p, *b; + int blocking = (c->flags & REDIS_BLOCK); + int reuseaddr = (c->flags & REDIS_REUSEADDR); + int reuses = 0; + long timeout_msec = -1; + + servinfo = NULL; + c->connection_type = REDIS_CONN_TCP; + c->tcp.port = port; + + /* We need to take possession of the passed parameters + * to make them reusable for a reconnect. + * We also carefully check we don't free data we already own, + * as in the case of the reconnect method. + * + * This is a bit ugly, but atleast it works and doesn't leak memory. + **/ + if (c->tcp.host != addr) { + hi_free(c->tcp.host); + + c->tcp.host = hi_strdup(addr); + if (c->tcp.host == NULL) + goto oom; + } + + if (timeout) { + if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR) + goto oom; + } else { + hi_free(c->connect_timeout); + c->connect_timeout = NULL; + } + + if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) { + __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified"); + goto error; + } + + if (source_addr == NULL) { + hi_free(c->tcp.source_addr); + c->tcp.source_addr = NULL; + } else if (c->tcp.source_addr != source_addr) { + hi_free(c->tcp.source_addr); + c->tcp.source_addr = hi_strdup(source_addr); + } + + snprintf(_port, 6, "%d", port); + memset(&hints,0,sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + /* Try with IPv6 if no IPv4 address was found. We do it in this order since + * in a Redis client you can't afford to test if you have IPv6 connectivity + * as this would add latency to every connect. Otherwise a more sensible + * route could be: Use IPv6 if both addresses are available and there is IPv6 + * connectivity. */ + if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) { + hints.ai_family = AF_INET6; + if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { + __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); + return REDIS_ERR; + } + } + for (p = servinfo; p != NULL; p = p->ai_next) { +addrretry: + if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == REDIS_INVALID_FD) + continue; + + c->fd = s; + if (redisSetBlocking(c,0) != REDIS_OK) + goto error; + if (c->tcp.source_addr) { + int bound = 0; + /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ + if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + + if (reuseaddr) { + n = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n, + sizeof(n)) < 0) { + freeaddrinfo(bservinfo); + goto error; + } + } + + for (b = bservinfo; b != NULL; b = b->ai_next) { + if (bind(s,b->ai_addr,b->ai_addrlen) != -1) { + bound = 1; + break; + } + } + freeaddrinfo(bservinfo); + if (!bound) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + } + + /* For repeat connection */ + hi_free(c->saddr); + c->saddr = hi_malloc(p->ai_addrlen); + if (c->saddr == NULL) + goto oom; + + memcpy(c->saddr, p->ai_addr, p->ai_addrlen); + c->addrlen = p->ai_addrlen; + + if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { + if (errno == EHOSTUNREACH) { + redisNetClose(c); + continue; + } else if (errno == EINPROGRESS) { + if (blocking) { + goto wait_for_ready; + } + /* This is ok. + * Note that even when it's in blocking mode, we unset blocking + * for `connect()` + */ + } else if (errno == EADDRNOTAVAIL && reuseaddr) { + if (++reuses >= REDIS_CONNECT_RETRIES) { + goto error; + } else { + redisNetClose(c); + goto addrretry; + } + } else { + wait_for_ready: + if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) + goto error; + if (redisSetTcpNoDelay(c) != REDIS_OK) + goto error; + } + } + if (blocking && redisSetBlocking(c,1) != REDIS_OK) + goto error; + + c->flags |= REDIS_CONNECTED; + rv = REDIS_OK; + goto end; + } + if (p == NULL) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + +oom: + __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); +error: + rv = REDIS_ERR; +end: + if(servinfo) { + freeaddrinfo(servinfo); + } + + return rv; // Need to return REDIS_OK if alright +} + +int redisContextConnectTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout) { + return _redisContextConnectTcp(c, addr, port, timeout, NULL); +} + +int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr) { + return _redisContextConnectTcp(c, addr, port, timeout, source_addr); +} + +int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) { +#ifndef _WIN32 + int blocking = (c->flags & REDIS_BLOCK); + struct sockaddr_un *sa; + long timeout_msec = -1; + + if (redisCreateSocket(c,AF_UNIX) < 0) + return REDIS_ERR; + if (redisSetBlocking(c,0) != REDIS_OK) + return REDIS_ERR; + + c->connection_type = REDIS_CONN_UNIX; + if (c->unix_sock.path != path) { + hi_free(c->unix_sock.path); + + c->unix_sock.path = hi_strdup(path); + if (c->unix_sock.path == NULL) + goto oom; + } + + if (timeout) { + if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR) + goto oom; + } else { + hi_free(c->connect_timeout); + c->connect_timeout = NULL; + } + + if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK) + return REDIS_ERR; + + /* Don't leak sockaddr if we're reconnecting */ + if (c->saddr) hi_free(c->saddr); + + sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un))); + if (sa == NULL) + goto oom; + + c->addrlen = sizeof(struct sockaddr_un); + sa->sun_family = AF_UNIX; + strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1); + if (connect(c->fd, (struct sockaddr*)sa, sizeof(*sa)) == -1) { + if (errno == EINPROGRESS && !blocking) { + /* This is ok. */ + } else { + if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) + return REDIS_ERR; + } + } + + /* Reset socket to be blocking after connect(2). */ + if (blocking && redisSetBlocking(c,1) != REDIS_OK) + return REDIS_ERR; + + c->flags |= REDIS_CONNECTED; + return REDIS_OK; +#else + /* We currently do not support Unix sockets for Windows. */ + /* TODO(m): https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ */ + errno = EPROTONOSUPPORT; + return REDIS_ERR; +#endif /* _WIN32 */ +oom: + __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); + return REDIS_ERR; +} diff --git a/ext/hiredis-1.0.2/net.h b/ext/hiredis-1.0.2/net.h new file mode 100644 index 0000000..9f43283 --- /dev/null +++ b/ext/hiredis-1.0.2/net.h @@ -0,0 +1,56 @@ +/* Extracted from anet.c to work properly with Hiredis error reporting. + * + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __NET_H +#define __NET_H + +#include "hiredis.h" + +void redisNetClose(redisContext *c); +ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap); +ssize_t redisNetWrite(redisContext *c); + +int redisCheckSocketError(redisContext *c); +int redisContextSetTimeout(redisContext *c, const struct timeval tv); +int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); +int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr); +int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); +int redisKeepAlive(redisContext *c, int interval); +int redisCheckConnectDone(redisContext *c, int *completed); + +int redisSetTcpNoDelay(redisContext *c); + +#endif diff --git a/ext/hiredis-1.0.2/read.c b/ext/hiredis-1.0.2/read.c new file mode 100644 index 0000000..0952469 --- /dev/null +++ b/ext/hiredis-1.0.2/read.c @@ -0,0 +1,739 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include +#include +#ifndef _MSC_VER +#include +#include +#endif +#include +#include +#include +#include +#include + +#include "alloc.h" +#include "read.h" +#include "sds.h" +#include "win32.h" + +/* Initial size of our nested reply stack and how much we grow it when needd */ +#define REDIS_READER_STACK_SIZE 9 + +static void __redisReaderSetError(redisReader *r, int type, const char *str) { + size_t len; + + if (r->reply != NULL && r->fn && r->fn->freeObject) { + r->fn->freeObject(r->reply); + r->reply = NULL; + } + + /* Clear input buffer on errors. */ + sdsfree(r->buf); + r->buf = NULL; + r->pos = r->len = 0; + + /* Reset task stack. */ + r->ridx = -1; + + /* Set error. */ + r->err = type; + len = strlen(str); + len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1); + memcpy(r->errstr,str,len); + r->errstr[len] = '\0'; +} + +static size_t chrtos(char *buf, size_t size, char byte) { + size_t len = 0; + + switch(byte) { + case '\\': + case '"': + len = snprintf(buf,size,"\"\\%c\"",byte); + break; + case '\n': len = snprintf(buf,size,"\"\\n\""); break; + case '\r': len = snprintf(buf,size,"\"\\r\""); break; + case '\t': len = snprintf(buf,size,"\"\\t\""); break; + case '\a': len = snprintf(buf,size,"\"\\a\""); break; + case '\b': len = snprintf(buf,size,"\"\\b\""); break; + default: + if (isprint(byte)) + len = snprintf(buf,size,"\"%c\"",byte); + else + len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte); + break; + } + + return len; +} + +static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) { + char cbuf[8], sbuf[128]; + + chrtos(cbuf,sizeof(cbuf),byte); + snprintf(sbuf,sizeof(sbuf), + "Protocol error, got %s as reply type byte", cbuf); + __redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf); +} + +static void __redisReaderSetErrorOOM(redisReader *r) { + __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory"); +} + +static char *readBytes(redisReader *r, unsigned int bytes) { + char *p; + if (r->len-r->pos >= bytes) { + p = r->buf+r->pos; + r->pos += bytes; + return p; + } + return NULL; +} + +/* Find pointer to \r\n. */ +static char *seekNewline(char *s, size_t len) { + int pos = 0; + int _len = len-1; + + /* Position should be < len-1 because the character at "pos" should be + * followed by a \n. Note that strchr cannot be used because it doesn't + * allow to search a limited length and the buffer that is being searched + * might not have a trailing NULL character. */ + while (pos < _len) { + while(pos < _len && s[pos] != '\r') pos++; + if (pos==_len) { + /* Not found. */ + return NULL; + } else { + if (s[pos+1] == '\n') { + /* Found. */ + return s+pos; + } else { + /* Continue searching. */ + pos++; + } + } + } + return NULL; +} + +/* Convert a string into a long long. Returns REDIS_OK if the string could be + * parsed into a (non-overflowing) long long, REDIS_ERR otherwise. The value + * will be set to the parsed value when appropriate. + * + * Note that this function demands that the string strictly represents + * a long long: no spaces or other characters before or after the string + * representing the number are accepted, nor zeroes at the start if not + * for the string "0" representing the zero number. + * + * Because of its strictness, it is safe to use this function to check if + * you can convert a string into a long long, and obtain back the string + * from the number without any loss in the string representation. */ +static int string2ll(const char *s, size_t slen, long long *value) { + const char *p = s; + size_t plen = 0; + int negative = 0; + unsigned long long v; + + if (plen == slen) + return REDIS_ERR; + + /* Special case: first and only digit is 0. */ + if (slen == 1 && p[0] == '0') { + if (value != NULL) *value = 0; + return REDIS_OK; + } + + if (p[0] == '-') { + negative = 1; + p++; plen++; + + /* Abort on only a negative sign. */ + if (plen == slen) + return REDIS_ERR; + } + + /* First digit should be 1-9, otherwise the string should just be 0. */ + if (p[0] >= '1' && p[0] <= '9') { + v = p[0]-'0'; + p++; plen++; + } else if (p[0] == '0' && slen == 1) { + *value = 0; + return REDIS_OK; + } else { + return REDIS_ERR; + } + + while (plen < slen && p[0] >= '0' && p[0] <= '9') { + if (v > (ULLONG_MAX / 10)) /* Overflow. */ + return REDIS_ERR; + v *= 10; + + if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */ + return REDIS_ERR; + v += p[0]-'0'; + + p++; plen++; + } + + /* Return if not all bytes were used. */ + if (plen < slen) + return REDIS_ERR; + + if (negative) { + if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */ + return REDIS_ERR; + if (value != NULL) *value = -v; + } else { + if (v > LLONG_MAX) /* Overflow. */ + return REDIS_ERR; + if (value != NULL) *value = v; + } + return REDIS_OK; +} + +static char *readLine(redisReader *r, int *_len) { + char *p, *s; + int len; + + p = r->buf+r->pos; + s = seekNewline(p,(r->len-r->pos)); + if (s != NULL) { + len = s-(r->buf+r->pos); + r->pos += len+2; /* skip \r\n */ + if (_len) *_len = len; + return p; + } + return NULL; +} + +static void moveToNextTask(redisReader *r) { + redisReadTask *cur, *prv; + while (r->ridx >= 0) { + /* Return a.s.a.p. when the stack is now empty. */ + if (r->ridx == 0) { + r->ridx--; + return; + } + + cur = r->task[r->ridx]; + prv = r->task[r->ridx-1]; + assert(prv->type == REDIS_REPLY_ARRAY || + prv->type == REDIS_REPLY_MAP || + prv->type == REDIS_REPLY_SET || + prv->type == REDIS_REPLY_PUSH); + if (cur->idx == prv->elements-1) { + r->ridx--; + } else { + /* Reset the type because the next item can be anything */ + assert(cur->idx < prv->elements); + cur->type = -1; + cur->elements = -1; + cur->idx++; + return; + } + } +} + +static int processLineItem(redisReader *r) { + redisReadTask *cur = r->task[r->ridx]; + void *obj; + char *p; + int len; + + if ((p = readLine(r,&len)) != NULL) { + if (cur->type == REDIS_REPLY_INTEGER) { + if (r->fn && r->fn->createInteger) { + long long v; + if (string2ll(p, len, &v) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad integer value"); + return REDIS_ERR; + } + obj = r->fn->createInteger(cur,v); + } else { + obj = (void*)REDIS_REPLY_INTEGER; + } + } else if (cur->type == REDIS_REPLY_DOUBLE) { + if (r->fn && r->fn->createDouble) { + char buf[326], *eptr; + double d; + + if ((size_t)len >= sizeof(buf)) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Double value is too large"); + return REDIS_ERR; + } + + memcpy(buf,p,len); + buf[len] = '\0'; + + if (strcasecmp(buf,",inf") == 0) { + d = INFINITY; /* Positive infinite. */ + } else if (strcasecmp(buf,",-inf") == 0) { + d = -INFINITY; /* Negative infinite. */ + } else { + d = strtod((char*)buf,&eptr); + if (buf[0] == '\0' || eptr[0] != '\0' || isnan(d)) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad double value"); + return REDIS_ERR; + } + } + obj = r->fn->createDouble(cur,d,buf,len); + } else { + obj = (void*)REDIS_REPLY_DOUBLE; + } + } else if (cur->type == REDIS_REPLY_NIL) { + if (r->fn && r->fn->createNil) + obj = r->fn->createNil(cur); + else + obj = (void*)REDIS_REPLY_NIL; + } else if (cur->type == REDIS_REPLY_BOOL) { + int bval = p[0] == 't' || p[0] == 'T'; + if (r->fn && r->fn->createBool) + obj = r->fn->createBool(cur,bval); + else + obj = (void*)REDIS_REPLY_BOOL; + } else { + /* Type will be error or status. */ + if (r->fn && r->fn->createString) + obj = r->fn->createString(cur,p,len); + else + obj = (void*)(size_t)(cur->type); + } + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + /* Set reply if this is the root object. */ + if (r->ridx == 0) r->reply = obj; + moveToNextTask(r); + return REDIS_OK; + } + + return REDIS_ERR; +} + +static int processBulkItem(redisReader *r) { + redisReadTask *cur = r->task[r->ridx]; + void *obj = NULL; + char *p, *s; + long long len; + unsigned long bytelen; + int success = 0; + + p = r->buf+r->pos; + s = seekNewline(p,r->len-r->pos); + if (s != NULL) { + p = r->buf+r->pos; + bytelen = s-(r->buf+r->pos)+2; /* include \r\n */ + + if (string2ll(p, bytelen - 2, &len) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad bulk string length"); + return REDIS_ERR; + } + + if (len < -1 || (LLONG_MAX > SIZE_MAX && len > (long long)SIZE_MAX)) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bulk string length out of range"); + return REDIS_ERR; + } + + if (len == -1) { + /* The nil object can always be created. */ + if (r->fn && r->fn->createNil) + obj = r->fn->createNil(cur); + else + obj = (void*)REDIS_REPLY_NIL; + success = 1; + } else { + /* Only continue when the buffer contains the entire bulk item. */ + bytelen += len+2; /* include \r\n */ + if (r->pos+bytelen <= r->len) { + if ((cur->type == REDIS_REPLY_VERB && len < 4) || + (cur->type == REDIS_REPLY_VERB && s[5] != ':')) + { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Verbatim string 4 bytes of content type are " + "missing or incorrectly encoded."); + return REDIS_ERR; + } + if (r->fn && r->fn->createString) + obj = r->fn->createString(cur,s+2,len); + else + obj = (void*)(long)cur->type; + success = 1; + } + } + + /* Proceed when obj was created. */ + if (success) { + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + r->pos += bytelen; + + /* Set reply if this is the root object. */ + if (r->ridx == 0) r->reply = obj; + moveToNextTask(r); + return REDIS_OK; + } + } + + return REDIS_ERR; +} + +static int redisReaderGrow(redisReader *r) { + redisReadTask **aux; + int newlen; + + /* Grow our stack size */ + newlen = r->tasks + REDIS_READER_STACK_SIZE; + aux = hi_realloc(r->task, sizeof(*r->task) * newlen); + if (aux == NULL) + goto oom; + + r->task = aux; + + /* Allocate new tasks */ + for (; r->tasks < newlen; r->tasks++) { + r->task[r->tasks] = hi_calloc(1, sizeof(**r->task)); + if (r->task[r->tasks] == NULL) + goto oom; + } + + return REDIS_OK; +oom: + __redisReaderSetErrorOOM(r); + return REDIS_ERR; +} + +/* Process the array, map and set types. */ +static int processAggregateItem(redisReader *r) { + redisReadTask *cur = r->task[r->ridx]; + void *obj; + char *p; + long long elements; + int root = 0, len; + + /* Set error for nested multi bulks with depth > 7 */ + if (r->ridx == r->tasks - 1) { + if (redisReaderGrow(r) == REDIS_ERR) + return REDIS_ERR; + } + + if ((p = readLine(r,&len)) != NULL) { + if (string2ll(p, len, &elements) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad multi-bulk length"); + return REDIS_ERR; + } + + root = (r->ridx == 0); + + if (elements < -1 || (LLONG_MAX > SIZE_MAX && elements > SIZE_MAX) || + (r->maxelements > 0 && elements > r->maxelements)) + { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Multi-bulk length out of range"); + return REDIS_ERR; + } + + if (elements == -1) { + if (r->fn && r->fn->createNil) + obj = r->fn->createNil(cur); + else + obj = (void*)REDIS_REPLY_NIL; + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + moveToNextTask(r); + } else { + if (cur->type == REDIS_REPLY_MAP) elements *= 2; + + if (r->fn && r->fn->createArray) + obj = r->fn->createArray(cur,elements); + else + obj = (void*)(long)cur->type; + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + /* Modify task stack when there are more than 0 elements. */ + if (elements > 0) { + cur->elements = elements; + cur->obj = obj; + r->ridx++; + r->task[r->ridx]->type = -1; + r->task[r->ridx]->elements = -1; + r->task[r->ridx]->idx = 0; + r->task[r->ridx]->obj = NULL; + r->task[r->ridx]->parent = cur; + r->task[r->ridx]->privdata = r->privdata; + } else { + moveToNextTask(r); + } + } + + /* Set reply if this is the root object. */ + if (root) r->reply = obj; + return REDIS_OK; + } + + return REDIS_ERR; +} + +static int processItem(redisReader *r) { + redisReadTask *cur = r->task[r->ridx]; + char *p; + + /* check if we need to read type */ + if (cur->type < 0) { + if ((p = readBytes(r,1)) != NULL) { + switch (p[0]) { + case '-': + cur->type = REDIS_REPLY_ERROR; + break; + case '+': + cur->type = REDIS_REPLY_STATUS; + break; + case ':': + cur->type = REDIS_REPLY_INTEGER; + break; + case ',': + cur->type = REDIS_REPLY_DOUBLE; + break; + case '_': + cur->type = REDIS_REPLY_NIL; + break; + case '$': + cur->type = REDIS_REPLY_STRING; + break; + case '*': + cur->type = REDIS_REPLY_ARRAY; + break; + case '%': + cur->type = REDIS_REPLY_MAP; + break; + case '~': + cur->type = REDIS_REPLY_SET; + break; + case '#': + cur->type = REDIS_REPLY_BOOL; + break; + case '=': + cur->type = REDIS_REPLY_VERB; + break; + case '>': + cur->type = REDIS_REPLY_PUSH; + break; + default: + __redisReaderSetErrorProtocolByte(r,*p); + return REDIS_ERR; + } + } else { + /* could not consume 1 byte */ + return REDIS_ERR; + } + } + + /* process typed item */ + switch(cur->type) { + case REDIS_REPLY_ERROR: + case REDIS_REPLY_STATUS: + case REDIS_REPLY_INTEGER: + case REDIS_REPLY_DOUBLE: + case REDIS_REPLY_NIL: + case REDIS_REPLY_BOOL: + return processLineItem(r); + case REDIS_REPLY_STRING: + case REDIS_REPLY_VERB: + return processBulkItem(r); + case REDIS_REPLY_ARRAY: + case REDIS_REPLY_MAP: + case REDIS_REPLY_SET: + case REDIS_REPLY_PUSH: + return processAggregateItem(r); + default: + assert(NULL); + return REDIS_ERR; /* Avoid warning. */ + } +} + +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) { + redisReader *r; + + r = hi_calloc(1,sizeof(redisReader)); + if (r == NULL) + return NULL; + + r->buf = sdsempty(); + if (r->buf == NULL) + goto oom; + + r->task = hi_calloc(REDIS_READER_STACK_SIZE, sizeof(*r->task)); + if (r->task == NULL) + goto oom; + + for (; r->tasks < REDIS_READER_STACK_SIZE; r->tasks++) { + r->task[r->tasks] = hi_calloc(1, sizeof(**r->task)); + if (r->task[r->tasks] == NULL) + goto oom; + } + + r->fn = fn; + r->maxbuf = REDIS_READER_MAX_BUF; + r->maxelements = REDIS_READER_MAX_ARRAY_ELEMENTS; + r->ridx = -1; + + return r; +oom: + redisReaderFree(r); + return NULL; +} + +void redisReaderFree(redisReader *r) { + if (r == NULL) + return; + + if (r->reply != NULL && r->fn && r->fn->freeObject) + r->fn->freeObject(r->reply); + + if (r->task) { + /* We know r->task[i] is allocated if i < r->tasks */ + for (int i = 0; i < r->tasks; i++) { + hi_free(r->task[i]); + } + + hi_free(r->task); + } + + sdsfree(r->buf); + hi_free(r); +} + +int redisReaderFeed(redisReader *r, const char *buf, size_t len) { + sds newbuf; + + /* Return early when this reader is in an erroneous state. */ + if (r->err) + return REDIS_ERR; + + /* Copy the provided buffer. */ + if (buf != NULL && len >= 1) { + /* Destroy internal buffer when it is empty and is quite large. */ + if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) { + sdsfree(r->buf); + r->buf = sdsempty(); + if (r->buf == 0) goto oom; + + r->pos = 0; + } + + newbuf = sdscatlen(r->buf,buf,len); + if (newbuf == NULL) goto oom; + + r->buf = newbuf; + r->len = sdslen(r->buf); + } + + return REDIS_OK; +oom: + __redisReaderSetErrorOOM(r); + return REDIS_ERR; +} + +int redisReaderGetReply(redisReader *r, void **reply) { + /* Default target pointer to NULL. */ + if (reply != NULL) + *reply = NULL; + + /* Return early when this reader is in an erroneous state. */ + if (r->err) + return REDIS_ERR; + + /* When the buffer is empty, there will never be a reply. */ + if (r->len == 0) + return REDIS_OK; + + /* Set first item to process when the stack is empty. */ + if (r->ridx == -1) { + r->task[0]->type = -1; + r->task[0]->elements = -1; + r->task[0]->idx = -1; + r->task[0]->obj = NULL; + r->task[0]->parent = NULL; + r->task[0]->privdata = r->privdata; + r->ridx = 0; + } + + /* Process items in reply. */ + while (r->ridx >= 0) + if (processItem(r) != REDIS_OK) + break; + + /* Return ASAP when an error occurred. */ + if (r->err) + return REDIS_ERR; + + /* Discard part of the buffer when we've consumed at least 1k, to avoid + * doing unnecessary calls to memmove() in sds.c. */ + if (r->pos >= 1024) { + if (sdsrange(r->buf,r->pos,-1) < 0) return REDIS_ERR; + r->pos = 0; + r->len = sdslen(r->buf); + } + + /* Emit a reply when there is one. */ + if (r->ridx == -1) { + if (reply != NULL) { + *reply = r->reply; + } else if (r->reply != NULL && r->fn && r->fn->freeObject) { + r->fn->freeObject(r->reply); + } + r->reply = NULL; + } + return REDIS_OK; +} diff --git a/ext/hiredis-1.0.2/read.h b/ext/hiredis-1.0.2/read.h new file mode 100644 index 0000000..2d74d77 --- /dev/null +++ b/ext/hiredis-1.0.2/read.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __HIREDIS_READ_H +#define __HIREDIS_READ_H +#include /* for size_t */ + +#define REDIS_ERR -1 +#define REDIS_OK 0 + +/* When an error occurs, the err flag in a context is set to hold the type of + * error that occurred. REDIS_ERR_IO means there was an I/O error and you + * should use the "errno" variable to find out what is wrong. + * For other values, the "errstr" field will hold a description. */ +#define REDIS_ERR_IO 1 /* Error in read or write */ +#define REDIS_ERR_EOF 3 /* End of file */ +#define REDIS_ERR_PROTOCOL 4 /* Protocol error */ +#define REDIS_ERR_OOM 5 /* Out of memory */ +#define REDIS_ERR_TIMEOUT 6 /* Timed out */ +#define REDIS_ERR_OTHER 2 /* Everything else... */ + +#define REDIS_REPLY_STRING 1 +#define REDIS_REPLY_ARRAY 2 +#define REDIS_REPLY_INTEGER 3 +#define REDIS_REPLY_NIL 4 +#define REDIS_REPLY_STATUS 5 +#define REDIS_REPLY_ERROR 6 +#define REDIS_REPLY_DOUBLE 7 +#define REDIS_REPLY_BOOL 8 +#define REDIS_REPLY_MAP 9 +#define REDIS_REPLY_SET 10 +#define REDIS_REPLY_ATTR 11 +#define REDIS_REPLY_PUSH 12 +#define REDIS_REPLY_BIGNUM 13 +#define REDIS_REPLY_VERB 14 + +/* Default max unused reader buffer. */ +#define REDIS_READER_MAX_BUF (1024*16) + +/* Default multi-bulk element limit */ +#define REDIS_READER_MAX_ARRAY_ELEMENTS ((1LL<<32) - 1) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct redisReadTask { + int type; + long long elements; /* number of elements in multibulk container */ + int idx; /* index in parent (array) object */ + void *obj; /* holds user-generated value for a read task */ + struct redisReadTask *parent; /* parent task */ + void *privdata; /* user-settable arbitrary field */ +} redisReadTask; + +typedef struct redisReplyObjectFunctions { + void *(*createString)(const redisReadTask*, char*, size_t); + void *(*createArray)(const redisReadTask*, size_t); + void *(*createInteger)(const redisReadTask*, long long); + void *(*createDouble)(const redisReadTask*, double, char*, size_t); + void *(*createNil)(const redisReadTask*); + void *(*createBool)(const redisReadTask*, int); + void (*freeObject)(void*); +} redisReplyObjectFunctions; + +typedef struct redisReader { + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + + char *buf; /* Read buffer */ + size_t pos; /* Buffer cursor */ + size_t len; /* Buffer length */ + size_t maxbuf; /* Max length of unused buffer */ + long long maxelements; /* Max multi-bulk elements */ + + redisReadTask **task; + int tasks; + + int ridx; /* Index of current read task */ + void *reply; /* Temporary reply pointer */ + + redisReplyObjectFunctions *fn; + void *privdata; +} redisReader; + +/* Public API for the protocol parser. */ +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); +void redisReaderFree(redisReader *r); +int redisReaderFeed(redisReader *r, const char *buf, size_t len); +int redisReaderGetReply(redisReader *r, void **reply); + +#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) +#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) +#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/hiredis-1.0.2/sds.c b/ext/hiredis-1.0.2/sds.c new file mode 100644 index 0000000..49d2096 --- /dev/null +++ b/ext/hiredis-1.0.2/sds.c @@ -0,0 +1,1289 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fmacros.h" +#include +#include +#include +#include +#include +#include +#include "sds.h" +#include "sdsalloc.h" + +static inline int sdsHdrSize(char type) { + switch(type&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return sizeof(struct sdshdr5); + case SDS_TYPE_8: + return sizeof(struct sdshdr8); + case SDS_TYPE_16: + return sizeof(struct sdshdr16); + case SDS_TYPE_32: + return sizeof(struct sdshdr32); + case SDS_TYPE_64: + return sizeof(struct sdshdr64); + } + return 0; +} + +static inline char sdsReqType(size_t string_size) { + if (string_size < 32) + return SDS_TYPE_5; + if (string_size < 0xff) + return SDS_TYPE_8; + if (string_size < 0xffff) + return SDS_TYPE_16; + if (string_size < 0xffffffff) + return SDS_TYPE_32; + return SDS_TYPE_64; +} + +/* Create a new sds string with the content specified by the 'init' pointer + * and 'initlen'. + * If NULL is used for 'init' the string is initialized with zero bytes. + * + * The string is always null-termined (all the sds strings are, always) so + * even if you create an sds string with: + * + * mystring = sdsnewlen("abc",3); + * + * You can print the string with printf() as there is an implicit \0 at the + * end of the string. However the string is binary safe and can contain + * \0 characters in the middle, as the length is stored in the sds header. */ +sds sdsnewlen(const void *init, size_t initlen) { + void *sh; + sds s; + char type = sdsReqType(initlen); + /* Empty strings are usually created in order to append. Use type 8 + * since type 5 is not good at this. */ + if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8; + int hdrlen = sdsHdrSize(type); + unsigned char *fp; /* flags pointer. */ + + sh = s_malloc(hdrlen+initlen+1); + if (sh == NULL) return NULL; + if (!init) + memset(sh, 0, hdrlen+initlen+1); + s = (char*)sh+hdrlen; + fp = ((unsigned char*)s)-1; + switch(type) { + case SDS_TYPE_5: { + *fp = type | (initlen << SDS_TYPE_BITS); + break; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + } + if (initlen && init) + memcpy(s, init, initlen); + s[initlen] = '\0'; + return s; +} + +/* Create an empty (zero length) sds string. Even in this case the string + * always has an implicit null term. */ +sds sdsempty(void) { + return sdsnewlen("",0); +} + +/* Create a new sds string starting from a null terminated C string. */ +sds sdsnew(const char *init) { + size_t initlen = (init == NULL) ? 0 : strlen(init); + return sdsnewlen(init, initlen); +} + +/* Duplicate an sds string. */ +sds sdsdup(const sds s) { + return sdsnewlen(s, sdslen(s)); +} + +/* Free an sds string. No operation is performed if 's' is NULL. */ +void sdsfree(sds s) { + if (s == NULL) return; + s_free((char*)s-sdsHdrSize(s[-1])); +} + +/* Set the sds string length to the length as obtained with strlen(), so + * considering as content only up to the first null term character. + * + * This function is useful when the sds string is hacked manually in some + * way, like in the following example: + * + * s = sdsnew("foobar"); + * s[2] = '\0'; + * sdsupdatelen(s); + * printf("%d\n", sdslen(s)); + * + * The output will be "2", but if we comment out the call to sdsupdatelen() + * the output will be "6" as the string was modified but the logical length + * remains 6 bytes. */ +void sdsupdatelen(sds s) { + int reallen = strlen(s); + sdssetlen(s, reallen); +} + +/* Modify an sds string in-place to make it empty (zero length). + * However all the existing buffer is not discarded but set as free space + * so that next append operations will not require allocations up to the + * number of bytes previously available. */ +void sdsclear(sds s) { + sdssetlen(s, 0); + s[0] = '\0'; +} + +/* Enlarge the free space at the end of the sds string so that the caller + * is sure that after calling this function can overwrite up to addlen + * bytes after the end of the string, plus one more byte for nul term. + * + * Note: this does not change the *length* of the sds string as returned + * by sdslen(), but only the free buffer space we have. */ +sds sdsMakeRoomFor(sds s, size_t addlen) { + void *sh, *newsh; + size_t avail = sdsavail(s); + size_t len, newlen; + char type, oldtype = s[-1] & SDS_TYPE_MASK; + int hdrlen; + + /* Return ASAP if there is enough space left. */ + if (avail >= addlen) return s; + + len = sdslen(s); + sh = (char*)s-sdsHdrSize(oldtype); + newlen = (len+addlen); + if (newlen < SDS_MAX_PREALLOC) + newlen *= 2; + else + newlen += SDS_MAX_PREALLOC; + + type = sdsReqType(newlen); + + /* Don't use type 5: the user is appending to the string and type 5 is + * not able to remember empty space, so sdsMakeRoomFor() must be called + * at every appending operation. */ + if (type == SDS_TYPE_5) type = SDS_TYPE_8; + + hdrlen = sdsHdrSize(type); + if (oldtype==type) { + newsh = s_realloc(sh, hdrlen+newlen+1); + if (newsh == NULL) return NULL; + s = (char*)newsh+hdrlen; + } else { + /* Since the header size changes, need to move the string forward, + * and can't use realloc */ + newsh = s_malloc(hdrlen+newlen+1); + if (newsh == NULL) return NULL; + memcpy((char*)newsh+hdrlen, s, len+1); + s_free(sh); + s = (char*)newsh+hdrlen; + s[-1] = type; + sdssetlen(s, len); + } + sdssetalloc(s, newlen); + return s; +} + +/* Reallocate the sds string so that it has no free space at the end. The + * contained string remains not altered, but next concatenation operations + * will require a reallocation. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdsRemoveFreeSpace(sds s) { + void *sh, *newsh; + char type, oldtype = s[-1] & SDS_TYPE_MASK; + int hdrlen; + size_t len = sdslen(s); + sh = (char*)s-sdsHdrSize(oldtype); + + type = sdsReqType(len); + hdrlen = sdsHdrSize(type); + if (oldtype==type) { + newsh = s_realloc(sh, hdrlen+len+1); + if (newsh == NULL) return NULL; + s = (char*)newsh+hdrlen; + } else { + newsh = s_malloc(hdrlen+len+1); + if (newsh == NULL) return NULL; + memcpy((char*)newsh+hdrlen, s, len+1); + s_free(sh); + s = (char*)newsh+hdrlen; + s[-1] = type; + sdssetlen(s, len); + } + sdssetalloc(s, len); + return s; +} + +/* Return the total size of the allocation of the specifed sds string, + * including: + * 1) The sds header before the pointer. + * 2) The string. + * 3) The free buffer at the end if any. + * 4) The implicit null term. + */ +size_t sdsAllocSize(sds s) { + size_t alloc = sdsalloc(s); + return sdsHdrSize(s[-1])+alloc+1; +} + +/* Return the pointer of the actual SDS allocation (normally SDS strings + * are referenced by the start of the string buffer). */ +void *sdsAllocPtr(sds s) { + return (void*) (s-sdsHdrSize(s[-1])); +} + +/* Increment the sds length and decrements the left free space at the + * end of the string according to 'incr'. Also set the null term + * in the new end of the string. + * + * This function is used in order to fix the string length after the + * user calls sdsMakeRoomFor(), writes something after the end of + * the current string, and finally needs to set the new length. + * + * Note: it is possible to use a negative increment in order to + * right-trim the string. + * + * Usage example: + * + * Using sdsIncrLen() and sdsMakeRoomFor() it is possible to mount the + * following schema, to cat bytes coming from the kernel to the end of an + * sds string without copying into an intermediate buffer: + * + * oldlen = sdslen(s); + * s = sdsMakeRoomFor(s, BUFFER_SIZE); + * nread = read(fd, s+oldlen, BUFFER_SIZE); + * ... check for nread <= 0 and handle it ... + * sdsIncrLen(s, nread); + */ +void sdsIncrLen(sds s, int incr) { + unsigned char flags = s[-1]; + size_t len; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char oldlen = SDS_TYPE_5_LEN(flags); + assert((incr > 0 && oldlen+incr < 32) || (incr < 0 && oldlen >= (unsigned int)(-incr))); + *fp = SDS_TYPE_5 | ((oldlen+incr) << SDS_TYPE_BITS); + len = oldlen+incr; + break; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + assert((incr >= 0 && sh->alloc-sh->len >= (unsigned int)incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + assert((incr >= 0 && sh->alloc-sh->len >= (uint64_t)incr) || (incr < 0 && sh->len >= (uint64_t)(-incr))); + len = (sh->len += incr); + break; + } + default: len = 0; /* Just to avoid compilation warnings. */ + } + s[len] = '\0'; +} + +/* Grow the sds to have the specified length. Bytes that were not part of + * the original length of the sds will be set to zero. + * + * if the specified length is smaller than the current length, no operation + * is performed. */ +sds sdsgrowzero(sds s, size_t len) { + size_t curlen = sdslen(s); + + if (len <= curlen) return s; + s = sdsMakeRoomFor(s,len-curlen); + if (s == NULL) return NULL; + + /* Make sure added region doesn't contain garbage */ + memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */ + sdssetlen(s, len); + return s; +} + +/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the + * end of the specified sds string 's'. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatlen(sds s, const void *t, size_t len) { + size_t curlen = sdslen(s); + + s = sdsMakeRoomFor(s,len); + if (s == NULL) return NULL; + memcpy(s+curlen, t, len); + sdssetlen(s, curlen+len); + s[curlen+len] = '\0'; + return s; +} + +/* Append the specified null termianted C string to the sds string 's'. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscat(sds s, const char *t) { + return sdscatlen(s, t, strlen(t)); +} + +/* Append the specified sds 't' to the existing sds 's'. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatsds(sds s, const sds t) { + return sdscatlen(s, t, sdslen(t)); +} + +/* Destructively modify the sds string 's' to hold the specified binary + * safe string pointed by 't' of length 'len' bytes. */ +sds sdscpylen(sds s, const char *t, size_t len) { + if (sdsalloc(s) < len) { + s = sdsMakeRoomFor(s,len-sdslen(s)); + if (s == NULL) return NULL; + } + memcpy(s, t, len); + s[len] = '\0'; + sdssetlen(s, len); + return s; +} + +/* Like sdscpylen() but 't' must be a null-termined string so that the length + * of the string is obtained with strlen(). */ +sds sdscpy(sds s, const char *t) { + return sdscpylen(s, t, strlen(t)); +} + +/* Helper for sdscatlonglong() doing the actual number -> string + * conversion. 's' must point to a string with room for at least + * SDS_LLSTR_SIZE bytes. + * + * The function returns the length of the null-terminated string + * representation stored at 's'. */ +#define SDS_LLSTR_SIZE 21 +int sdsll2str(char *s, long long value) { + char *p, aux; + unsigned long long v; + size_t l; + + /* Generate the string representation, this method produces + * an reversed string. */ + v = (value < 0) ? -value : value; + p = s; + do { + *p++ = '0'+(v%10); + v /= 10; + } while(v); + if (value < 0) *p++ = '-'; + + /* Compute length and add null term. */ + l = p-s; + *p = '\0'; + + /* Reverse the string. */ + p--; + while(s < p) { + aux = *s; + *s = *p; + *p = aux; + s++; + p--; + } + return l; +} + +/* Identical sdsll2str(), but for unsigned long long type. */ +int sdsull2str(char *s, unsigned long long v) { + char *p, aux; + size_t l; + + /* Generate the string representation, this method produces + * an reversed string. */ + p = s; + do { + *p++ = '0'+(v%10); + v /= 10; + } while(v); + + /* Compute length and add null term. */ + l = p-s; + *p = '\0'; + + /* Reverse the string. */ + p--; + while(s < p) { + aux = *s; + *s = *p; + *p = aux; + s++; + p--; + } + return l; +} + +/* Create an sds string from a long long value. It is much faster than: + * + * sdscatprintf(sdsempty(),"%lld\n", value); + */ +sds sdsfromlonglong(long long value) { + char buf[SDS_LLSTR_SIZE]; + int len = sdsll2str(buf,value); + + return sdsnewlen(buf,len); +} + +/* Like sdscatprintf() but gets va_list instead of being variadic. */ +sds sdscatvprintf(sds s, const char *fmt, va_list ap) { + va_list cpy; + char staticbuf[1024], *buf = staticbuf, *t; + size_t buflen = strlen(fmt)*2; + + /* We try to start using a static buffer for speed. + * If not possible we revert to heap allocation. */ + if (buflen > sizeof(staticbuf)) { + buf = s_malloc(buflen); + if (buf == NULL) return NULL; + } else { + buflen = sizeof(staticbuf); + } + + /* Try with buffers two times bigger every time we fail to + * fit the string in the current buffer size. */ + while(1) { + buf[buflen-2] = '\0'; + va_copy(cpy,ap); + vsnprintf(buf, buflen, fmt, cpy); + va_end(cpy); + if (buf[buflen-2] != '\0') { + if (buf != staticbuf) s_free(buf); + buflen *= 2; + buf = s_malloc(buflen); + if (buf == NULL) return NULL; + continue; + } + break; + } + + /* Finally concat the obtained string to the SDS string and return it. */ + t = sdscat(s, buf); + if (buf != staticbuf) s_free(buf); + return t; +} + +/* Append to the sds string 's' a string obtained using printf-alike format + * specifier. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. + * + * Example: + * + * s = sdsnew("Sum is: "); + * s = sdscatprintf(s,"%d+%d = %d",a,b,a+b). + * + * Often you need to create a string from scratch with the printf-alike + * format. When this is the need, just use sdsempty() as the target string: + * + * s = sdscatprintf(sdsempty(), "... your format ...", args); + */ +sds sdscatprintf(sds s, const char *fmt, ...) { + va_list ap; + char *t; + va_start(ap, fmt); + t = sdscatvprintf(s,fmt,ap); + va_end(ap); + return t; +} + +/* This function is similar to sdscatprintf, but much faster as it does + * not rely on sprintf() family functions implemented by the libc that + * are often very slow. Moreover directly handling the sds string as + * new data is concatenated provides a performance improvement. + * + * However this function only handles an incompatible subset of printf-alike + * format specifiers: + * + * %s - C String + * %S - SDS string + * %i - signed int + * %I - 64 bit signed integer (long long, int64_t) + * %u - unsigned int + * %U - 64 bit unsigned integer (unsigned long long, uint64_t) + * %% - Verbatim "%" character. + */ +sds sdscatfmt(sds s, char const *fmt, ...) { + const char *f = fmt; + int i; + va_list ap; + + va_start(ap,fmt); + i = sdslen(s); /* Position of the next byte to write to dest str. */ + while(*f) { + char next, *str; + size_t l; + long long num; + unsigned long long unum; + + /* Make sure there is always space for at least 1 char. */ + if (sdsavail(s)==0) { + s = sdsMakeRoomFor(s,1); + if (s == NULL) goto fmt_error; + } + + switch(*f) { + case '%': + next = *(f+1); + f++; + switch(next) { + case 's': + case 'S': + str = va_arg(ap,char*); + l = (next == 's') ? strlen(str) : sdslen(str); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + if (s == NULL) goto fmt_error; + } + memcpy(s+i,str,l); + sdsinclen(s,l); + i += l; + break; + case 'i': + case 'I': + if (next == 'i') + num = va_arg(ap,int); + else + num = va_arg(ap,long long); + { + char buf[SDS_LLSTR_SIZE]; + l = sdsll2str(buf,num); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + if (s == NULL) goto fmt_error; + } + memcpy(s+i,buf,l); + sdsinclen(s,l); + i += l; + } + break; + case 'u': + case 'U': + if (next == 'u') + unum = va_arg(ap,unsigned int); + else + unum = va_arg(ap,unsigned long long); + { + char buf[SDS_LLSTR_SIZE]; + l = sdsull2str(buf,unum); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + if (s == NULL) goto fmt_error; + } + memcpy(s+i,buf,l); + sdsinclen(s,l); + i += l; + } + break; + default: /* Handle %% and generally %. */ + s[i++] = next; + sdsinclen(s,1); + break; + } + break; + default: + s[i++] = *f; + sdsinclen(s,1); + break; + } + f++; + } + va_end(ap); + + /* Add null-term */ + s[i] = '\0'; + return s; + +fmt_error: + va_end(ap); + return NULL; +} + +/* Remove the part of the string from left and from right composed just of + * contiguous characters found in 'cset', that is a null terminted C string. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. + * + * Example: + * + * s = sdsnew("AA...AA.a.aa.aHelloWorld :::"); + * s = sdstrim(s,"Aa. :"); + * printf("%s\n", s); + * + * Output will be just "Hello World". + */ +sds sdstrim(sds s, const char *cset) { + char *start, *end, *sp, *ep; + size_t len; + + sp = start = s; + ep = end = s+sdslen(s)-1; + while(sp <= end && strchr(cset, *sp)) sp++; + while(ep > sp && strchr(cset, *ep)) ep--; + len = (sp > ep) ? 0 : ((ep-sp)+1); + if (s != sp) memmove(s, sp, len); + s[len] = '\0'; + sdssetlen(s,len); + return s; +} + +/* Turn the string into a smaller (or equal) string containing only the + * substring specified by the 'start' and 'end' indexes. + * + * start and end can be negative, where -1 means the last character of the + * string, -2 the penultimate character, and so forth. + * + * The interval is inclusive, so the start and end characters will be part + * of the resulting string. + * + * The string is modified in-place. + * + * Return value: + * -1 (error) if sdslen(s) is larger than maximum positive ssize_t value. + * 0 on success. + * + * Example: + * + * s = sdsnew("Hello World"); + * sdsrange(s,1,-1); => "ello World" + */ +int sdsrange(sds s, ssize_t start, ssize_t end) { + size_t newlen, len = sdslen(s); + if (len > SSIZE_MAX) return -1; + + if (len == 0) return 0; + if (start < 0) { + start = len+start; + if (start < 0) start = 0; + } + if (end < 0) { + end = len+end; + if (end < 0) end = 0; + } + newlen = (start > end) ? 0 : (end-start)+1; + if (newlen != 0) { + if (start >= (ssize_t)len) { + newlen = 0; + } else if (end >= (ssize_t)len) { + end = len-1; + newlen = (start > end) ? 0 : (end-start)+1; + } + } else { + start = 0; + } + if (start && newlen) memmove(s, s+start, newlen); + s[newlen] = 0; + sdssetlen(s,newlen); + return 0; +} + +/* Apply tolower() to every character of the sds string 's'. */ +void sdstolower(sds s) { + int len = sdslen(s), j; + + for (j = 0; j < len; j++) s[j] = tolower(s[j]); +} + +/* Apply toupper() to every character of the sds string 's'. */ +void sdstoupper(sds s) { + int len = sdslen(s), j; + + for (j = 0; j < len; j++) s[j] = toupper(s[j]); +} + +/* Compare two sds strings s1 and s2 with memcmp(). + * + * Return value: + * + * positive if s1 > s2. + * negative if s1 < s2. + * 0 if s1 and s2 are exactly the same binary string. + * + * If two strings share exactly the same prefix, but one of the two has + * additional characters, the longer string is considered to be greater than + * the smaller one. */ +int sdscmp(const sds s1, const sds s2) { + size_t l1, l2, minlen; + int cmp; + + l1 = sdslen(s1); + l2 = sdslen(s2); + minlen = (l1 < l2) ? l1 : l2; + cmp = memcmp(s1,s2,minlen); + if (cmp == 0) return l1-l2; + return cmp; +} + +/* Split 's' with separator in 'sep'. An array + * of sds strings is returned. *count will be set + * by reference to the number of tokens returned. + * + * On out of memory, zero length string, zero length + * separator, NULL is returned. + * + * Note that 'sep' is able to split a string using + * a multi-character separator. For example + * sdssplit("foo_-_bar","_-_"); will return two + * elements "foo" and "bar". + * + * This version of the function is binary-safe but + * requires length arguments. sdssplit() is just the + * same function but for zero-terminated strings. + */ +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count) { + int elements = 0, slots = 5, start = 0, j; + sds *tokens; + + if (seplen < 1 || len < 0) return NULL; + + tokens = s_malloc(sizeof(sds)*slots); + if (tokens == NULL) return NULL; + + if (len == 0) { + *count = 0; + return tokens; + } + for (j = 0; j < (len-(seplen-1)); j++) { + /* make sure there is room for the next element and the final one */ + if (slots < elements+2) { + sds *newtokens; + + slots *= 2; + newtokens = s_realloc(tokens,sizeof(sds)*slots); + if (newtokens == NULL) goto cleanup; + tokens = newtokens; + } + /* search the separator */ + if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) { + tokens[elements] = sdsnewlen(s+start,j-start); + if (tokens[elements] == NULL) goto cleanup; + elements++; + start = j+seplen; + j = j+seplen-1; /* skip the separator */ + } + } + /* Add the final element. We are sure there is room in the tokens array. */ + tokens[elements] = sdsnewlen(s+start,len-start); + if (tokens[elements] == NULL) goto cleanup; + elements++; + *count = elements; + return tokens; + +cleanup: + { + int i; + for (i = 0; i < elements; i++) sdsfree(tokens[i]); + s_free(tokens); + *count = 0; + return NULL; + } +} + +/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */ +void sdsfreesplitres(sds *tokens, int count) { + if (!tokens) return; + while(count--) + sdsfree(tokens[count]); + s_free(tokens); +} + +/* Append to the sds string "s" an escaped string representation where + * all the non-printable characters (tested with isprint()) are turned into + * escapes in the form "\n\r\a...." or "\x". + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatrepr(sds s, const char *p, size_t len) { + s = sdscatlen(s,"\"",1); + while(len--) { + switch(*p) { + case '\\': + case '"': + s = sdscatprintf(s,"\\%c",*p); + break; + case '\n': s = sdscatlen(s,"\\n",2); break; + case '\r': s = sdscatlen(s,"\\r",2); break; + case '\t': s = sdscatlen(s,"\\t",2); break; + case '\a': s = sdscatlen(s,"\\a",2); break; + case '\b': s = sdscatlen(s,"\\b",2); break; + default: + if (isprint(*p)) + s = sdscatprintf(s,"%c",*p); + else + s = sdscatprintf(s,"\\x%02x",(unsigned char)*p); + break; + } + p++; + } + return sdscatlen(s,"\"",1); +} + +/* Helper function for sdssplitargs() that converts a hex digit into an + * integer from 0 to 15 */ +int hex_digit_to_int(char c) { + switch(c) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'a': case 'A': return 10; + case 'b': case 'B': return 11; + case 'c': case 'C': return 12; + case 'd': case 'D': return 13; + case 'e': case 'E': return 14; + case 'f': case 'F': return 15; + default: return 0; + } +} + +/* Split a line into arguments, where every argument can be in the + * following programming-language REPL-alike form: + * + * foo bar "newline are supported\n" and "\xff\x00otherstuff" + * + * The number of arguments is stored into *argc, and an array + * of sds is returned. + * + * The caller should free the resulting array of sds strings with + * sdsfreesplitres(). + * + * Note that sdscatrepr() is able to convert back a string into + * a quoted string in the same format sdssplitargs() is able to parse. + * + * The function returns the allocated tokens on success, even when the + * input string is empty, or NULL if the input contains unbalanced + * quotes or closed quotes followed by non space characters + * as in: "foo"bar or "foo' + */ +sds *sdssplitargs(const char *line, int *argc) { + const char *p = line; + char *current = NULL; + char **vector = NULL; + + *argc = 0; + while(1) { + /* skip blanks */ + while(*p && isspace(*p)) p++; + if (*p) { + /* get a token */ + int inq=0; /* set to 1 if we are in "quotes" */ + int insq=0; /* set to 1 if we are in 'single quotes' */ + int done=0; + + if (current == NULL) current = sdsempty(); + while(!done) { + if (inq) { + if (*p == '\\' && *(p+1) == 'x' && + isxdigit(*(p+2)) && + isxdigit(*(p+3))) + { + unsigned char byte; + + byte = (hex_digit_to_int(*(p+2))*16)+ + hex_digit_to_int(*(p+3)); + current = sdscatlen(current,(char*)&byte,1); + p += 3; + } else if (*p == '\\' && *(p+1)) { + char c; + + p++; + switch(*p) { + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'b': c = '\b'; break; + case 'a': c = '\a'; break; + default: c = *p; break; + } + current = sdscatlen(current,&c,1); + } else if (*p == '"') { + /* closing quote must be followed by a space or + * nothing at all. */ + if (*(p+1) && !isspace(*(p+1))) goto err; + done=1; + } else if (!*p) { + /* unterminated quotes */ + goto err; + } else { + current = sdscatlen(current,p,1); + } + } else if (insq) { + if (*p == '\\' && *(p+1) == '\'') { + p++; + current = sdscatlen(current,"'",1); + } else if (*p == '\'') { + /* closing quote must be followed by a space or + * nothing at all. */ + if (*(p+1) && !isspace(*(p+1))) goto err; + done=1; + } else if (!*p) { + /* unterminated quotes */ + goto err; + } else { + current = sdscatlen(current,p,1); + } + } else { + switch(*p) { + case ' ': + case '\n': + case '\r': + case '\t': + case '\0': + done=1; + break; + case '"': + inq=1; + break; + case '\'': + insq=1; + break; + default: + current = sdscatlen(current,p,1); + break; + } + } + if (*p) p++; + } + /* add the token to the vector */ + { + char **new_vector = s_realloc(vector,((*argc)+1)*sizeof(char*)); + if (new_vector == NULL) { + s_free(vector); + return NULL; + } + + vector = new_vector; + vector[*argc] = current; + (*argc)++; + current = NULL; + } + } else { + /* Even on empty input string return something not NULL. */ + if (vector == NULL) vector = s_malloc(sizeof(void*)); + return vector; + } + } + +err: + while((*argc)--) + sdsfree(vector[*argc]); + s_free(vector); + if (current) sdsfree(current); + *argc = 0; + return NULL; +} + +/* Modify the string substituting all the occurrences of the set of + * characters specified in the 'from' string to the corresponding character + * in the 'to' array. + * + * For instance: sdsmapchars(mystring, "ho", "01", 2) + * will have the effect of turning the string "hello" into "0ell1". + * + * The function returns the sds string pointer, that is always the same + * as the input pointer since no resize is needed. */ +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) { + size_t j, i, l = sdslen(s); + + for (j = 0; j < l; j++) { + for (i = 0; i < setlen; i++) { + if (s[j] == from[i]) { + s[j] = to[i]; + break; + } + } + } + return s; +} + +/* Join an array of C strings using the specified separator (also a C string). + * Returns the result as an sds string. */ +sds sdsjoin(char **argv, int argc, char *sep) { + sds join = sdsempty(); + int j; + + for (j = 0; j < argc; j++) { + join = sdscat(join, argv[j]); + if (j != argc-1) join = sdscat(join,sep); + } + return join; +} + +/* Like sdsjoin, but joins an array of SDS strings. */ +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) { + sds join = sdsempty(); + int j; + + for (j = 0; j < argc; j++) { + join = sdscatsds(join, argv[j]); + if (j != argc-1) join = sdscatlen(join,sep,seplen); + } + return join; +} + +/* Wrappers to the allocators used by SDS. Note that SDS will actually + * just use the macros defined into sdsalloc.h in order to avoid to pay + * the overhead of function calls. Here we define these wrappers only for + * the programs SDS is linked to, if they want to touch the SDS internals + * even if they use a different allocator. */ +void *sds_malloc(size_t size) { return s_malloc(size); } +void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); } +void sds_free(void *ptr) { s_free(ptr); } + +#if defined(SDS_TEST_MAIN) +#include +#include "testhelp.h" +#include "limits.h" + +#define UNUSED(x) (void)(x) +int sdsTest(void) { + { + sds x = sdsnew("foo"), y; + + test_cond("Create a string and obtain the length", + sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0) + + sdsfree(x); + x = sdsnewlen("foo",2); + test_cond("Create a string with specified length", + sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0) + + x = sdscat(x,"bar"); + test_cond("Strings concatenation", + sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0); + + x = sdscpy(x,"a"); + test_cond("sdscpy() against an originally longer string", + sdslen(x) == 1 && memcmp(x,"a\0",2) == 0) + + x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk"); + test_cond("sdscpy() against an originally shorter string", + sdslen(x) == 33 && + memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0) + + sdsfree(x); + x = sdscatprintf(sdsempty(),"%d",123); + test_cond("sdscatprintf() seems working in the base case", + sdslen(x) == 3 && memcmp(x,"123\0",4) == 0) + + sdsfree(x); + x = sdsnew("--"); + x = sdscatfmt(x, "Hello %s World %I,%I--", "Hi!", LLONG_MIN,LLONG_MAX); + test_cond("sdscatfmt() seems working in the base case", + sdslen(x) == 60 && + memcmp(x,"--Hello Hi! World -9223372036854775808," + "9223372036854775807--",60) == 0) + printf("[%s]\n",x); + + sdsfree(x); + x = sdsnew("--"); + x = sdscatfmt(x, "%u,%U--", UINT_MAX, ULLONG_MAX); + test_cond("sdscatfmt() seems working with unsigned numbers", + sdslen(x) == 35 && + memcmp(x,"--4294967295,18446744073709551615--",35) == 0) + + sdsfree(x); + x = sdsnew(" x "); + sdstrim(x," x"); + test_cond("sdstrim() works when all chars match", + sdslen(x) == 0) + + sdsfree(x); + x = sdsnew(" x "); + sdstrim(x," "); + test_cond("sdstrim() works when a single char remains", + sdslen(x) == 1 && x[0] == 'x') + + sdsfree(x); + x = sdsnew("xxciaoyyy"); + sdstrim(x,"xy"); + test_cond("sdstrim() correctly trims characters", + sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0) + + y = sdsdup(x); + sdsrange(y,1,1); + test_cond("sdsrange(...,1,1)", + sdslen(y) == 1 && memcmp(y,"i\0",2) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,1,-1); + test_cond("sdsrange(...,1,-1)", + sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,-2,-1); + test_cond("sdsrange(...,-2,-1)", + sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,2,1); + test_cond("sdsrange(...,2,1)", + sdslen(y) == 0 && memcmp(y,"\0",1) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,1,100); + test_cond("sdsrange(...,1,100)", + sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,100,100); + test_cond("sdsrange(...,100,100)", + sdslen(y) == 0 && memcmp(y,"\0",1) == 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("foo"); + y = sdsnew("foa"); + test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("bar"); + y = sdsnew("bar"); + test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("aar"); + y = sdsnew("bar"); + test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0) + + sdsfree(y); + sdsfree(x); + x = sdsnewlen("\a\n\0foo\r",7); + y = sdscatrepr(sdsempty(),x,sdslen(x)); + test_cond("sdscatrepr(...data...)", + memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0) + + { + unsigned int oldfree; + char *p; + int step = 10, j, i; + + sdsfree(x); + sdsfree(y); + x = sdsnew("0"); + test_cond("sdsnew() free/len buffers", sdslen(x) == 1 && sdsavail(x) == 0); + + /* Run the test a few times in order to hit the first two + * SDS header types. */ + for (i = 0; i < 10; i++) { + int oldlen = sdslen(x); + x = sdsMakeRoomFor(x,step); + int type = x[-1]&SDS_TYPE_MASK; + + test_cond("sdsMakeRoomFor() len", sdslen(x) == oldlen); + if (type != SDS_TYPE_5) { + test_cond("sdsMakeRoomFor() free", sdsavail(x) >= step); + oldfree = sdsavail(x); + } + p = x+oldlen; + for (j = 0; j < step; j++) { + p[j] = 'A'+j; + } + sdsIncrLen(x,step); + } + test_cond("sdsMakeRoomFor() content", + memcmp("0ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ",x,101) == 0); + test_cond("sdsMakeRoomFor() final length",sdslen(x)==101); + + sdsfree(x); + } + } + test_report() + return 0; +} +#endif + +#ifdef SDS_TEST_MAIN +int main(void) { + return sdsTest(); +} +#endif diff --git a/ext/hiredis-1.0.2/sds.h b/ext/hiredis-1.0.2/sds.h new file mode 100644 index 0000000..eda8833 --- /dev/null +++ b/ext/hiredis-1.0.2/sds.h @@ -0,0 +1,278 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SDS_H +#define __SDS_H + +#define SDS_MAX_PREALLOC (1024*1024) +#ifdef _MSC_VER +#define __attribute__(x) +typedef long long ssize_t; +#define SSIZE_MAX (LLONG_MAX >> 1) +#endif + +#include +#include +#include + +typedef char *sds; + +/* Note: sdshdr5 is never used, we just access the flags byte directly. + * However is here to document the layout of type 5 SDS strings. */ +struct __attribute__ ((__packed__)) sdshdr5 { + unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr8 { + uint8_t len; /* used */ + uint8_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr16 { + uint16_t len; /* used */ + uint16_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr32 { + uint32_t len; /* used */ + uint32_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr64 { + uint64_t len; /* used */ + uint64_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; + +#define SDS_TYPE_5 0 +#define SDS_TYPE_8 1 +#define SDS_TYPE_16 2 +#define SDS_TYPE_32 3 +#define SDS_TYPE_64 4 +#define SDS_TYPE_MASK 7 +#define SDS_TYPE_BITS 3 +#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))); +#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)))) +#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) + +static inline size_t sdslen(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->len; + case SDS_TYPE_16: + return SDS_HDR(16,s)->len; + case SDS_TYPE_32: + return SDS_HDR(32,s)->len; + case SDS_TYPE_64: + return SDS_HDR(64,s)->len; + } + return 0; +} + +static inline size_t sdsavail(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + return 0; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + return sh->alloc - sh->len; + } + } + return 0; +} + +static inline void sdssetlen(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + *fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS)); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len = (uint8_t)newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len = (uint16_t)newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len = (uint32_t)newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len = (uint64_t)newlen; + break; + } +} + +static inline void sdsinclen(sds s, size_t inc) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc; + *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len += (uint8_t)inc; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len += (uint16_t)inc; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len += (uint32_t)inc; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len += (uint64_t)inc; + break; + } +} + +/* sdsalloc() = sdsavail() + sdslen() */ +static inline size_t sdsalloc(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->alloc; + case SDS_TYPE_16: + return SDS_HDR(16,s)->alloc; + case SDS_TYPE_32: + return SDS_HDR(32,s)->alloc; + case SDS_TYPE_64: + return SDS_HDR(64,s)->alloc; + } + return 0; +} + +static inline void sdssetalloc(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + /* Nothing to do, this type has no total allocation info. */ + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->alloc = (uint8_t)newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->alloc = (uint16_t)newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->alloc = (uint32_t)newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->alloc = (uint64_t)newlen; + break; + } +} + +sds sdsnewlen(const void *init, size_t initlen); +sds sdsnew(const char *init); +sds sdsempty(void); +sds sdsdup(const sds s); +void sdsfree(sds s); +sds sdsgrowzero(sds s, size_t len); +sds sdscatlen(sds s, const void *t, size_t len); +sds sdscat(sds s, const char *t); +sds sdscatsds(sds s, const sds t); +sds sdscpylen(sds s, const char *t, size_t len); +sds sdscpy(sds s, const char *t); + +sds sdscatvprintf(sds s, const char *fmt, va_list ap); +#ifdef __GNUC__ +sds sdscatprintf(sds s, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +#else +sds sdscatprintf(sds s, const char *fmt, ...); +#endif + +sds sdscatfmt(sds s, char const *fmt, ...); +sds sdstrim(sds s, const char *cset); +int sdsrange(sds s, ssize_t start, ssize_t end); +void sdsupdatelen(sds s); +void sdsclear(sds s); +int sdscmp(const sds s1, const sds s2); +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count); +void sdsfreesplitres(sds *tokens, int count); +void sdstolower(sds s); +void sdstoupper(sds s); +sds sdsfromlonglong(long long value); +sds sdscatrepr(sds s, const char *p, size_t len); +sds *sdssplitargs(const char *line, int *argc); +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); +sds sdsjoin(char **argv, int argc, char *sep); +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen); + +/* Low level functions exposed to the user API */ +sds sdsMakeRoomFor(sds s, size_t addlen); +void sdsIncrLen(sds s, int incr); +sds sdsRemoveFreeSpace(sds s); +size_t sdsAllocSize(sds s); +void *sdsAllocPtr(sds s); + +/* Export the allocator used by SDS to the program using SDS. + * Sometimes the program SDS is linked to, may use a different set of + * allocators, but may want to allocate or free things that SDS will + * respectively free or allocate. */ +void *sds_malloc(size_t size); +void *sds_realloc(void *ptr, size_t size); +void sds_free(void *ptr); + +#ifdef REDIS_TEST +int sdsTest(int argc, char *argv[]); +#endif + +#endif diff --git a/ext/hiredis-1.0.2/sdsalloc.h b/ext/hiredis-1.0.2/sdsalloc.h new file mode 100644 index 0000000..5538dd9 --- /dev/null +++ b/ext/hiredis-1.0.2/sdsalloc.h @@ -0,0 +1,44 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* SDS allocator selection. + * + * This file is used in order to change the SDS allocator at compile time. + * Just define the following defines to what you want to use. Also add + * the include of your alternate allocator if needed (not needed in order + * to use the default libc allocator). */ + +#include "alloc.h" + +#define s_malloc hi_malloc +#define s_realloc hi_realloc +#define s_free hi_free diff --git a/ext/hiredis-1.0.2/sockcompat.c b/ext/hiredis-1.0.2/sockcompat.c new file mode 100644 index 0000000..f99d14b --- /dev/null +++ b/ext/hiredis-1.0.2/sockcompat.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2019, Marcus Geelnard + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define REDIS_SOCKCOMPAT_IMPLEMENTATION +#include "sockcompat.h" + +#ifdef _WIN32 +static int _wsaErrorToErrno(int err) { + switch (err) { + case WSAEWOULDBLOCK: + return EWOULDBLOCK; + case WSAEINPROGRESS: + return EINPROGRESS; + case WSAEALREADY: + return EALREADY; + case WSAENOTSOCK: + return ENOTSOCK; + case WSAEDESTADDRREQ: + return EDESTADDRREQ; + case WSAEMSGSIZE: + return EMSGSIZE; + case WSAEPROTOTYPE: + return EPROTOTYPE; + case WSAENOPROTOOPT: + return ENOPROTOOPT; + case WSAEPROTONOSUPPORT: + return EPROTONOSUPPORT; + case WSAEOPNOTSUPP: + return EOPNOTSUPP; + case WSAEAFNOSUPPORT: + return EAFNOSUPPORT; + case WSAEADDRINUSE: + return EADDRINUSE; + case WSAEADDRNOTAVAIL: + return EADDRNOTAVAIL; + case WSAENETDOWN: + return ENETDOWN; + case WSAENETUNREACH: + return ENETUNREACH; + case WSAENETRESET: + return ENETRESET; + case WSAECONNABORTED: + return ECONNABORTED; + case WSAECONNRESET: + return ECONNRESET; + case WSAENOBUFS: + return ENOBUFS; + case WSAEISCONN: + return EISCONN; + case WSAENOTCONN: + return ENOTCONN; + case WSAETIMEDOUT: + return ETIMEDOUT; + case WSAECONNREFUSED: + return ECONNREFUSED; + case WSAELOOP: + return ELOOP; + case WSAENAMETOOLONG: + return ENAMETOOLONG; + case WSAEHOSTUNREACH: + return EHOSTUNREACH; + case WSAENOTEMPTY: + return ENOTEMPTY; + default: + /* We just return a generic I/O error if we could not find a relevant error. */ + return EIO; + } +} + +static void _updateErrno(int success) { + errno = success ? 0 : _wsaErrorToErrno(WSAGetLastError()); +} + +static int _initWinsock() { + static int s_initialized = 0; + if (!s_initialized) { + static WSADATA wsadata; + int err = WSAStartup(MAKEWORD(2,2), &wsadata); + if (err != 0) { + errno = _wsaErrorToErrno(err); + return 0; + } + s_initialized = 1; + } + return 1; +} + +int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { + /* Note: This function is likely to be called before other functions, so run init here. */ + if (!_initWinsock()) { + return EAI_FAIL; + } + + switch (getaddrinfo(node, service, hints, res)) { + case 0: return 0; + case WSATRY_AGAIN: return EAI_AGAIN; + case WSAEINVAL: return EAI_BADFLAGS; + case WSAEAFNOSUPPORT: return EAI_FAMILY; + case WSA_NOT_ENOUGH_MEMORY: return EAI_MEMORY; + case WSAHOST_NOT_FOUND: return EAI_NONAME; + case WSATYPE_NOT_FOUND: return EAI_SERVICE; + case WSAESOCKTNOSUPPORT: return EAI_SOCKTYPE; + default: return EAI_FAIL; /* Including WSANO_RECOVERY */ + } +} + +const char *win32_gai_strerror(int errcode) { + switch (errcode) { + case 0: errcode = 0; break; + case EAI_AGAIN: errcode = WSATRY_AGAIN; break; + case EAI_BADFLAGS: errcode = WSAEINVAL; break; + case EAI_FAMILY: errcode = WSAEAFNOSUPPORT; break; + case EAI_MEMORY: errcode = WSA_NOT_ENOUGH_MEMORY; break; + case EAI_NONAME: errcode = WSAHOST_NOT_FOUND; break; + case EAI_SERVICE: errcode = WSATYPE_NOT_FOUND; break; + case EAI_SOCKTYPE: errcode = WSAESOCKTNOSUPPORT; break; + default: errcode = WSANO_RECOVERY; break; /* Including EAI_FAIL */ + } + return gai_strerror(errcode); +} + +void win32_freeaddrinfo(struct addrinfo *res) { + freeaddrinfo(res); +} + +SOCKET win32_socket(int domain, int type, int protocol) { + SOCKET s; + + /* Note: This function is likely to be called before other functions, so run init here. */ + if (!_initWinsock()) { + return INVALID_SOCKET; + } + + _updateErrno((s = socket(domain, type, protocol)) != INVALID_SOCKET); + return s; +} + +int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp) { + int ret = ioctlsocket(fd, (long)request, argp); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) { + int ret = bind(sockfd, addr, addrlen); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) { + int ret = connect(sockfd, addr, addrlen); + _updateErrno(ret != SOCKET_ERROR); + + /* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as + * EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX + * logic consistent. */ + if (errno == EWOULDBLOCK) { + errno = EINPROGRESS; + } + + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen) { + int ret = 0; + if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) { + if (*optlen >= sizeof (struct timeval)) { + struct timeval *tv = optval; + DWORD timeout = 0; + socklen_t dwlen = 0; + ret = getsockopt(sockfd, level, optname, (char *)&timeout, &dwlen); + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout * 1000) % 1000000; + } else { + ret = WSAEFAULT; + } + *optlen = sizeof (struct timeval); + } else { + ret = getsockopt(sockfd, level, optname, (char*)optval, optlen); + } + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen) { + int ret = 0; + if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) { + const struct timeval *tv = optval; + DWORD timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + ret = setsockopt(sockfd, level, optname, (const char*)&timeout, sizeof(DWORD)); + } else { + ret = setsockopt(sockfd, level, optname, (const char*)optval, optlen); + } + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_close(SOCKET fd) { + int ret = closesocket(fd); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags) { + int ret = recv(sockfd, (char*)buf, (int)len, flags); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags) { + int ret = send(sockfd, (const char*)buf, (int)len, flags); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout) { + int ret = WSAPoll(fds, nfds, timeout); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} +#endif /* _WIN32 */ diff --git a/ext/hiredis-1.0.2/sockcompat.h b/ext/hiredis-1.0.2/sockcompat.h new file mode 100644 index 0000000..85810e8 --- /dev/null +++ b/ext/hiredis-1.0.2/sockcompat.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019, Marcus Geelnard + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SOCKCOMPAT_H +#define __SOCKCOMPAT_H + +#ifndef _WIN32 +/* For POSIX systems we use the standard BSD socket API. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +/* For Windows we use winsock. */ +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 /* To get WSAPoll etc. */ +#include +#include +#include +#include + +#ifdef _MSC_VER +typedef long long ssize_t; +#endif + +/* Emulate the parts of the BSD socket API that we need (override the winsock signatures). */ +int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); +const char *win32_gai_strerror(int errcode); +void win32_freeaddrinfo(struct addrinfo *res); +SOCKET win32_socket(int domain, int type, int protocol); +int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp); +int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); +int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); +int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen); +int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen); +int win32_close(SOCKET fd); +ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags); +ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags); +typedef ULONG nfds_t; +int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout); + +#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION +#define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res) +#undef gai_strerror +#define gai_strerror(errcode) win32_gai_strerror(errcode) +#define freeaddrinfo(res) win32_freeaddrinfo(res) +#define socket(domain, type, protocol) win32_socket(domain, type, protocol) +#define ioctl(fd, request, argp) win32_ioctl(fd, request, argp) +#define bind(sockfd, addr, addrlen) win32_bind(sockfd, addr, addrlen) +#define connect(sockfd, addr, addrlen) win32_connect(sockfd, addr, addrlen) +#define getsockopt(sockfd, level, optname, optval, optlen) win32_getsockopt(sockfd, level, optname, optval, optlen) +#define setsockopt(sockfd, level, optname, optval, optlen) win32_setsockopt(sockfd, level, optname, optval, optlen) +#define close(fd) win32_close(fd) +#define recv(sockfd, buf, len, flags) win32_recv(sockfd, buf, len, flags) +#define send(sockfd, buf, len, flags) win32_send(sockfd, buf, len, flags) +#define poll(fds, nfds, timeout) win32_poll(fds, nfds, timeout) +#endif /* REDIS_SOCKCOMPAT_IMPLEMENTATION */ +#endif /* _WIN32 */ + +#endif /* __SOCKCOMPAT_H */ diff --git a/ext/hiredis-1.0.2/ssl.c b/ext/hiredis-1.0.2/ssl.c new file mode 100644 index 0000000..7df58fb --- /dev/null +++ b/ext/hiredis-1.0.2/ssl.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * Copyright (c) 2019, Redis Labs + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "hiredis.h" +#include "async.h" + +#include +#include +#include +#ifdef _WIN32 +#include +#else +#include +#endif + +#include +#include + +#include "win32.h" +#include "async_private.h" +#include "hiredis_ssl.h" + +void __redisSetError(redisContext *c, int type, const char *str); + +struct redisSSLContext { + /* Associated OpenSSL SSL_CTX as created by redisCreateSSLContext() */ + SSL_CTX *ssl_ctx; + + /* Requested SNI, or NULL */ + char *server_name; +}; + +/* The SSL connection context is attached to SSL/TLS connections as a privdata. */ +typedef struct redisSSL { + /** + * OpenSSL SSL object. + */ + SSL *ssl; + + /** + * SSL_write() requires to be called again with the same arguments it was + * previously called with in the event of an SSL_read/SSL_write situation + */ + size_t lastLen; + + /** Whether the SSL layer requires read (possibly before a write) */ + int wantRead; + + /** + * Whether a write was requested prior to a read. If set, the write() + * should resume whenever a read takes place, if possible + */ + int pendingWrite; +} redisSSL; + +/* Forward declaration */ +redisContextFuncs redisContextSSLFuncs; + +/** + * OpenSSL global initialization and locking handling callbacks. + * Note that this is only required for OpenSSL < 1.1.0. + */ + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define HIREDIS_USE_CRYPTO_LOCKS +#endif + +#ifdef HIREDIS_USE_CRYPTO_LOCKS +#ifdef _WIN32 +typedef CRITICAL_SECTION sslLockType; +static void sslLockInit(sslLockType* l) { + InitializeCriticalSection(l); +} +static void sslLockAcquire(sslLockType* l) { + EnterCriticalSection(l); +} +static void sslLockRelease(sslLockType* l) { + LeaveCriticalSection(l); +} +#else +typedef pthread_mutex_t sslLockType; +static void sslLockInit(sslLockType *l) { + pthread_mutex_init(l, NULL); +} +static void sslLockAcquire(sslLockType *l) { + pthread_mutex_lock(l); +} +static void sslLockRelease(sslLockType *l) { + pthread_mutex_unlock(l); +} +#endif + +static sslLockType* ossl_locks; + +static void opensslDoLock(int mode, int lkid, const char *f, int line) { + sslLockType *l = ossl_locks + lkid; + + if (mode & CRYPTO_LOCK) { + sslLockAcquire(l); + } else { + sslLockRelease(l); + } + + (void)f; + (void)line; +} + +static int initOpensslLocks(void) { + unsigned ii, nlocks; + if (CRYPTO_get_locking_callback() != NULL) { + /* Someone already set the callback before us. Don't destroy it! */ + return REDIS_OK; + } + nlocks = CRYPTO_num_locks(); + ossl_locks = hi_malloc(sizeof(*ossl_locks) * nlocks); + if (ossl_locks == NULL) + return REDIS_ERR; + + for (ii = 0; ii < nlocks; ii++) { + sslLockInit(ossl_locks + ii); + } + CRYPTO_set_locking_callback(opensslDoLock); + return REDIS_OK; +} +#endif /* HIREDIS_USE_CRYPTO_LOCKS */ + +int redisInitOpenSSL(void) +{ + SSL_library_init(); +#ifdef HIREDIS_USE_CRYPTO_LOCKS + initOpensslLocks(); +#endif + + return REDIS_OK; +} + +/** + * redisSSLContext helper context destruction. + */ + +const char *redisSSLContextGetError(redisSSLContextError error) +{ + switch (error) { + case REDIS_SSL_CTX_NONE: + return "No Error"; + case REDIS_SSL_CTX_CREATE_FAILED: + return "Failed to create OpenSSL SSL_CTX"; + case REDIS_SSL_CTX_CERT_KEY_REQUIRED: + return "Client cert and key must both be specified or skipped"; + case REDIS_SSL_CTX_CA_CERT_LOAD_FAILED: + return "Failed to load CA Certificate or CA Path"; + case REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED: + return "Failed to load client certificate"; + case REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED: + return "Failed to load private key"; + default: + return "Unknown error code"; + } +} + +void redisFreeSSLContext(redisSSLContext *ctx) +{ + if (!ctx) + return; + + if (ctx->server_name) { + hi_free(ctx->server_name); + ctx->server_name = NULL; + } + + if (ctx->ssl_ctx) { + SSL_CTX_free(ctx->ssl_ctx); + ctx->ssl_ctx = NULL; + } + + hi_free(ctx); +} + + +/** + * redisSSLContext helper context initialization. + */ + +redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath, + const char *cert_filename, const char *private_key_filename, + const char *server_name, redisSSLContextError *error) +{ + redisSSLContext *ctx = hi_calloc(1, sizeof(redisSSLContext)); + if (ctx == NULL) + goto error; + + ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method()); + if (!ctx->ssl_ctx) { + if (error) *error = REDIS_SSL_CTX_CREATE_FAILED; + goto error; + } + + SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL); + + if ((cert_filename != NULL && private_key_filename == NULL) || + (private_key_filename != NULL && cert_filename == NULL)) { + if (error) *error = REDIS_SSL_CTX_CERT_KEY_REQUIRED; + goto error; + } + + if (capath || cacert_filename) { + if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, cacert_filename, capath)) { + if (error) *error = REDIS_SSL_CTX_CA_CERT_LOAD_FAILED; + goto error; + } + } + + if (cert_filename) { + if (!SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, cert_filename)) { + if (error) *error = REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED; + goto error; + } + if (!SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, private_key_filename, SSL_FILETYPE_PEM)) { + if (error) *error = REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED; + goto error; + } + } + + if (server_name) + ctx->server_name = hi_strdup(server_name); + + return ctx; + +error: + redisFreeSSLContext(ctx); + return NULL; +} + +/** + * SSL Connection initialization. + */ + + +static int redisSSLConnect(redisContext *c, SSL *ssl) { + if (c->privctx) { + __redisSetError(c, REDIS_ERR_OTHER, "redisContext was already associated"); + return REDIS_ERR; + } + + redisSSL *rssl = hi_calloc(1, sizeof(redisSSL)); + if (rssl == NULL) { + __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); + return REDIS_ERR; + } + + c->funcs = &redisContextSSLFuncs; + rssl->ssl = ssl; + + SSL_set_mode(rssl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + SSL_set_fd(rssl->ssl, c->fd); + SSL_set_connect_state(rssl->ssl); + + ERR_clear_error(); + int rv = SSL_connect(rssl->ssl); + if (rv == 1) { + c->privctx = rssl; + return REDIS_OK; + } + + rv = SSL_get_error(rssl->ssl, rv); + if (((c->flags & REDIS_BLOCK) == 0) && + (rv == SSL_ERROR_WANT_READ || rv == SSL_ERROR_WANT_WRITE)) { + c->privctx = rssl; + return REDIS_OK; + } + + if (c->err == 0) { + char err[512]; + if (rv == SSL_ERROR_SYSCALL) + snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",strerror(errno)); + else { + unsigned long e = ERR_peek_last_error(); + snprintf(err,sizeof(err)-1,"SSL_connect failed: %s", + ERR_reason_error_string(e)); + } + __redisSetError(c, REDIS_ERR_IO, err); + } + + hi_free(rssl); + return REDIS_ERR; +} + +/** + * A wrapper around redisSSLConnect() for users who manage their own context and + * create their own SSL object. + */ + +int redisInitiateSSL(redisContext *c, SSL *ssl) { + return redisSSLConnect(c, ssl); +} + +/** + * A wrapper around redisSSLConnect() for users who use redisSSLContext and don't + * manage their own SSL objects. + */ + +int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx) +{ + if (!c || !redis_ssl_ctx) + return REDIS_ERR; + + /* We want to verify that redisSSLConnect() won't fail on this, as it will + * not own the SSL object in that case and we'll end up leaking. + */ + if (c->privctx) + return REDIS_ERR; + + SSL *ssl = SSL_new(redis_ssl_ctx->ssl_ctx); + if (!ssl) { + __redisSetError(c, REDIS_ERR_OTHER, "Couldn't create new SSL instance"); + goto error; + } + + if (redis_ssl_ctx->server_name) { + if (!SSL_set_tlsext_host_name(ssl, redis_ssl_ctx->server_name)) { + __redisSetError(c, REDIS_ERR_OTHER, "Failed to set server_name/SNI"); + goto error; + } + } + + return redisSSLConnect(c, ssl); + +error: + if (ssl) + SSL_free(ssl); + return REDIS_ERR; +} + +static int maybeCheckWant(redisSSL *rssl, int rv) { + /** + * If the error is WANT_READ or WANT_WRITE, the appropriate flags are set + * and true is returned. False is returned otherwise + */ + if (rv == SSL_ERROR_WANT_READ) { + rssl->wantRead = 1; + return 1; + } else if (rv == SSL_ERROR_WANT_WRITE) { + rssl->pendingWrite = 1; + return 1; + } else { + return 0; + } +} + +/** + * Implementation of redisContextFuncs for SSL connections. + */ + +static void redisSSLFree(void *privctx){ + redisSSL *rsc = privctx; + + if (!rsc) return; + if (rsc->ssl) { + SSL_free(rsc->ssl); + rsc->ssl = NULL; + } + hi_free(rsc); +} + +static ssize_t redisSSLRead(redisContext *c, char *buf, size_t bufcap) { + redisSSL *rssl = c->privctx; + + int nread = SSL_read(rssl->ssl, buf, bufcap); + if (nread > 0) { + return nread; + } else if (nread == 0) { + __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection"); + return -1; + } else { + int err = SSL_get_error(rssl->ssl, nread); + if (c->flags & REDIS_BLOCK) { + /** + * In blocking mode, we should never end up in a situation where + * we get an error without it being an actual error, except + * in the case of EINTR, which can be spuriously received from + * debuggers or whatever. + */ + if (errno == EINTR) { + return 0; + } else { + const char *msg = NULL; + if (errno == EAGAIN) { + msg = "Resource temporarily unavailable"; + } + __redisSetError(c, REDIS_ERR_IO, msg); + return -1; + } + } + + /** + * We can very well get an EWOULDBLOCK/EAGAIN, however + */ + if (maybeCheckWant(rssl, err)) { + return 0; + } else { + __redisSetError(c, REDIS_ERR_IO, NULL); + return -1; + } + } +} + +static ssize_t redisSSLWrite(redisContext *c) { + redisSSL *rssl = c->privctx; + + size_t len = rssl->lastLen ? rssl->lastLen : sdslen(c->obuf); + int rv = SSL_write(rssl->ssl, c->obuf, len); + + if (rv > 0) { + rssl->lastLen = 0; + } else if (rv < 0) { + rssl->lastLen = len; + + int err = SSL_get_error(rssl->ssl, rv); + if ((c->flags & REDIS_BLOCK) == 0 && maybeCheckWant(rssl, err)) { + return 0; + } else { + __redisSetError(c, REDIS_ERR_IO, NULL); + return -1; + } + } + return rv; +} + +static void redisSSLAsyncRead(redisAsyncContext *ac) { + int rv; + redisSSL *rssl = ac->c.privctx; + redisContext *c = &ac->c; + + rssl->wantRead = 0; + + if (rssl->pendingWrite) { + int done; + + /* This is probably just a write event */ + rssl->pendingWrite = 0; + rv = redisBufferWrite(c, &done); + if (rv == REDIS_ERR) { + __redisAsyncDisconnect(ac); + return; + } else if (!done) { + _EL_ADD_WRITE(ac); + } + } + + rv = redisBufferRead(c); + if (rv == REDIS_ERR) { + __redisAsyncDisconnect(ac); + } else { + _EL_ADD_READ(ac); + redisProcessCallbacks(ac); + } +} + +static void redisSSLAsyncWrite(redisAsyncContext *ac) { + int rv, done = 0; + redisSSL *rssl = ac->c.privctx; + redisContext *c = &ac->c; + + rssl->pendingWrite = 0; + rv = redisBufferWrite(c, &done); + if (rv == REDIS_ERR) { + __redisAsyncDisconnect(ac); + return; + } + + if (!done) { + if (rssl->wantRead) { + /* Need to read-before-write */ + rssl->pendingWrite = 1; + _EL_DEL_WRITE(ac); + } else { + /* No extra reads needed, just need to write more */ + _EL_ADD_WRITE(ac); + } + } else { + /* Already done! */ + _EL_DEL_WRITE(ac); + } + + /* Always reschedule a read */ + _EL_ADD_READ(ac); +} + +redisContextFuncs redisContextSSLFuncs = { + .free_privctx = redisSSLFree, + .async_read = redisSSLAsyncRead, + .async_write = redisSSLAsyncWrite, + .read = redisSSLRead, + .write = redisSSLWrite +}; + diff --git a/ext/hiredis-1.0.2/test.c b/ext/hiredis-1.0.2/test.c new file mode 100644 index 0000000..397f564 --- /dev/null +++ b/ext/hiredis-1.0.2/test.c @@ -0,0 +1,1401 @@ +#include "fmacros.h" +#include "sockcompat.h" +#include +#include +#include +#ifndef _WIN32 +#include +#include +#endif +#include +#include +#include +#include + +#include "hiredis.h" +#include "async.h" +#ifdef HIREDIS_TEST_SSL +#include "hiredis_ssl.h" +#endif +#include "net.h" +#include "win32.h" + +enum connection_type { + CONN_TCP, + CONN_UNIX, + CONN_FD, + CONN_SSL +}; + +struct config { + enum connection_type type; + + struct { + const char *host; + int port; + struct timeval timeout; + } tcp; + + struct { + const char *path; + } unix_sock; + + struct { + const char *host; + int port; + const char *ca_cert; + const char *cert; + const char *key; + } ssl; +}; + +struct privdata { + int dtor_counter; +}; + +#ifdef HIREDIS_TEST_SSL +redisSSLContext *_ssl_ctx = NULL; +#endif + +/* The following lines make up our testing "framework" :) */ +static int tests = 0, fails = 0, skips = 0; +#define test(_s) { printf("#%02d ", ++tests); printf(_s); } +#define test_cond(_c) if(_c) printf("\033[0;32mPASSED\033[0;0m\n"); else {printf("\033[0;31mFAILED\033[0;0m\n"); fails++;} +#define test_skipped() { printf("\033[01;33mSKIPPED\033[0;0m\n"); skips++; } + +static long long usec(void) { +#ifndef _MSC_VER + struct timeval tv; + gettimeofday(&tv,NULL); + return (((long long)tv.tv_sec)*1000000)+tv.tv_usec; +#else + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + return (((long long)ft.dwHighDateTime << 32) | ft.dwLowDateTime) / 10; +#endif +} + +/* The assert() calls below have side effects, so we need assert() + * even if we are compiling without asserts (-DNDEBUG). */ +#ifdef NDEBUG +#undef assert +#define assert(e) (void)(e) +#endif + +/* Helper to extract Redis version information. Aborts on any failure. */ +#define REDIS_VERSION_FIELD "redis_version:" +void get_redis_version(redisContext *c, int *majorptr, int *minorptr) { + redisReply *reply; + char *eptr, *s, *e; + int major, minor; + + reply = redisCommand(c, "INFO"); + if (reply == NULL || c->err || reply->type != REDIS_REPLY_STRING) + goto abort; + if ((s = strstr(reply->str, REDIS_VERSION_FIELD)) == NULL) + goto abort; + + s += strlen(REDIS_VERSION_FIELD); + + /* We need a field terminator and at least 'x.y.z' (5) bytes of data */ + if ((e = strstr(s, "\r\n")) == NULL || (e - s) < 5) + goto abort; + + /* Extract version info */ + major = strtol(s, &eptr, 10); + if (*eptr != '.') goto abort; + minor = strtol(eptr+1, NULL, 10); + + /* Push info the caller wants */ + if (majorptr) *majorptr = major; + if (minorptr) *minorptr = minor; + + freeReplyObject(reply); + return; + +abort: + freeReplyObject(reply); + fprintf(stderr, "Error: Cannot determine Redis version, aborting\n"); + exit(1); +} + +static redisContext *select_database(redisContext *c) { + redisReply *reply; + + /* Switch to DB 9 for testing, now that we know we can chat. */ + reply = redisCommand(c,"SELECT 9"); + assert(reply != NULL); + freeReplyObject(reply); + + /* Make sure the DB is emtpy */ + reply = redisCommand(c,"DBSIZE"); + assert(reply != NULL); + if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) { + /* Awesome, DB 9 is empty and we can continue. */ + freeReplyObject(reply); + } else { + printf("Database #9 is not empty, test can not continue\n"); + exit(1); + } + + return c; +} + +/* Switch protocol */ +static void send_hello(redisContext *c, int version) { + redisReply *reply; + int expected; + + reply = redisCommand(c, "HELLO %d", version); + expected = version == 3 ? REDIS_REPLY_MAP : REDIS_REPLY_ARRAY; + assert(reply != NULL && reply->type == expected); + freeReplyObject(reply); +} + +/* Togggle client tracking */ +static void send_client_tracking(redisContext *c, const char *str) { + redisReply *reply; + + reply = redisCommand(c, "CLIENT TRACKING %s", str); + assert(reply != NULL && reply->type == REDIS_REPLY_STATUS); + freeReplyObject(reply); +} + +static int disconnect(redisContext *c, int keep_fd) { + redisReply *reply; + + /* Make sure we're on DB 9. */ + reply = redisCommand(c,"SELECT 9"); + assert(reply != NULL); + freeReplyObject(reply); + reply = redisCommand(c,"FLUSHDB"); + assert(reply != NULL); + freeReplyObject(reply); + + /* Free the context as well, but keep the fd if requested. */ + if (keep_fd) + return redisFreeKeepFd(c); + redisFree(c); + return -1; +} + +static void do_ssl_handshake(redisContext *c) { +#ifdef HIREDIS_TEST_SSL + redisInitiateSSLWithContext(c, _ssl_ctx); + if (c->err) { + printf("SSL error: %s\n", c->errstr); + redisFree(c); + exit(1); + } +#else + (void) c; +#endif +} + +static redisContext *do_connect(struct config config) { + redisContext *c = NULL; + + if (config.type == CONN_TCP) { + c = redisConnect(config.tcp.host, config.tcp.port); + } else if (config.type == CONN_SSL) { + c = redisConnect(config.ssl.host, config.ssl.port); + } else if (config.type == CONN_UNIX) { + c = redisConnectUnix(config.unix_sock.path); + } else if (config.type == CONN_FD) { + /* Create a dummy connection just to get an fd to inherit */ + redisContext *dummy_ctx = redisConnectUnix(config.unix_sock.path); + if (dummy_ctx) { + int fd = disconnect(dummy_ctx, 1); + printf("Connecting to inherited fd %d\n", fd); + c = redisConnectFd(fd); + } + } else { + assert(NULL); + } + + if (c == NULL) { + printf("Connection error: can't allocate redis context\n"); + exit(1); + } else if (c->err) { + printf("Connection error: %s\n", c->errstr); + redisFree(c); + exit(1); + } + + if (config.type == CONN_SSL) { + do_ssl_handshake(c); + } + + return select_database(c); +} + +static void do_reconnect(redisContext *c, struct config config) { + redisReconnect(c); + + if (config.type == CONN_SSL) { + do_ssl_handshake(c); + } +} + +static void test_format_commands(void) { + char *cmd; + int len; + + test("Format command without interpolation: "); + len = redisFormatCommand(&cmd,"SET foo bar"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + hi_free(cmd); + + test("Format command with %%s string interpolation: "); + len = redisFormatCommand(&cmd,"SET %s %s","foo","bar"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + hi_free(cmd); + + test("Format command with %%s and an empty string: "); + len = redisFormatCommand(&cmd,"SET %s %s","foo",""); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(0+2)); + hi_free(cmd); + + test("Format command with an empty string in between proper interpolations: "); + len = redisFormatCommand(&cmd,"SET %s %s","","foo"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 && + len == 4+4+(3+2)+4+(0+2)+4+(3+2)); + hi_free(cmd); + + test("Format command with %%b string interpolation: "); + len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + hi_free(cmd); + + test("Format command with %%b and an empty string: "); + len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(0+2)); + hi_free(cmd); + + test("Format command with literal %%: "); + len = redisFormatCommand(&cmd,"SET %% %%"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 && + len == 4+4+(3+2)+4+(1+2)+4+(1+2)); + hi_free(cmd); + + /* Vararg width depends on the type. These tests make sure that the + * width is correctly determined using the format and subsequent varargs + * can correctly be interpolated. */ +#define INTEGER_WIDTH_TEST(fmt, type) do { \ + type value = 123; \ + test("Format command with printf-delegation (" #type "): "); \ + len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \ + test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \ + len == 4+5+(12+2)+4+(9+2)); \ + hi_free(cmd); \ +} while(0) + +#define FLOAT_WIDTH_TEST(type) do { \ + type value = 123.0; \ + test("Format command with printf-delegation (" #type "): "); \ + len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \ + test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \ + len == 4+5+(12+2)+4+(9+2)); \ + hi_free(cmd); \ +} while(0) + + INTEGER_WIDTH_TEST("d", int); + INTEGER_WIDTH_TEST("hhd", char); + INTEGER_WIDTH_TEST("hd", short); + INTEGER_WIDTH_TEST("ld", long); + INTEGER_WIDTH_TEST("lld", long long); + INTEGER_WIDTH_TEST("u", unsigned int); + INTEGER_WIDTH_TEST("hhu", unsigned char); + INTEGER_WIDTH_TEST("hu", unsigned short); + INTEGER_WIDTH_TEST("lu", unsigned long); + INTEGER_WIDTH_TEST("llu", unsigned long long); + FLOAT_WIDTH_TEST(float); + FLOAT_WIDTH_TEST(double); + + test("Format command with invalid printf format: "); + len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3); + test_cond(len == -1); + + const char *argv[3]; + argv[0] = "SET"; + argv[1] = "foo\0xxx"; + argv[2] = "bar"; + size_t lens[3] = { 3, 7, 3 }; + int argc = 3; + + test("Format command by passing argc/argv without lengths: "); + len = redisFormatCommandArgv(&cmd,argc,argv,NULL); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + hi_free(cmd); + + test("Format command by passing argc/argv with lengths: "); + len = redisFormatCommandArgv(&cmd,argc,argv,lens); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(7+2)+4+(3+2)); + hi_free(cmd); + + sds sds_cmd; + + sds_cmd = NULL; + test("Format command into sds by passing argc/argv without lengths: "); + len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,NULL); + test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + sdsfree(sds_cmd); + + sds_cmd = NULL; + test("Format command into sds by passing argc/argv with lengths: "); + len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,lens); + test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(7+2)+4+(3+2)); + sdsfree(sds_cmd); +} + +static void test_append_formatted_commands(struct config config) { + redisContext *c; + redisReply *reply; + char *cmd; + int len; + + c = do_connect(config); + + test("Append format command: "); + + len = redisFormatCommand(&cmd, "SET foo bar"); + + test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK); + + assert(redisGetReply(c, (void*)&reply) == REDIS_OK); + + hi_free(cmd); + freeReplyObject(reply); + + disconnect(c, 0); +} + +static void test_reply_reader(void) { + redisReader *reader; + void *reply, *root; + int ret; + int i; + + test("Error handling in reply parser: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"@foo\r\n",6); + ret = redisReaderGetReply(reader,NULL); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); + redisReaderFree(reader); + + /* when the reply already contains multiple items, they must be free'd + * on an error. valgrind will bark when this doesn't happen. */ + test("Memory cleanup in reply parser: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"*2\r\n",4); + redisReaderFeed(reader,(char*)"$5\r\nhello\r\n",11); + redisReaderFeed(reader,(char*)"@foo\r\n",6); + ret = redisReaderGetReply(reader,NULL); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); + redisReaderFree(reader); + + reader = redisReaderCreate(); + test("Can handle arbitrarily nested multi-bulks: "); + for (i = 0; i < 128; i++) { + redisReaderFeed(reader,(char*)"*1\r\n", 4); + } + redisReaderFeed(reader,(char*)"$6\r\nLOLWUT\r\n",12); + ret = redisReaderGetReply(reader,&reply); + root = reply; /* Keep track of the root reply */ + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && + ((redisReply*)reply)->elements == 1); + + test("Can parse arbitrarily nested multi-bulks correctly: "); + while(i--) { + assert(reply != NULL && ((redisReply*)reply)->type == REDIS_REPLY_ARRAY); + reply = ((redisReply*)reply)->element[0]; + } + test_cond(((redisReply*)reply)->type == REDIS_REPLY_STRING && + !memcmp(((redisReply*)reply)->str, "LOLWUT", 6)); + freeReplyObject(root); + redisReaderFree(reader); + + test("Correctly parses LLONG_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":9223372036854775807\r\n",22); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_INTEGER && + ((redisReply*)reply)->integer == LLONG_MAX); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when > LLONG_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":9223372036854775808\r\n",22); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bad integer value") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Correctly parses LLONG_MIN: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":-9223372036854775808\r\n",23); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_INTEGER && + ((redisReply*)reply)->integer == LLONG_MIN); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when < LLONG_MIN: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":-9223372036854775809\r\n",23); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bad integer value") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when array < -1: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "*-2\r\n+asdf\r\n",12); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when bulk < -1: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "$-2\r\nasdf\r\n",11); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bulk string length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Can configure maximum multi-bulk elements: "); + reader = redisReaderCreate(); + reader->maxelements = 1024; + redisReaderFeed(reader, "*1025\r\n", 7); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr, "Multi-bulk length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Multi-bulk never overflows regardless of maxelements: "); + size_t bad_mbulk_len = (SIZE_MAX / sizeof(void *)) + 3; + char bad_mbulk_reply[100]; + snprintf(bad_mbulk_reply, sizeof(bad_mbulk_reply), "*%llu\r\n+asdf\r\n", + (unsigned long long) bad_mbulk_len); + + reader = redisReaderCreate(); + reader->maxelements = 0; /* Don't rely on default limit */ + redisReaderFeed(reader, bad_mbulk_reply, strlen(bad_mbulk_reply)); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && strcasecmp(reader->errstr, "Out of memory") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + +#if LLONG_MAX > SIZE_MAX + test("Set error when array > SIZE_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "*9223372036854775807\r\n+asdf\r\n",29); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when bulk > SIZE_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "$9223372036854775807\r\nasdf\r\n",28); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bulk string length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); +#endif + + test("Works with NULL functions for reply: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"+OK\r\n",5); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); + redisReaderFree(reader); + + test("Works when a single newline (\\r\\n) covers two calls to feed: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"+OK\r",4); + ret = redisReaderGetReply(reader,&reply); + assert(ret == REDIS_OK && reply == NULL); + redisReaderFeed(reader,(char*)"\n",1); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); + redisReaderFree(reader); + + test("Don't reset state after protocol error: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"x",1); + ret = redisReaderGetReply(reader,&reply); + assert(ret == REDIS_ERR); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && reply == NULL); + redisReaderFree(reader); + + /* Regression test for issue #45 on GitHub. */ + test("Don't do empty allocation for empty multi bulk: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"*0\r\n",4); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && + ((redisReply*)reply)->elements == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + /* RESP3 verbatim strings (GitHub issue #802) */ + test("Can parse RESP3 verbatim strings: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"=10\r\ntxt:LOLWUT\r\n",17); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_VERB && + !memcmp(((redisReply*)reply)->str,"LOLWUT", 6)); + freeReplyObject(reply); + redisReaderFree(reader); + + /* RESP3 push messages (Github issue #815) */ + test("Can parse RESP3 push messages: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)">2\r\n$6\r\nLOLWUT\r\n:42\r\n",21); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_PUSH && + ((redisReply*)reply)->elements == 2 && + ((redisReply*)reply)->element[0]->type == REDIS_REPLY_STRING && + !memcmp(((redisReply*)reply)->element[0]->str,"LOLWUT",6) && + ((redisReply*)reply)->element[1]->type == REDIS_REPLY_INTEGER && + ((redisReply*)reply)->element[1]->integer == 42); + freeReplyObject(reply); + redisReaderFree(reader); +} + +static void test_free_null(void) { + void *redisCtx = NULL; + void *reply = NULL; + + test("Don't fail when redisFree is passed a NULL value: "); + redisFree(redisCtx); + test_cond(redisCtx == NULL); + + test("Don't fail when freeReplyObject is passed a NULL value: "); + freeReplyObject(reply); + test_cond(reply == NULL); +} + +static void *hi_malloc_fail(size_t size) { + (void)size; + return NULL; +} + +static void *hi_calloc_fail(size_t nmemb, size_t size) { + (void)nmemb; + (void)size; + return NULL; +} + +static void *hi_realloc_fail(void *ptr, size_t size) { + (void)ptr; + (void)size; + return NULL; +} + +static void test_allocator_injection(void) { + hiredisAllocFuncs ha = { + .mallocFn = hi_malloc_fail, + .callocFn = hi_calloc_fail, + .reallocFn = hi_realloc_fail, + .strdupFn = strdup, + .freeFn = free, + }; + + // Override hiredis allocators + hiredisSetAllocators(&ha); + + test("redisContext uses injected allocators: "); + redisContext *c = redisConnect("localhost", 6379); + test_cond(c == NULL); + + test("redisReader uses injected allocators: "); + redisReader *reader = redisReaderCreate(); + test_cond(reader == NULL); + + // Return allocators to default + hiredisResetAllocators(); +} + +#define HIREDIS_BAD_DOMAIN "idontexist-noreally.com" +static void test_blocking_connection_errors(void) { + redisContext *c; + struct addrinfo hints = {.ai_family = AF_INET}; + struct addrinfo *ai_tmp = NULL; + + int rv = getaddrinfo(HIREDIS_BAD_DOMAIN, "6379", &hints, &ai_tmp); + if (rv != 0) { + // Address does *not* exist + test("Returns error when host cannot be resolved: "); + // First see if this domain name *actually* resolves to NXDOMAIN + c = redisConnect(HIREDIS_BAD_DOMAIN, 6379); + test_cond( + c->err == REDIS_ERR_OTHER && + (strcmp(c->errstr, "Name or service not known") == 0 || + strcmp(c->errstr, "Can't resolve: " HIREDIS_BAD_DOMAIN) == 0 || + strcmp(c->errstr, "Name does not resolve") == 0 || + strcmp(c->errstr, "nodename nor servname provided, or not known") == 0 || + strcmp(c->errstr, "No address associated with hostname") == 0 || + strcmp(c->errstr, "Temporary failure in name resolution") == 0 || + strcmp(c->errstr, "hostname nor servname provided, or not known") == 0 || + strcmp(c->errstr, "no address associated with name") == 0 || + strcmp(c->errstr, "No such host is known. ") == 0)); + redisFree(c); + } else { + printf("Skipping NXDOMAIN test. Found evil ISP!\n"); + freeaddrinfo(ai_tmp); + } + +#ifndef _WIN32 + test("Returns error when the port is not open: "); + c = redisConnect((char*)"localhost", 1); + test_cond(c->err == REDIS_ERR_IO && + strcmp(c->errstr,"Connection refused") == 0); + redisFree(c); + + test("Returns error when the unix_sock socket path doesn't accept connections: "); + c = redisConnectUnix((char*)"/tmp/idontexist.sock"); + test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */ + redisFree(c); +#endif +} + +/* Dummy push handler */ +void push_handler(void *privdata, void *reply) { + int *counter = privdata; + freeReplyObject(reply); + *counter += 1; +} + +/* Dummy function just to test setting a callback with redisOptions */ +void push_handler_async(redisAsyncContext *ac, void *reply) { + (void)ac; + (void)reply; +} + +static void test_resp3_push_handler(redisContext *c) { + redisPushFn *old = NULL; + redisReply *reply; + void *privdata; + int n = 0; + + /* Switch to RESP3 and turn on client tracking */ + send_hello(c, 3); + send_client_tracking(c, "ON"); + privdata = c->privdata; + c->privdata = &n; + + reply = redisCommand(c, "GET key:0"); + assert(reply != NULL); + freeReplyObject(reply); + + test("RESP3 PUSH messages are handled out of band by default: "); + reply = redisCommand(c, "SET key:0 val:0"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS); + freeReplyObject(reply); + + assert((reply = redisCommand(c, "GET key:0")) != NULL); + freeReplyObject(reply); + + old = redisSetPushCallback(c, push_handler); + test("We can set a custom RESP3 PUSH handler: "); + reply = redisCommand(c, "SET key:0 val:0"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && n == 1); + freeReplyObject(reply); + + /* Unset the push callback and generate an invalidate message making + * sure it is not handled out of band. */ + test("With no handler, PUSH replies come in-band: "); + redisSetPushCallback(c, NULL); + assert((reply = redisCommand(c, "GET key:0")) != NULL); + freeReplyObject(reply); + assert((reply = redisCommand(c, "SET key:0 invalid")) != NULL); + test_cond(reply->type == REDIS_REPLY_PUSH); + freeReplyObject(reply); + + test("With no PUSH handler, no replies are lost: "); + assert(redisGetReply(c, (void**)&reply) == REDIS_OK); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS); + freeReplyObject(reply); + + /* Return to the originally set PUSH handler */ + assert(old != NULL); + redisSetPushCallback(c, old); + + /* Switch back to RESP2 and disable tracking */ + c->privdata = privdata; + send_client_tracking(c, "OFF"); + send_hello(c, 2); +} + +redisOptions get_redis_tcp_options(struct config config) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, config.tcp.host, config.tcp.port); + return options; +} + +static void test_resp3_push_options(struct config config) { + redisAsyncContext *ac; + redisContext *c; + redisOptions options; + + test("We set a default RESP3 handler for redisContext: "); + options = get_redis_tcp_options(config); + assert((c = redisConnectWithOptions(&options)) != NULL); + test_cond(c->push_cb != NULL); + redisFree(c); + + test("We don't set a default RESP3 push handler for redisAsyncContext: "); + options = get_redis_tcp_options(config); + assert((ac = redisAsyncConnectWithOptions(&options)) != NULL); + test_cond(ac->c.push_cb == NULL); + redisAsyncFree(ac); + + test("Our REDIS_OPT_NO_PUSH_AUTOFREE flag works: "); + options = get_redis_tcp_options(config); + options.options |= REDIS_OPT_NO_PUSH_AUTOFREE; + assert((c = redisConnectWithOptions(&options)) != NULL); + test_cond(c->push_cb == NULL); + redisFree(c); + + test("We can use redisOptions to set a custom PUSH handler for redisContext: "); + options = get_redis_tcp_options(config); + options.push_cb = push_handler; + assert((c = redisConnectWithOptions(&options)) != NULL); + test_cond(c->push_cb == push_handler); + redisFree(c); + + test("We can use redisOptions to set a custom PUSH handler for redisAsyncContext: "); + options = get_redis_tcp_options(config); + options.async_push_cb = push_handler_async; + assert((ac = redisAsyncConnectWithOptions(&options)) != NULL); + test_cond(ac->push_cb == push_handler_async); + redisAsyncFree(ac); +} + +void free_privdata(void *privdata) { + struct privdata *data = privdata; + data->dtor_counter++; +} + +static void test_privdata_hooks(struct config config) { + struct privdata data = {0}; + redisOptions options; + redisContext *c; + + test("We can use redisOptions to set privdata: "); + options = get_redis_tcp_options(config); + REDIS_OPTIONS_SET_PRIVDATA(&options, &data, free_privdata); + assert((c = redisConnectWithOptions(&options)) != NULL); + test_cond(c->privdata == &data); + + test("Our privdata destructor fires when we free the context: "); + redisFree(c); + test_cond(data.dtor_counter == 1); +} + +static void test_blocking_connection(struct config config) { + redisContext *c; + redisReply *reply; + int major; + + c = do_connect(config); + + test("Is able to deliver commands: "); + reply = redisCommand(c,"PING"); + test_cond(reply->type == REDIS_REPLY_STATUS && + strcasecmp(reply->str,"pong") == 0) + freeReplyObject(reply); + + test("Is a able to send commands verbatim: "); + reply = redisCommand(c,"SET foo bar"); + test_cond (reply->type == REDIS_REPLY_STATUS && + strcasecmp(reply->str,"ok") == 0) + freeReplyObject(reply); + + test("%%s String interpolation works: "); + reply = redisCommand(c,"SET %s %s","foo","hello world"); + freeReplyObject(reply); + reply = redisCommand(c,"GET foo"); + test_cond(reply->type == REDIS_REPLY_STRING && + strcmp(reply->str,"hello world") == 0); + freeReplyObject(reply); + + test("%%b String interpolation works: "); + reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11); + freeReplyObject(reply); + reply = redisCommand(c,"GET foo"); + test_cond(reply->type == REDIS_REPLY_STRING && + memcmp(reply->str,"hello\x00world",11) == 0) + + test("Binary reply length is correct: "); + test_cond(reply->len == 11) + freeReplyObject(reply); + + test("Can parse nil replies: "); + reply = redisCommand(c,"GET nokey"); + test_cond(reply->type == REDIS_REPLY_NIL) + freeReplyObject(reply); + + /* test 7 */ + test("Can parse integer replies: "); + reply = redisCommand(c,"INCR mycounter"); + test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) + freeReplyObject(reply); + + test("Can parse multi bulk replies: "); + freeReplyObject(redisCommand(c,"LPUSH mylist foo")); + freeReplyObject(redisCommand(c,"LPUSH mylist bar")); + reply = redisCommand(c,"LRANGE mylist 0 -1"); + test_cond(reply->type == REDIS_REPLY_ARRAY && + reply->elements == 2 && + !memcmp(reply->element[0]->str,"bar",3) && + !memcmp(reply->element[1]->str,"foo",3)) + freeReplyObject(reply); + + /* m/e with multi bulk reply *before* other reply. + * specifically test ordering of reply items to parse. */ + test("Can handle nested multi bulk replies: "); + freeReplyObject(redisCommand(c,"MULTI")); + freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1")); + freeReplyObject(redisCommand(c,"PING")); + reply = (redisCommand(c,"EXEC")); + test_cond(reply->type == REDIS_REPLY_ARRAY && + reply->elements == 2 && + reply->element[0]->type == REDIS_REPLY_ARRAY && + reply->element[0]->elements == 2 && + !memcmp(reply->element[0]->element[0]->str,"bar",3) && + !memcmp(reply->element[0]->element[1]->str,"foo",3) && + reply->element[1]->type == REDIS_REPLY_STATUS && + strcasecmp(reply->element[1]->str,"pong") == 0); + freeReplyObject(reply); + + /* Make sure passing NULL to redisGetReply is safe */ + test("Can pass NULL to redisGetReply: "); + assert(redisAppendCommand(c, "PING") == REDIS_OK); + test_cond(redisGetReply(c, NULL) == REDIS_OK); + + get_redis_version(c, &major, NULL); + if (major >= 6) test_resp3_push_handler(c); + test_resp3_push_options(config); + + test_privdata_hooks(config); + + disconnect(c, 0); +} + +/* Send DEBUG SLEEP 0 to detect if we have this command */ +static int detect_debug_sleep(redisContext *c) { + int detected; + redisReply *reply = redisCommand(c, "DEBUG SLEEP 0\r\n"); + + if (reply == NULL || c->err) { + const char *cause = c->err ? c->errstr : "(none)"; + fprintf(stderr, "Error testing for DEBUG SLEEP (Redis error: %s), exiting\n", cause); + exit(-1); + } + + detected = reply->type == REDIS_REPLY_STATUS; + freeReplyObject(reply); + + return detected; +} + +static void test_blocking_connection_timeouts(struct config config) { + redisContext *c; + redisReply *reply; + ssize_t s; + const char *sleep_cmd = "DEBUG SLEEP 3\r\n"; + struct timeval tv; + + c = do_connect(config); + test("Successfully completes a command when the timeout is not exceeded: "); + reply = redisCommand(c,"SET foo fast"); + freeReplyObject(reply); + tv.tv_sec = 0; + tv.tv_usec = 10000; + redisSetTimeout(c, tv); + reply = redisCommand(c, "GET foo"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0); + freeReplyObject(reply); + disconnect(c, 0); + + c = do_connect(config); + test("Does not return a reply when the command times out: "); + if (detect_debug_sleep(c)) { + redisAppendFormattedCommand(c, sleep_cmd, strlen(sleep_cmd)); + s = c->funcs->write(c); + tv.tv_sec = 0; + tv.tv_usec = 10000; + redisSetTimeout(c, tv); + reply = redisCommand(c, "GET foo"); +#ifndef _WIN32 + test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && + strcmp(c->errstr, "Resource temporarily unavailable") == 0); +#else + test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_TIMEOUT && + strcmp(c->errstr, "recv timeout") == 0); +#endif + freeReplyObject(reply); + } else { + test_skipped(); + } + + test("Reconnect properly reconnects after a timeout: "); + do_reconnect(c, config); + reply = redisCommand(c, "PING"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + freeReplyObject(reply); + + test("Reconnect properly uses owned parameters: "); + config.tcp.host = "foo"; + config.unix_sock.path = "foo"; + do_reconnect(c, config); + reply = redisCommand(c, "PING"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + freeReplyObject(reply); + + disconnect(c, 0); +} + +static void test_blocking_io_errors(struct config config) { + redisContext *c; + redisReply *reply; + void *_reply; + int major, minor; + + /* Connect to target given by config. */ + c = do_connect(config); + get_redis_version(c, &major, &minor); + + test("Returns I/O error when the connection is lost: "); + reply = redisCommand(c,"QUIT"); + if (major > 2 || (major == 2 && minor > 0)) { + /* > 2.0 returns OK on QUIT and read() should be issued once more + * to know the descriptor is at EOF. */ + test_cond(strcasecmp(reply->str,"OK") == 0 && + redisGetReply(c,&_reply) == REDIS_ERR); + freeReplyObject(reply); + } else { + test_cond(reply == NULL); + } + +#ifndef _WIN32 + /* On 2.0, QUIT will cause the connection to be closed immediately and + * the read(2) for the reply on QUIT will set the error to EOF. + * On >2.0, QUIT will return with OK and another read(2) needed to be + * issued to find out the socket was closed by the server. In both + * conditions, the error will be set to EOF. */ + assert(c->err == REDIS_ERR_EOF && + strcmp(c->errstr,"Server closed the connection") == 0); +#endif + redisFree(c); + + c = do_connect(config); + test("Returns I/O error on socket timeout: "); + struct timeval tv = { 0, 1000 }; + assert(redisSetTimeout(c,tv) == REDIS_OK); + int respcode = redisGetReply(c,&_reply); +#ifndef _WIN32 + test_cond(respcode == REDIS_ERR && c->err == REDIS_ERR_IO && errno == EAGAIN); +#else + test_cond(respcode == REDIS_ERR && c->err == REDIS_ERR_TIMEOUT); +#endif + redisFree(c); +} + +static void test_invalid_timeout_errors(struct config config) { + redisContext *c; + + test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: "); + + config.tcp.timeout.tv_sec = 0; + config.tcp.timeout.tv_usec = 10000001; + + c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout); + + test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); + redisFree(c); + + test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: "); + + config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1; + config.tcp.timeout.tv_usec = 0; + + c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout); + + test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); + redisFree(c); +} + +/* Wrap malloc to abort on failure so OOM checks don't make the test logic + * harder to follow. */ +void *hi_malloc_safe(size_t size) { + void *ptr = hi_malloc(size); + if (ptr == NULL) { + fprintf(stderr, "Error: Out of memory\n"); + exit(-1); + } + + return ptr; +} + +static void test_throughput(struct config config) { + redisContext *c = do_connect(config); + redisReply **replies; + int i, num; + long long t1, t2; + + test("Throughput:\n"); + for (i = 0; i < 500; i++) + freeReplyObject(redisCommand(c,"LPUSH mylist foo")); + + num = 1000; + replies = hi_malloc_safe(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c,"PING"); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + hi_free(replies); + printf("\t(%dx PING: %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = hi_malloc_safe(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c,"LRANGE mylist 0 499"); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); + assert(replies[i] != NULL && replies[i]->elements == 500); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + hi_free(replies); + printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = hi_malloc_safe(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c, "INCRBY incrkey %d", 1000000); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + hi_free(replies); + printf("\t(%dx INCRBY: %.3fs)\n", num, (t2-t1)/1000000.0); + + num = 10000; + replies = hi_malloc_safe(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"PING"); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + hi_free(replies); + printf("\t(%dx PING (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = hi_malloc_safe(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"LRANGE mylist 0 499"); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); + assert(replies[i] != NULL && replies[i]->elements == 500); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + hi_free(replies); + printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = hi_malloc_safe(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"INCRBY incrkey %d", 1000000); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + hi_free(replies); + printf("\t(%dx INCRBY (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + disconnect(c, 0); +} + +// static long __test_callback_flags = 0; +// static void __test_callback(redisContext *c, void *privdata) { +// ((void)c); +// /* Shift to detect execution order */ +// __test_callback_flags <<= 8; +// __test_callback_flags |= (long)privdata; +// } +// +// static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) { +// ((void)c); +// /* Shift to detect execution order */ +// __test_callback_flags <<= 8; +// __test_callback_flags |= (long)privdata; +// if (reply) freeReplyObject(reply); +// } +// +// static redisContext *__connect_nonblock() { +// /* Reset callback flags */ +// __test_callback_flags = 0; +// return redisConnectNonBlock("127.0.0.1", port, NULL); +// } +// +// static void test_nonblocking_connection() { +// redisContext *c; +// int wdone = 0; +// +// test("Calls command callback when command is issued: "); +// c = __connect_nonblock(); +// redisSetCommandCallback(c,__test_callback,(void*)1); +// redisCommand(c,"PING"); +// test_cond(__test_callback_flags == 1); +// redisFree(c); +// +// test("Calls disconnect callback on redisDisconnect: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)2); +// redisDisconnect(c); +// test_cond(__test_callback_flags == 2); +// redisFree(c); +// +// test("Calls disconnect callback and free callback on redisFree: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)2); +// redisSetFreeCallback(c,__test_callback,(void*)4); +// redisFree(c); +// test_cond(__test_callback_flags == ((2 << 8) | 4)); +// +// test("redisBufferWrite against empty write buffer: "); +// c = __connect_nonblock(); +// test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1); +// redisFree(c); +// +// test("redisBufferWrite against not yet connected fd: "); +// c = __connect_nonblock(); +// redisCommand(c,"PING"); +// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && +// strncmp(c->error,"write:",6) == 0); +// redisFree(c); +// +// test("redisBufferWrite against closed fd: "); +// c = __connect_nonblock(); +// redisCommand(c,"PING"); +// redisDisconnect(c); +// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && +// strncmp(c->error,"write:",6) == 0); +// redisFree(c); +// +// test("Process callbacks in the right sequence: "); +// c = __connect_nonblock(); +// redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING"); +// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); +// redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING"); +// +// /* Write output buffer */ +// wdone = 0; +// while(!wdone) { +// usleep(500); +// redisBufferWrite(c,&wdone); +// } +// +// /* Read until at least one callback is executed (the 3 replies will +// * arrive in a single packet, causing all callbacks to be executed in +// * a single pass). */ +// while(__test_callback_flags == 0) { +// assert(redisBufferRead(c) == REDIS_OK); +// redisProcessCallbacks(c); +// } +// test_cond(__test_callback_flags == 0x010203); +// redisFree(c); +// +// test("redisDisconnect executes pending callbacks with NULL reply: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)1); +// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); +// redisDisconnect(c); +// test_cond(__test_callback_flags == 0x0201); +// redisFree(c); +// } + +int main(int argc, char **argv) { + struct config cfg = { + .tcp = { + .host = "127.0.0.1", + .port = 6379 + }, + .unix_sock = { + .path = "/tmp/redis.sock" + } + }; + int throughput = 1; + int test_inherit_fd = 1; + int skips_as_fails = 0; + int test_unix_socket; + + /* Parse command line options. */ + argv++; argc--; + while (argc) { + if (argc >= 2 && !strcmp(argv[0],"-h")) { + argv++; argc--; + cfg.tcp.host = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"-p")) { + argv++; argc--; + cfg.tcp.port = atoi(argv[0]); + } else if (argc >= 2 && !strcmp(argv[0],"-s")) { + argv++; argc--; + cfg.unix_sock.path = argv[0]; + } else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) { + throughput = 0; + } else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) { + test_inherit_fd = 0; + } else if (argc >= 1 && !strcmp(argv[0],"--skips-as-fails")) { + skips_as_fails = 1; +#ifdef HIREDIS_TEST_SSL + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-port")) { + argv++; argc--; + cfg.ssl.port = atoi(argv[0]); + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-host")) { + argv++; argc--; + cfg.ssl.host = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-ca-cert")) { + argv++; argc--; + cfg.ssl.ca_cert = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-cert")) { + argv++; argc--; + cfg.ssl.cert = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-key")) { + argv++; argc--; + cfg.ssl.key = argv[0]; +#endif + } else { + fprintf(stderr, "Invalid argument: %s\n", argv[0]); + exit(1); + } + argv++; argc--; + } + +#ifndef _WIN32 + /* Ignore broken pipe signal (for I/O error tests). */ + signal(SIGPIPE, SIG_IGN); + + test_unix_socket = access(cfg.unix_sock.path, F_OK) == 0; + +#else + /* Unix sockets don't exist in Windows */ + test_unix_socket = 0; +#endif + + test_allocator_injection(); + + test_format_commands(); + test_reply_reader(); + test_blocking_connection_errors(); + test_free_null(); + + printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port); + cfg.type = CONN_TCP; + test_blocking_connection(cfg); + test_blocking_connection_timeouts(cfg); + test_blocking_io_errors(cfg); + test_invalid_timeout_errors(cfg); + test_append_formatted_commands(cfg); + if (throughput) test_throughput(cfg); + + printf("\nTesting against Unix socket connection (%s): ", cfg.unix_sock.path); + if (test_unix_socket) { + printf("\n"); + cfg.type = CONN_UNIX; + test_blocking_connection(cfg); + test_blocking_connection_timeouts(cfg); + test_blocking_io_errors(cfg); + if (throughput) test_throughput(cfg); + } else { + test_skipped(); + } + +#ifdef HIREDIS_TEST_SSL + if (cfg.ssl.port && cfg.ssl.host) { + + redisInitOpenSSL(); + _ssl_ctx = redisCreateSSLContext(cfg.ssl.ca_cert, NULL, cfg.ssl.cert, cfg.ssl.key, NULL, NULL); + assert(_ssl_ctx != NULL); + + printf("\nTesting against SSL connection (%s:%d):\n", cfg.ssl.host, cfg.ssl.port); + cfg.type = CONN_SSL; + + test_blocking_connection(cfg); + test_blocking_connection_timeouts(cfg); + test_blocking_io_errors(cfg); + test_invalid_timeout_errors(cfg); + test_append_formatted_commands(cfg); + if (throughput) test_throughput(cfg); + + redisFreeSSLContext(_ssl_ctx); + _ssl_ctx = NULL; + } +#endif + + if (test_inherit_fd) { + printf("\nTesting against inherited fd (%s): ", cfg.unix_sock.path); + if (test_unix_socket) { + printf("\n"); + cfg.type = CONN_FD; + test_blocking_connection(cfg); + } else { + test_skipped(); + } + } + + if (fails || (skips_as_fails && skips)) { + printf("*** %d TESTS FAILED ***\n", fails); + if (skips) { + printf("*** %d TESTS SKIPPED ***\n", skips); + } + return 1; + } + + printf("ALL TESTS PASSED (%d skipped)\n", skips); + return 0; +} diff --git a/ext/hiredis-1.0.2/test.sh b/ext/hiredis-1.0.2/test.sh new file mode 100755 index 0000000..c72bcb0 --- /dev/null +++ b/ext/hiredis-1.0.2/test.sh @@ -0,0 +1,78 @@ +#!/bin/sh -ue + +REDIS_SERVER=${REDIS_SERVER:-redis-server} +REDIS_PORT=${REDIS_PORT:-56379} +REDIS_SSL_PORT=${REDIS_SSL_PORT:-56443} +TEST_SSL=${TEST_SSL:-0} +SKIPS_AS_FAILS=${SKIPS_AS_FAILS-:0} +SSL_TEST_ARGS= +SKIPS_ARG= + +tmpdir=$(mktemp -d) +PID_FILE=${tmpdir}/hiredis-test-redis.pid +SOCK_FILE=${tmpdir}/hiredis-test-redis.sock + +if [ "$TEST_SSL" = "1" ]; then + SSL_CA_CERT=${tmpdir}/ca.crt + SSL_CA_KEY=${tmpdir}/ca.key + SSL_CERT=${tmpdir}/redis.crt + SSL_KEY=${tmpdir}/redis.key + + openssl genrsa -out ${tmpdir}/ca.key 4096 + openssl req \ + -x509 -new -nodes -sha256 \ + -key ${SSL_CA_KEY} \ + -days 3650 \ + -subj '/CN=Hiredis Test CA' \ + -out ${SSL_CA_CERT} + openssl genrsa -out ${SSL_KEY} 2048 + openssl req \ + -new -sha256 \ + -key ${SSL_KEY} \ + -subj '/CN=Hiredis Test Cert' | \ + openssl x509 \ + -req -sha256 \ + -CA ${SSL_CA_CERT} \ + -CAkey ${SSL_CA_KEY} \ + -CAserial ${tmpdir}/ca.txt \ + -CAcreateserial \ + -days 365 \ + -out ${SSL_CERT} + + SSL_TEST_ARGS="--ssl-host 127.0.0.1 --ssl-port ${REDIS_SSL_PORT} --ssl-ca-cert ${SSL_CA_CERT} --ssl-cert ${SSL_CERT} --ssl-key ${SSL_KEY}" +fi + +cleanup() { + set +e + kill $(cat ${PID_FILE}) + rm -rf ${tmpdir} +} +trap cleanup INT TERM EXIT + +cat > ${tmpdir}/redis.conf <> ${tmpdir}/redis.conf < /* for struct timeval */ + +#ifndef inline +#define inline __inline +#endif + +#ifndef strcasecmp +#define strcasecmp stricmp +#endif + +#ifndef strncasecmp +#define strncasecmp strnicmp +#endif + +#ifndef va_copy +#define va_copy(d,s) ((d) = (s)) +#endif + +#ifndef snprintf +#define snprintf c99_snprintf + +__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +__inline int c99_snprintf(char* str, size_t size, const char* format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} +#endif +#endif /* _MSC_VER */ + +#ifdef _WIN32 +#define strerror_r(errno,buf,len) strerror_s(buf,len,errno) +#endif /* _WIN32 */ + +#endif /* _WIN32_HELPER_INCLUDE */ diff --git a/ext/http-parser/AUTHORS b/ext/http-parser/AUTHORS new file mode 100644 index 0000000..5323b68 --- /dev/null +++ b/ext/http-parser/AUTHORS @@ -0,0 +1,68 @@ +# Authors ordered by first contribution. +Ryan Dahl +Jeremy Hinegardner +Sergey Shepelev +Joe Damato +tomika +Phoenix Sol +Cliff Frey +Ewen Cheslack-Postava +Santiago Gala +Tim Becker +Jeff Terrace +Ben Noordhuis +Nathan Rajlich +Mark Nottingham +Aman Gupta +Tim Becker +Sean Cunningham +Peter Griess +Salman Haq +Cliff Frey +Jon Kolb +Fouad Mardini +Paul Querna +Felix Geisendörfer +koichik +Andre Caron +Ivo Raisr +James McLaughlin +David Gwynne +Thomas LE ROUX +Randy Rizun +Andre Louis Caron +Simon Zimmermann +Erik Dubbelboer +Martell Malone +Bertrand Paquet +BogDan Vatra +Peter Faiman +Corey Richardson +Tóth Tamás +Cam Swords +Chris Dickinson +Uli Köhler +Charlie Somerville +Patrik Stutz +Fedor Indutny +runner +Alexis Campailla +David Wragg +Vinnie Falco +Alex Butum +Rex Feng +Alex Kocharin +Mark Koopman +Helge Heß +Alexis La Goutte +George Miroshnykov +Maciej Małecki +Marc O'Morain +Jeff Pinner +Timothy J Fontaine +Akagi201 +Romain Giraud +Jay Satiro +Arne Steen +Kjell Schubert +Olivier Mengué diff --git a/ext/http-parser/LICENSE-MIT b/ext/http-parser/LICENSE-MIT new file mode 100644 index 0000000..58010b3 --- /dev/null +++ b/ext/http-parser/LICENSE-MIT @@ -0,0 +1,23 @@ +http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright +Igor Sysoev. + +Additional changes are licensed under the same terms as NGINX and +copyright Joyent, Inc. and other Node contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/ext/http-parser/README.md b/ext/http-parser/README.md new file mode 100644 index 0000000..439b309 --- /dev/null +++ b/ext/http-parser/README.md @@ -0,0 +1,246 @@ +HTTP Parser +=========== + +[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser) + +This is a parser for HTTP messages written in C. It parses both requests and +responses. The parser is designed to be used in performance HTTP +applications. It does not make any syscalls nor allocations, it does not +buffer data, it can be interrupted at anytime. Depending on your +architecture, it only requires about 40 bytes of data per message +stream (in a web server that is per connection). + +Features: + + * No dependencies + * Handles persistent streams (keep-alive). + * Decodes chunked encoding. + * Upgrade support + * Defends against buffer overflow attacks. + +The parser extracts the following information from HTTP messages: + + * Header fields and values + * Content-Length + * Request method + * Response status code + * Transfer-Encoding + * HTTP version + * Request URL + * Message body + + +Usage +----- + +One `http_parser` object is used per TCP connection. Initialize the struct +using `http_parser_init()` and set the callbacks. That might look something +like this for a request parser: +```c +http_parser_settings settings; +settings.on_url = my_url_callback; +settings.on_header_field = my_header_field_callback; +/* ... */ + +http_parser *parser = malloc(sizeof(http_parser)); +http_parser_init(parser, HTTP_REQUEST); +parser->data = my_socket; +``` + +When data is received on the socket execute the parser and check for errors. + +```c +size_t len = 80*1024, nparsed; +char buf[len]; +ssize_t recved; + +recved = recv(fd, buf, len, 0); + +if (recved < 0) { + /* Handle error. */ +} + +/* Start up / continue the parser. + * Note we pass recved==0 to signal that EOF has been received. + */ +nparsed = http_parser_execute(parser, &settings, buf, recved); + +if (parser->upgrade) { + /* handle new protocol */ +} else if (nparsed != recved) { + /* Handle error. Usually just close the connection. */ +} +``` + +HTTP needs to know where the end of the stream is. For example, sometimes +servers send responses without Content-Length and expect the client to +consume input (for the body) until EOF. To tell http_parser about EOF, give +`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors +can still be encountered during an EOF, so one must still be prepared +to receive them. + +Scalar valued message information such as `status_code`, `method`, and the +HTTP version are stored in the parser structure. This data is only +temporally stored in `http_parser` and gets reset on each new message. If +this information is needed later, copy it out of the structure during the +`headers_complete` callback. + +The parser decodes the transfer-encoding for both requests and responses +transparently. That is, a chunked encoding is decoded before being sent to +the on_body callback. + + +The Special Problem of Upgrade +------------------------------ + +HTTP supports upgrading the connection to a different protocol. An +increasingly common example of this is the WebSocket protocol which sends +a request like + + GET /demo HTTP/1.1 + Upgrade: WebSocket + Connection: Upgrade + Host: example.com + Origin: http://example.com + WebSocket-Protocol: sample + +followed by non-HTTP data. + +(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the +WebSocket protocol.) + +To support this, the parser will treat this as a normal HTTP message without a +body, issuing both on_headers_complete and on_message_complete callbacks. However +http_parser_execute() will stop parsing at the end of the headers and return. + +The user is expected to check if `parser->upgrade` has been set to 1 after +`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied +offset by the return value of `http_parser_execute()`. + + +Callbacks +--------- + +During the `http_parser_execute()` call, the callbacks set in +`http_parser_settings` will be executed. The parser maintains state and +never looks behind, so buffering the data is not necessary. If you need to +save certain data for later usage, you can do that from the callbacks. + +There are two types of callbacks: + +* notification `typedef int (*http_cb) (http_parser*);` + Callbacks: on_message_begin, on_headers_complete, on_message_complete. +* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);` + Callbacks: (requests only) on_url, + (common) on_header_field, on_header_value, on_body; + +Callbacks must return 0 on success. Returning a non-zero value indicates +error to the parser, making it exit immediately. + +For cases where it is necessary to pass local information to/from a callback, +the `http_parser` object's `data` field can be used. +An example of such a case is when using threads to handle a socket connection, +parse a request, and then give a response over that socket. By instantiation +of a thread-local struct containing relevant data (e.g. accepted socket, +allocated memory for callbacks to write into, etc), a parser's callbacks are +able to communicate data between the scope of the thread and the scope of the +callback in a threadsafe manner. This allows http-parser to be used in +multi-threaded contexts. + +Example: +```c + typedef struct { + socket_t sock; + void* buffer; + int buf_len; + } custom_data_t; + + +int my_url_callback(http_parser* parser, const char *at, size_t length) { + /* access to thread local custom_data_t struct. + Use this access save parsed data for later use into thread local + buffer, or communicate over socket + */ + parser->data; + ... + return 0; +} + +... + +void http_parser_thread(socket_t sock) { + int nparsed = 0; + /* allocate memory for user data */ + custom_data_t *my_data = malloc(sizeof(custom_data_t)); + + /* some information for use by callbacks. + * achieves thread -> callback information flow */ + my_data->sock = sock; + + /* instantiate a thread-local parser */ + http_parser *parser = malloc(sizeof(http_parser)); + http_parser_init(parser, HTTP_REQUEST); /* initialise parser */ + /* this custom data reference is accessible through the reference to the + parser supplied to callback functions */ + parser->data = my_data; + + http_parser_settings settings; /* set up callbacks */ + settings.on_url = my_url_callback; + + /* execute parser */ + nparsed = http_parser_execute(parser, &settings, buf, recved); + + ... + /* parsed information copied from callback. + can now perform action on data copied into thread-local memory from callbacks. + achieves callback -> thread information flow */ + my_data->buffer; + ... +} + +``` + +In case you parse HTTP message in chunks (i.e. `read()` request line +from socket, parse, read half headers, parse, etc) your data callbacks +may be called more than once. Http-parser guarantees that data pointer is only +valid for the lifetime of callback. You can also `read()` into a heap allocated +buffer to avoid copying memory around if this fits your application. + +Reading headers may be a tricky task if you read/parse headers partially. +Basically, you need to remember whether last header callback was field or value +and apply the following logic: + + (on_header_field and on_header_value shortened to on_h_*) + ------------------------ ------------ -------------------------------------------- + | State (prev. callback) | Callback | Description/action | + ------------------------ ------------ -------------------------------------------- + | nothing (first call) | on_h_field | Allocate new buffer and copy callback data | + | | | into it | + ------------------------ ------------ -------------------------------------------- + | value | on_h_field | New header started. | + | | | Copy current name,value buffers to headers | + | | | list and allocate new buffer for new name | + ------------------------ ------------ -------------------------------------------- + | field | on_h_field | Previous name continues. Reallocate name | + | | | buffer and append callback data to it | + ------------------------ ------------ -------------------------------------------- + | field | on_h_value | Value for current header started. Allocate | + | | | new buffer and copy callback data to it | + ------------------------ ------------ -------------------------------------------- + | value | on_h_value | Value continues. Reallocate value buffer | + | | | and append callback data to it | + ------------------------ ------------ -------------------------------------------- + + +Parsing URLs +------------ + +A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`. +Users of this library may wish to use it to parse URLs constructed from +consecutive `on_url` callbacks. + +See examples of reading in headers: + +* [partial example](http://gist.github.com/155877) in C +* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C +* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript diff --git a/ext/http-parser/http_parser.c b/ext/http-parser/http_parser.c new file mode 100644 index 0000000..895bf0c --- /dev/null +++ b/ext/http-parser/http_parser.c @@ -0,0 +1,2470 @@ +/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev + * + * Additional changes are licensed under the same terms as NGINX and + * copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "http_parser.h" +#include +#include +#include +#include +#include +#include + +#ifndef ULLONG_MAX +# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ +#endif + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#ifndef BIT_AT +# define BIT_AT(a, i) \ + (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ + (1 << ((unsigned int) (i) & 7)))) +#endif + +#ifndef ELEM_AT +# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v)) +#endif + +#define SET_ERRNO(e) \ +do { \ + parser->http_errno = (e); \ +} while(0) + +#define CURRENT_STATE() p_state +#define UPDATE_STATE(V) p_state = (enum state) (V); +#define RETURN(V) \ +do { \ + parser->state = CURRENT_STATE(); \ + return (V); \ +} while (0); +#define REEXECUTE() \ + goto reexecute; \ + + +#ifdef __GNUC__ +# define LIKELY(X) __builtin_expect(!!(X), 1) +# define UNLIKELY(X) __builtin_expect(!!(X), 0) +#else +# define LIKELY(X) (X) +# define UNLIKELY(X) (X) +#endif + + +/* Run the notify callback FOR, returning ER if it fails */ +#define CALLBACK_NOTIFY_(FOR, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != settings->on_##FOR(parser))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + UPDATE_STATE(parser->state); \ + \ + /* We either errored above or got paused; get out */ \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ + return (ER); \ + } \ + } \ +} while (0) + +/* Run the notify callback FOR and consume the current byte */ +#define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1) + +/* Run the notify callback FOR and don't consume the current byte */ +#define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data) + +/* Run data callback FOR with LEN bytes, returning ER if it fails */ +#define CALLBACK_DATA_(FOR, LEN, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (FOR##_mark) { \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != \ + settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + UPDATE_STATE(parser->state); \ + \ + /* We either errored above or got paused; get out */ \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ + return (ER); \ + } \ + } \ + FOR##_mark = NULL; \ + } \ +} while (0) + +/* Run the data callback FOR and consume the current byte */ +#define CALLBACK_DATA(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) + +/* Run the data callback FOR and don't consume the current byte */ +#define CALLBACK_DATA_NOADVANCE(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) + +/* Set the mark FOR; non-destructive if mark is already set */ +#define MARK(FOR) \ +do { \ + if (!FOR##_mark) { \ + FOR##_mark = p; \ + } \ +} while (0) + +/* Don't allow the total size of the HTTP headers (including the status + * line) to exceed HTTP_MAX_HEADER_SIZE. This check is here to protect + * embedders against denial-of-service attacks where the attacker feeds + * us a never-ending header that the embedder keeps buffering. + * + * This check is arguably the responsibility of embedders but we're doing + * it on the embedder's behalf because most won't bother and this way we + * make the web a little safer. HTTP_MAX_HEADER_SIZE is still far bigger + * than any reasonable request or response so this should never affect + * day-to-day operation. + */ +#define COUNT_HEADER_SIZE(V) \ +do { \ + parser->nread += (V); \ + if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \ + SET_ERRNO(HPE_HEADER_OVERFLOW); \ + goto error; \ + } \ +} while (0) + + +#define PROXY_CONNECTION "proxy-connection" +#define CONNECTION "connection" +#define CONTENT_LENGTH "content-length" +#define TRANSFER_ENCODING "transfer-encoding" +#define UPGRADE "upgrade" +#define CHUNKED "chunked" +#define KEEP_ALIVE "keep-alive" +#define CLOSE "close" + + +static const char *method_strings[] = + { +#define XX(num, name, string) #string, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +static const char tokens[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0, '!', 0, '#', '$', '%', '&', '\'', +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 0, 0, '*', '+', 0, '-', '.', 0, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + '0', '1', '2', '3', '4', '5', '6', '7', +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + '8', '9', 0, 0, 0, 0, 0, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 'x', 'y', 'z', 0, 0, 0, '^', '_', +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 'x', 'y', 'z', 0, '|', 0, '~', 0 }; + + +static const int8_t unhex[256] = + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; + + +#if HTTP_PARSER_STRICT +# define T(v) 0 +#else +# define T(v) v +#endif + + +static const uint8_t normal_url_char[32] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; + +#undef T + +enum state + { s_dead = 1 /* important that this is > 0 */ + + , s_start_req_or_res + , s_res_or_resp_H + , s_start_res + , s_res_H + , s_res_HT + , s_res_HTT + , s_res_HTTP + , s_res_first_http_major + , s_res_http_major + , s_res_first_http_minor + , s_res_http_minor + , s_res_first_status_code + , s_res_status_code + , s_res_status_start + , s_res_status + , s_res_line_almost_done + + , s_start_req + + , s_req_method + , s_req_spaces_before_url + , s_req_schema + , s_req_schema_slash + , s_req_schema_slash_slash + , s_req_server_start + , s_req_server + , s_req_server_with_at + , s_req_path + , s_req_query_string_start + , s_req_query_string + , s_req_fragment_start + , s_req_fragment + , s_req_http_start + , s_req_http_H + , s_req_http_HT + , s_req_http_HTT + , s_req_http_HTTP + , s_req_first_http_major + , s_req_http_major + , s_req_first_http_minor + , s_req_http_minor + , s_req_line_almost_done + + , s_header_field_start + , s_header_field + , s_header_value_discard_ws + , s_header_value_discard_ws_almost_done + , s_header_value_discard_lws + , s_header_value_start + , s_header_value + , s_header_value_lws + + , s_header_almost_done + + , s_chunk_size_start + , s_chunk_size + , s_chunk_parameters + , s_chunk_size_almost_done + + , s_headers_almost_done + , s_headers_done + + /* Important: 's_headers_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + + , s_chunk_data + , s_chunk_data_almost_done + , s_chunk_data_done + + , s_body_identity + , s_body_identity_eof + + , s_message_done + }; + + +#define PARSING_HEADER(state) (state <= s_headers_done) + + +enum header_states + { h_general = 0 + , h_C + , h_CO + , h_CON + + , h_matching_connection + , h_matching_proxy_connection + , h_matching_content_length + , h_matching_transfer_encoding + , h_matching_upgrade + + , h_connection + , h_content_length + , h_transfer_encoding + , h_upgrade + + , h_matching_transfer_encoding_chunked + , h_matching_connection_token_start + , h_matching_connection_keep_alive + , h_matching_connection_close + , h_matching_connection_upgrade + , h_matching_connection_token + + , h_transfer_encoding_chunked + , h_connection_keep_alive + , h_connection_close + , h_connection_upgrade + }; + +enum http_host_state + { + s_http_host_dead = 1 + , s_http_userinfo_start + , s_http_userinfo + , s_http_host_start + , s_http_host_v6_start + , s_http_host + , s_http_host_v6 + , s_http_host_v6_end + , s_http_host_v6_zone_start + , s_http_host_v6_zone + , s_http_host_port_start + , s_http_host_port +}; + +/* Macros for character classes; depends on strict-mode */ +#define CR '\r' +#define LF '\n' +#define LOWER(c) (unsigned char)(c | 0x20) +#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') +#define IS_NUM(c) ((c) >= '0' && (c) <= '9') +#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) +#define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) +#define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ + (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ + (c) == ')') +#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ + (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ + (c) == '$' || (c) == ',') + +#define STRICT_TOKEN(c) (tokens[(unsigned char)c]) + +#if HTTP_PARSER_STRICT +#define TOKEN(c) (tokens[(unsigned char)c]) +#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) +#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') +#else +#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) +#define IS_URL_CHAR(c) \ + (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) +#define IS_HOST_CHAR(c) \ + (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') +#endif + +/** + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + **/ +#define IS_HEADER_CHAR(ch) \ + (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127)) + +#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) + + +#if HTTP_PARSER_STRICT +# define STRICT_CHECK(cond) \ +do { \ + if (cond) { \ + SET_ERRNO(HPE_STRICT); \ + goto error; \ + } \ +} while (0) +# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) +#else +# define STRICT_CHECK(cond) +# define NEW_MESSAGE() start_state +#endif + + +/* Map errno values to strings for human-readable output */ +#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, +static struct { + const char *name; + const char *description; +} http_strerror_tab[] = { + HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) +}; +#undef HTTP_STRERROR_GEN + +int http_message_needs_eof(const http_parser *parser); + +/* Our URL parser. + * + * This is designed to be shared by http_parser_execute() for URL validation, + * hence it has a state transition + byte-for-byte interface. In addition, it + * is meant to be embedded in http_parser_parse_url(), which does the dirty + * work of turning state transitions URL components for its API. + * + * This function should only be invoked with non-space characters. It is + * assumed that the caller cares about (and can detect) the transition between + * URL and non-URL states by looking for these. + */ +static enum state +parse_url_char(enum state s, const char ch) +{ + if (ch == ' ' || ch == '\r' || ch == '\n') { + return s_dead; + } + +#if HTTP_PARSER_STRICT + if (ch == '\t' || ch == '\f') { + return s_dead; + } +#endif + + switch (s) { + case s_req_spaces_before_url: + /* Proxied requests are followed by scheme of an absolute URI (alpha). + * All methods except CONNECT are followed by '/' or '*'. + */ + + if (ch == '/' || ch == '*') { + return s_req_path; + } + + if (IS_ALPHA(ch)) { + return s_req_schema; + } + + break; + + case s_req_schema: + if (IS_ALPHA(ch)) { + return s; + } + + if (ch == ':') { + return s_req_schema_slash; + } + + break; + + case s_req_schema_slash: + if (ch == '/') { + return s_req_schema_slash_slash; + } + + break; + + case s_req_schema_slash_slash: + if (ch == '/') { + return s_req_server_start; + } + + break; + + case s_req_server_with_at: + if (ch == '@') { + return s_dead; + } + + /* FALLTHROUGH */ + case s_req_server_start: + case s_req_server: + if (ch == '/') { + return s_req_path; + } + + if (ch == '?') { + return s_req_query_string_start; + } + + if (ch == '@') { + return s_req_server_with_at; + } + + if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { + return s_req_server; + } + + break; + + case s_req_path: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + return s_req_query_string_start; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_query_string_start: + case s_req_query_string: + if (IS_URL_CHAR(ch)) { + return s_req_query_string; + } + + switch (ch) { + case '?': + /* allow extra '?' in query string */ + return s_req_query_string; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_fragment_start: + if (IS_URL_CHAR(ch)) { + return s_req_fragment; + } + + switch (ch) { + case '?': + return s_req_fragment; + + case '#': + return s; + } + + break; + + case s_req_fragment: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + case '#': + return s; + } + + break; + + default: + break; + } + + /* We should never fall out of the switch above unless there's an error */ + return s_dead; +} + +size_t http_parser_execute (http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len) +{ + char c, ch; + int8_t unhex_val; + const char *p = data; + const char *header_field_mark = 0; + const char *header_value_mark = 0; + const char *url_mark = 0; + const char *body_mark = 0; + const char *status_mark = 0; + enum state p_state = (enum state) parser->state; + const unsigned int lenient = parser->lenient_http_headers; + + /* We're in an error state. Don't bother doing anything. */ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + return 0; + } + + if (len == 0) { + switch (CURRENT_STATE()) { + case s_body_identity_eof: + /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if + * we got paused. + */ + CALLBACK_NOTIFY_NOADVANCE(message_complete); + return 0; + + case s_dead: + case s_start_req_or_res: + case s_start_res: + case s_start_req: + return 0; + + default: + SET_ERRNO(HPE_INVALID_EOF_STATE); + return 1; + } + } + + + if (CURRENT_STATE() == s_header_field) + header_field_mark = data; + if (CURRENT_STATE() == s_header_value) + header_value_mark = data; + switch (CURRENT_STATE()) { + case s_req_path: + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_server: + case s_req_server_with_at: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + url_mark = data; + break; + case s_res_status: + status_mark = data; + break; + default: + break; + } + + for (p=data; p != data + len; p++) { + ch = *p; + + if (PARSING_HEADER(CURRENT_STATE())) + COUNT_HEADER_SIZE(1); + +reexecute: + switch (CURRENT_STATE()) { + + case s_dead: + /* this state is used after a 'Connection: close' message + * the parser will error out if it reads another message + */ + if (LIKELY(ch == CR || ch == LF)) + break; + + SET_ERRNO(HPE_CLOSED_CONNECTION); + goto error; + + case s_start_req_or_res: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (ch == 'H') { + UPDATE_STATE(s_res_or_resp_H); + + CALLBACK_NOTIFY(message_begin); + } else { + parser->type = HTTP_REQUEST; + UPDATE_STATE(s_start_req); + REEXECUTE(); + } + + break; + } + + case s_res_or_resp_H: + if (ch == 'T') { + parser->type = HTTP_RESPONSE; + UPDATE_STATE(s_res_HT); + } else { + if (UNLIKELY(ch != 'E')) { + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + parser->type = HTTP_REQUEST; + parser->method = HTTP_HEAD; + parser->index = 2; + UPDATE_STATE(s_req_method); + } + break; + + case s_start_res: + { + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + switch (ch) { + case 'H': + UPDATE_STATE(s_res_H); + break; + + case CR: + case LF: + break; + + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + CALLBACK_NOTIFY(message_begin); + break; + } + + case s_res_H: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_res_HT); + break; + + case s_res_HT: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_res_HTT); + break; + + case s_res_HTT: + STRICT_CHECK(ch != 'P'); + UPDATE_STATE(s_res_HTTP); + break; + + case s_res_HTTP: + STRICT_CHECK(ch != '/'); + UPDATE_STATE(s_res_first_http_major); + break; + + case s_res_first_http_major: + if (UNLIKELY(ch < '0' || ch > '9')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + UPDATE_STATE(s_res_http_major); + break; + + /* major HTTP version or dot */ + case s_res_http_major: + { + if (ch == '.') { + UPDATE_STATE(s_res_first_http_minor); + break; + } + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (UNLIKELY(parser->http_major > 999)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* first digit of minor HTTP version */ + case s_res_first_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + UPDATE_STATE(s_res_http_minor); + break; + + /* minor HTTP version or end of request line */ + case s_res_http_minor: + { + if (ch == ' ') { + UPDATE_STATE(s_res_first_status_code); + break; + } + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (UNLIKELY(parser->http_minor > 999)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + case s_res_first_status_code: + { + if (!IS_NUM(ch)) { + if (ch == ' ') { + break; + } + + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + parser->status_code = ch - '0'; + UPDATE_STATE(s_res_status_code); + break; + } + + case s_res_status_code: + { + if (!IS_NUM(ch)) { + switch (ch) { + case ' ': + UPDATE_STATE(s_res_status_start); + break; + case CR: + UPDATE_STATE(s_res_line_almost_done); + break; + case LF: + UPDATE_STATE(s_header_field_start); + break; + default: + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + break; + } + + parser->status_code *= 10; + parser->status_code += ch - '0'; + + if (UNLIKELY(parser->status_code > 999)) { + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + + break; + } + + case s_res_status_start: + { + if (ch == CR) { + UPDATE_STATE(s_res_line_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + break; + } + + MARK(status); + UPDATE_STATE(s_res_status); + parser->index = 0; + break; + } + + case s_res_status: + if (ch == CR) { + UPDATE_STATE(s_res_line_almost_done); + CALLBACK_DATA(status); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA(status); + break; + } + + break; + + case s_res_line_almost_done: + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_field_start); + break; + + case s_start_req: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (UNLIKELY(!IS_ALPHA(ch))) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + parser->method = (enum http_method) 0; + parser->index = 1; + switch (ch) { + case 'A': parser->method = HTTP_ACL; break; + case 'B': parser->method = HTTP_BIND; break; + case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; + case 'D': parser->method = HTTP_DELETE; break; + case 'G': parser->method = HTTP_GET; break; + case 'H': parser->method = HTTP_HEAD; break; + case 'L': parser->method = HTTP_LOCK; /* or LINK */ break; + case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; + case 'N': parser->method = HTTP_NOTIFY; break; + case 'O': parser->method = HTTP_OPTIONS; break; + case 'P': parser->method = HTTP_POST; + /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ + break; + case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break; + case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; + case 'T': parser->method = HTTP_TRACE; break; + case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break; + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + UPDATE_STATE(s_req_method); + + CALLBACK_NOTIFY(message_begin); + + break; + } + + case s_req_method: + { + const char *matcher; + if (UNLIKELY(ch == '\0')) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + matcher = method_strings[parser->method]; + if (ch == ' ' && matcher[parser->index] == '\0') { + UPDATE_STATE(s_req_spaces_before_url); + } else if (ch == matcher[parser->index]) { + ; /* nada */ + } else if (IS_ALPHA(ch)) { + + switch (parser->method << 16 | parser->index << 8 | ch) { +#define XX(meth, pos, ch, new_meth) \ + case (HTTP_##meth << 16 | pos << 8 | ch): \ + parser->method = HTTP_##new_meth; break; + + XX(POST, 1, 'U', PUT) + XX(POST, 1, 'A', PATCH) + XX(CONNECT, 1, 'H', CHECKOUT) + XX(CONNECT, 2, 'P', COPY) + XX(MKCOL, 1, 'O', MOVE) + XX(MKCOL, 1, 'E', MERGE) + XX(MKCOL, 2, 'A', MKACTIVITY) + XX(MKCOL, 3, 'A', MKCALENDAR) + XX(SUBSCRIBE, 1, 'E', SEARCH) + XX(REPORT, 2, 'B', REBIND) + XX(POST, 1, 'R', PROPFIND) + XX(PROPFIND, 4, 'P', PROPPATCH) + XX(PUT, 2, 'R', PURGE) + XX(LOCK, 1, 'I', LINK) + XX(UNLOCK, 2, 'S', UNSUBSCRIBE) + XX(UNLOCK, 2, 'B', UNBIND) + XX(UNLOCK, 3, 'I', UNLINK) +#undef XX + + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else if (ch == '-' && + parser->index == 1 && + parser->method == HTTP_MKCOL) { + parser->method = HTTP_MSEARCH; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + ++parser->index; + break; + } + + case s_req_spaces_before_url: + { + if (ch == ' ') break; + + MARK(url); + if (parser->method == HTTP_CONNECT) { + UPDATE_STATE(s_req_server_start); + } + + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + + break; + } + + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + { + switch (ch) { + /* No whitespace allowed here */ + case ' ': + case CR: + case LF: + SET_ERRNO(HPE_INVALID_URL); + goto error; + default: + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + + break; + } + + case s_req_server: + case s_req_server_with_at: + case s_req_path: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + { + switch (ch) { + case ' ': + UPDATE_STATE(s_req_http_start); + CALLBACK_DATA(url); + break; + case CR: + case LF: + parser->http_major = 0; + parser->http_minor = 9; + UPDATE_STATE((ch == CR) ? + s_req_line_almost_done : + s_header_field_start); + CALLBACK_DATA(url); + break; + default: + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + break; + } + + case s_req_http_start: + switch (ch) { + case 'H': + UPDATE_STATE(s_req_http_H); + break; + case ' ': + break; + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + break; + + case s_req_http_H: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_req_http_HT); + break; + + case s_req_http_HT: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_req_http_HTT); + break; + + case s_req_http_HTT: + STRICT_CHECK(ch != 'P'); + UPDATE_STATE(s_req_http_HTTP); + break; + + case s_req_http_HTTP: + STRICT_CHECK(ch != '/'); + UPDATE_STATE(s_req_first_http_major); + break; + + /* first digit of major HTTP version */ + case s_req_first_http_major: + if (UNLIKELY(ch < '1' || ch > '9')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + UPDATE_STATE(s_req_http_major); + break; + + /* major HTTP version or dot */ + case s_req_http_major: + { + if (ch == '.') { + UPDATE_STATE(s_req_first_http_minor); + break; + } + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (UNLIKELY(parser->http_major > 999)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* first digit of minor HTTP version */ + case s_req_first_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + UPDATE_STATE(s_req_http_minor); + break; + + /* minor HTTP version or end of request line */ + case s_req_http_minor: + { + if (ch == CR) { + UPDATE_STATE(s_req_line_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + break; + } + + /* XXX allow spaces after digit? */ + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (UNLIKELY(parser->http_minor > 999)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* end of request line */ + case s_req_line_almost_done: + { + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + UPDATE_STATE(s_header_field_start); + break; + } + + case s_header_field_start: + { + if (ch == CR) { + UPDATE_STATE(s_headers_almost_done); + break; + } + + if (ch == LF) { + /* they might be just sending \n instead of \r\n so this would be + * the second \n to denote the end of headers*/ + UPDATE_STATE(s_headers_almost_done); + REEXECUTE(); + } + + c = TOKEN(ch); + + if (UNLIKELY(!c)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + MARK(header_field); + + parser->index = 0; + UPDATE_STATE(s_header_field); + + switch (c) { + case 'c': + parser->header_state = h_C; + break; + + case 'p': + parser->header_state = h_matching_proxy_connection; + break; + + case 't': + parser->header_state = h_matching_transfer_encoding; + break; + + case 'u': + parser->header_state = h_matching_upgrade; + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_field: + { + const char* start = p; + for (; p != data + len; p++) { + ch = *p; + c = TOKEN(ch); + + if (!c) + break; + + switch (parser->header_state) { + case h_general: + break; + + case h_C: + parser->index++; + parser->header_state = (c == 'o' ? h_CO : h_general); + break; + + case h_CO: + parser->index++; + parser->header_state = (c == 'n' ? h_CON : h_general); + break; + + case h_CON: + parser->index++; + switch (c) { + case 'n': + parser->header_state = h_matching_connection; + break; + case 't': + parser->header_state = h_matching_content_length; + break; + default: + parser->header_state = h_general; + break; + } + break; + + /* connection */ + + case h_matching_connection: + parser->index++; + if (parser->index > sizeof(CONNECTION)-1 + || c != CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* proxy-connection */ + + case h_matching_proxy_connection: + parser->index++; + if (parser->index > sizeof(PROXY_CONNECTION)-1 + || c != PROXY_CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* content-length */ + + case h_matching_content_length: + parser->index++; + if (parser->index > sizeof(CONTENT_LENGTH)-1 + || c != CONTENT_LENGTH[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { + parser->header_state = h_content_length; + } + break; + + /* transfer-encoding */ + + case h_matching_transfer_encoding: + parser->index++; + if (parser->index > sizeof(TRANSFER_ENCODING)-1 + || c != TRANSFER_ENCODING[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { + parser->header_state = h_transfer_encoding; + } + break; + + /* upgrade */ + + case h_matching_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE)-1 + || c != UPGRADE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(UPGRADE)-2) { + parser->header_state = h_upgrade; + } + break; + + case h_connection: + case h_content_length: + case h_transfer_encoding: + case h_upgrade: + if (ch != ' ') parser->header_state = h_general; + break; + + default: + assert(0 && "Unknown header_state"); + break; + } + } + + COUNT_HEADER_SIZE(p - start); + + if (p == data + len) { + --p; + break; + } + + if (ch == ':') { + UPDATE_STATE(s_header_value_discard_ws); + CALLBACK_DATA(header_field); + break; + } + + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + case s_header_value_discard_ws: + if (ch == ' ' || ch == '\t') break; + + if (ch == CR) { + UPDATE_STATE(s_header_value_discard_ws_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_value_discard_lws); + break; + } + + /* FALLTHROUGH */ + + case s_header_value_start: + { + MARK(header_value); + + UPDATE_STATE(s_header_value); + parser->index = 0; + + c = LOWER(ch); + + switch (parser->header_state) { + case h_upgrade: + parser->flags |= F_UPGRADE; + parser->header_state = h_general; + break; + + case h_transfer_encoding: + /* looking for 'Transfer-Encoding: chunked' */ + if ('c' == c) { + parser->header_state = h_matching_transfer_encoding_chunked; + } else { + parser->header_state = h_general; + } + break; + + case h_content_length: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + if (parser->flags & F_CONTENTLENGTH) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + parser->flags |= F_CONTENTLENGTH; + parser->content_length = ch - '0'; + break; + + case h_connection: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + parser->header_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + parser->header_state = h_matching_connection_close; + } else if (c == 'u') { + parser->header_state = h_matching_connection_upgrade; + } else { + parser->header_state = h_matching_connection_token; + } + break; + + /* Multi-value `Connection` header */ + case h_matching_connection_token_start: + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_value: + { + const char* start = p; + enum header_states h_state = (enum header_states) parser->header_state; + for (; p != data + len; p++) { + ch = *p; + if (ch == CR) { + UPDATE_STATE(s_header_almost_done); + parser->header_state = h_state; + CALLBACK_DATA(header_value); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_almost_done); + COUNT_HEADER_SIZE(p - start); + parser->header_state = h_state; + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + + if (!lenient && !IS_HEADER_CHAR(ch)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + c = LOWER(ch); + + switch (h_state) { + case h_general: + { + const char* p_cr; + const char* p_lf; + size_t limit = data + len - p; + + limit = MIN(limit, HTTP_MAX_HEADER_SIZE); + + p_cr = (const char*) memchr(p, CR, limit); + p_lf = (const char*) memchr(p, LF, limit); + if (p_cr != NULL) { + if (p_lf != NULL && p_cr >= p_lf) + p = p_lf; + else + p = p_cr; + } else if (UNLIKELY(p_lf != NULL)) { + p = p_lf; + } else { + p = data + len; + } + --p; + + break; + } + + case h_connection: + case h_transfer_encoding: + assert(0 && "Shouldn't get here."); + break; + + case h_content_length: + { + uint64_t t; + + if (ch == ' ') break; + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + t = parser->content_length; + t *= 10; + t += ch - '0'; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + parser->content_length = t; + break; + } + + /* Transfer-Encoding: chunked */ + case h_matching_transfer_encoding_chunked: + parser->index++; + if (parser->index > sizeof(CHUNKED)-1 + || c != CHUNKED[parser->index]) { + h_state = h_general; + } else if (parser->index == sizeof(CHUNKED)-2) { + h_state = h_transfer_encoding_chunked; + } + break; + + case h_matching_connection_token_start: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + h_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + h_state = h_matching_connection_close; + } else if (c == 'u') { + h_state = h_matching_connection_upgrade; + } else if (STRICT_TOKEN(c)) { + h_state = h_matching_connection_token; + } else if (c == ' ' || c == '\t') { + /* Skip lws */ + } else { + h_state = h_general; + } + break; + + /* looking for 'Connection: keep-alive' */ + case h_matching_connection_keep_alive: + parser->index++; + if (parser->index > sizeof(KEEP_ALIVE)-1 + || c != KEEP_ALIVE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(KEEP_ALIVE)-2) { + h_state = h_connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case h_matching_connection_close: + parser->index++; + if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(CLOSE)-2) { + h_state = h_connection_close; + } + break; + + /* looking for 'Connection: upgrade' */ + case h_matching_connection_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE) - 1 || + c != UPGRADE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(UPGRADE)-2) { + h_state = h_connection_upgrade; + } + break; + + case h_matching_connection_token: + if (ch == ',') { + h_state = h_matching_connection_token_start; + parser->index = 0; + } + break; + + case h_transfer_encoding_chunked: + if (ch != ' ') h_state = h_general; + break; + + case h_connection_keep_alive: + case h_connection_close: + case h_connection_upgrade: + if (ch == ',') { + if (h_state == h_connection_keep_alive) { + parser->flags |= F_CONNECTION_KEEP_ALIVE; + } else if (h_state == h_connection_close) { + parser->flags |= F_CONNECTION_CLOSE; + } else if (h_state == h_connection_upgrade) { + parser->flags |= F_CONNECTION_UPGRADE; + } + h_state = h_matching_connection_token_start; + parser->index = 0; + } else if (ch != ' ') { + h_state = h_matching_connection_token; + } + break; + + default: + UPDATE_STATE(s_header_value); + h_state = h_general; + break; + } + } + parser->header_state = h_state; + + COUNT_HEADER_SIZE(p - start); + + if (p == data + len) + --p; + break; + } + + case s_header_almost_done: + { + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + UPDATE_STATE(s_header_value_lws); + break; + } + + case s_header_value_lws: + { + if (ch == ' ' || ch == '\t') { + UPDATE_STATE(s_header_value_start); + REEXECUTE(); + } + + /* finished the header */ + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + default: + break; + } + + UPDATE_STATE(s_header_field_start); + REEXECUTE(); + } + + case s_header_value_discard_ws_almost_done: + { + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_value_discard_lws); + break; + } + + case s_header_value_discard_lws: + { + if (ch == ' ' || ch == '\t') { + UPDATE_STATE(s_header_value_discard_ws); + break; + } else { + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + default: + break; + } + + /* header value was empty */ + MARK(header_value); + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + } + + case s_headers_almost_done: + { + STRICT_CHECK(ch != LF); + + if (parser->flags & F_TRAILING) { + /* End of a chunked request */ + UPDATE_STATE(s_message_done); + CALLBACK_NOTIFY_NOADVANCE(chunk_complete); + REEXECUTE(); + } + + /* Cannot use chunked encoding and a content-length header together + per the HTTP specification. */ + if ((parser->flags & F_CHUNKED) && + (parser->flags & F_CONTENTLENGTH)) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + UPDATE_STATE(s_headers_done); + + /* Set this here so that on_headers_complete() callbacks can see it */ + parser->upgrade = + ((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) == + (F_UPGRADE | F_CONNECTION_UPGRADE) || + parser->method == HTTP_CONNECT); + + /* Here we call the headers_complete callback. This is somewhat + * different than other callbacks because if the user returns 1, we + * will interpret that as saying that this message has no body. This + * is needed for the annoying case of recieving a response to a HEAD + * request. + * + * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so + * we have to simulate it by handling a change in errno below. + */ + if (settings->on_headers_complete) { + switch (settings->on_headers_complete(parser)) { + case 0: + break; + + case 2: + parser->upgrade = 1; + + case 1: + parser->flags |= F_SKIPBODY; + break; + + default: + SET_ERRNO(HPE_CB_headers_complete); + RETURN(p - data); /* Error */ + } + } + + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + RETURN(p - data); + } + + REEXECUTE(); + } + + case s_headers_done: + { + int hasBody; + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + hasBody = parser->flags & F_CHUNKED || + (parser->content_length > 0 && parser->content_length != ULLONG_MAX); + if (parser->upgrade && (parser->method == HTTP_CONNECT || + (parser->flags & F_SKIPBODY) || !hasBody)) { + /* Exit, the rest of the message is in a different protocol. */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + RETURN((p - data) + 1); + } + + if (parser->flags & F_SKIPBODY) { + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else if (parser->flags & F_CHUNKED) { + /* chunked encoding - ignore Content-Length header */ + UPDATE_STATE(s_chunk_size_start); + } else { + if (parser->content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else if (parser->content_length != ULLONG_MAX) { + /* Content-Length header given and non-zero */ + UPDATE_STATE(s_body_identity); + } else { + if (!http_message_needs_eof(parser)) { + /* Assume content-length 0 - read the next */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else { + /* Read body until EOF */ + UPDATE_STATE(s_body_identity_eof); + } + } + } + + break; + } + + case s_body_identity: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* The difference between advancing content_length and p is because + * the latter will automaticaly advance on the next loop iteration. + * Further, if content_length ends up at 0, we want to see the last + * byte again for our message complete callback. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + UPDATE_STATE(s_message_done); + + /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. + * + * The alternative to doing this is to wait for the next byte to + * trigger the data callback, just as in every other case. The + * problem with this is that this makes it difficult for the test + * harness to distinguish between complete-on-EOF and + * complete-on-length. It's not clear that this distinction is + * important for applications, but let's keep it for now. + */ + CALLBACK_DATA_(body, p - body_mark + 1, p - data); + REEXECUTE(); + } + + break; + } + + /* read until EOF */ + case s_body_identity_eof: + MARK(body); + p = data + len - 1; + + break; + + case s_message_done: + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + if (parser->upgrade) { + /* Exit, the rest of the message is in a different protocol. */ + RETURN((p - data) + 1); + } + break; + + case s_chunk_size_start: + { + assert(parser->nread == 1); + assert(parser->flags & F_CHUNKED); + + unhex_val = unhex[(unsigned char)ch]; + if (UNLIKELY(unhex_val == -1)) { + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + parser->content_length = unhex_val; + UPDATE_STATE(s_chunk_size); + break; + } + + case s_chunk_size: + { + uint64_t t; + + assert(parser->flags & F_CHUNKED); + + if (ch == CR) { + UPDATE_STATE(s_chunk_size_almost_done); + break; + } + + unhex_val = unhex[(unsigned char)ch]; + + if (unhex_val == -1) { + if (ch == ';' || ch == ' ') { + UPDATE_STATE(s_chunk_parameters); + break; + } + + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + t = parser->content_length; + t *= 16; + t += unhex_val; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = t; + break; + } + + case s_chunk_parameters: + { + assert(parser->flags & F_CHUNKED); + /* just ignore this shit. TODO check for overflow */ + if (ch == CR) { + UPDATE_STATE(s_chunk_size_almost_done); + break; + } + break; + } + + case s_chunk_size_almost_done: + { + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + if (parser->content_length == 0) { + parser->flags |= F_TRAILING; + UPDATE_STATE(s_header_field_start); + } else { + UPDATE_STATE(s_chunk_data); + } + CALLBACK_NOTIFY(chunk_header); + break; + } + + case s_chunk_data: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->flags & F_CHUNKED); + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* See the explanation in s_body_identity for why the content + * length and data pointers are managed this way. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + UPDATE_STATE(s_chunk_data_almost_done); + } + + break; + } + + case s_chunk_data_almost_done: + assert(parser->flags & F_CHUNKED); + assert(parser->content_length == 0); + STRICT_CHECK(ch != CR); + UPDATE_STATE(s_chunk_data_done); + CALLBACK_DATA(body); + break; + + case s_chunk_data_done: + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + parser->nread = 0; + UPDATE_STATE(s_chunk_size_start); + CALLBACK_NOTIFY(chunk_complete); + break; + + default: + assert(0 && "unhandled state"); + SET_ERRNO(HPE_INVALID_INTERNAL_STATE); + goto error; + } + } + + /* Run callbacks for any marks that we have leftover after we ran our of + * bytes. There should be at most one of these set, so it's OK to invoke + * them in series (unset marks will not result in callbacks). + * + * We use the NOADVANCE() variety of callbacks here because 'p' has already + * overflowed 'data' and this allows us to correct for the off-by-one that + * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' + * value that's in-bounds). + */ + + assert(((header_field_mark ? 1 : 0) + + (header_value_mark ? 1 : 0) + + (url_mark ? 1 : 0) + + (body_mark ? 1 : 0) + + (status_mark ? 1 : 0)) <= 1); + + CALLBACK_DATA_NOADVANCE(header_field); + CALLBACK_DATA_NOADVANCE(header_value); + CALLBACK_DATA_NOADVANCE(url); + CALLBACK_DATA_NOADVANCE(body); + CALLBACK_DATA_NOADVANCE(status); + + RETURN(len); + +error: + if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { + SET_ERRNO(HPE_UNKNOWN); + } + + RETURN(p - data); +} + + +/* Does the parser need to see an EOF to find the end of the message? */ +int +http_message_needs_eof (const http_parser *parser) +{ + if (parser->type == HTTP_REQUEST) { + return 0; + } + + /* See RFC 2616 section 4.4 */ + if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ + parser->status_code == 204 || /* No Content */ + parser->status_code == 304 || /* Not Modified */ + parser->flags & F_SKIPBODY) { /* response to a HEAD request */ + return 0; + } + + if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { + return 0; + } + + return 1; +} + + +int +http_should_keep_alive (const http_parser *parser) +{ + if (parser->http_major > 0 && parser->http_minor > 0) { + /* HTTP/1.1 */ + if (parser->flags & F_CONNECTION_CLOSE) { + return 0; + } + } else { + /* HTTP/1.0 or earlier */ + if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { + return 0; + } + } + + return !http_message_needs_eof(parser); +} + + +const char * +http_method_str (enum http_method m) +{ + return ELEM_AT(method_strings, m, ""); +} + + +void +http_parser_init (http_parser *parser, enum http_parser_type t) +{ + void *data = parser->data; /* preserve application data */ + memset(parser, 0, sizeof(*parser)); + parser->data = data; + parser->type = t; + parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); + parser->http_errno = HPE_OK; +} + +void +http_parser_settings_init(http_parser_settings *settings) +{ + memset(settings, 0, sizeof(*settings)); +} + +const char * +http_errno_name(enum http_errno err) { + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + return http_strerror_tab[err].name; +} + +const char * +http_errno_description(enum http_errno err) { + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + return http_strerror_tab[err].description; +} + +static enum http_host_state +http_parse_host_char(enum http_host_state s, const char ch) { + switch(s) { + case s_http_userinfo: + case s_http_userinfo_start: + if (ch == '@') { + return s_http_host_start; + } + + if (IS_USERINFO_CHAR(ch)) { + return s_http_userinfo; + } + break; + + case s_http_host_start: + if (ch == '[') { + return s_http_host_v6_start; + } + + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + break; + + case s_http_host: + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + /* FALLTHROUGH */ + case s_http_host_v6_end: + if (ch == ':') { + return s_http_host_port_start; + } + + break; + + case s_http_host_v6: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_start: + if (IS_HEX(ch) || ch == ':' || ch == '.') { + return s_http_host_v6; + } + + if (s == s_http_host_v6 && ch == '%') { + return s_http_host_v6_zone_start; + } + break; + + case s_http_host_v6_zone: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_zone_start: + /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */ + if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' || + ch == '~') { + return s_http_host_v6_zone; + } + break; + + case s_http_host_port: + case s_http_host_port_start: + if (IS_NUM(ch)) { + return s_http_host_port; + } + + break; + + default: + break; + } + return s_http_host_dead; +} + +static int +http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { + enum http_host_state s; + + const char *p; + size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; + + assert(u->field_set & (1 << UF_HOST)); + + u->field_data[UF_HOST].len = 0; + + s = found_at ? s_http_userinfo_start : s_http_host_start; + + for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { + enum http_host_state new_s = http_parse_host_char(s, *p); + + if (new_s == s_http_host_dead) { + return 1; + } + + switch(new_s) { + case s_http_host: + if (s != s_http_host) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6: + if (s != s_http_host_v6) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + u->field_data[UF_HOST].len++; + break; + + case s_http_host_port: + if (s != s_http_host_port) { + u->field_data[UF_PORT].off = p - buf; + u->field_data[UF_PORT].len = 0; + u->field_set |= (1 << UF_PORT); + } + u->field_data[UF_PORT].len++; + break; + + case s_http_userinfo: + if (s != s_http_userinfo) { + u->field_data[UF_USERINFO].off = p - buf ; + u->field_data[UF_USERINFO].len = 0; + u->field_set |= (1 << UF_USERINFO); + } + u->field_data[UF_USERINFO].len++; + break; + + default: + break; + } + s = new_s; + } + + /* Make sure we don't end somewhere unexpected */ + switch (s) { + case s_http_host_start: + case s_http_host_v6_start: + case s_http_host_v6: + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + case s_http_host_port_start: + case s_http_userinfo: + case s_http_userinfo_start: + return 1; + default: + break; + } + + return 0; +} + +void +http_parser_url_init(struct http_parser_url *u) { + memset(u, 0, sizeof(*u)); +} + +int +http_parser_parse_url(const char *buf, size_t buflen, int is_connect, + struct http_parser_url *u) +{ + enum state s; + const char *p; + enum http_parser_url_fields uf, old_uf; + int found_at = 0; + + u->port = u->field_set = 0; + s = is_connect ? s_req_server_start : s_req_spaces_before_url; + old_uf = UF_MAX; + + for (p = buf; p < buf + buflen; p++) { + s = parse_url_char(s, *p); + + /* Figure out the next field that we're operating on */ + switch (s) { + case s_dead: + return 1; + + /* Skip delimeters */ + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_query_string_start: + case s_req_fragment_start: + continue; + + case s_req_schema: + uf = UF_SCHEMA; + break; + + case s_req_server_with_at: + found_at = 1; + + /* FALLTROUGH */ + case s_req_server: + uf = UF_HOST; + break; + + case s_req_path: + uf = UF_PATH; + break; + + case s_req_query_string: + uf = UF_QUERY; + break; + + case s_req_fragment: + uf = UF_FRAGMENT; + break; + + default: + assert(!"Unexpected state"); + return 1; + } + + /* Nothing's changed; soldier on */ + if (uf == old_uf) { + u->field_data[uf].len++; + continue; + } + + u->field_data[uf].off = p - buf; + u->field_data[uf].len = 1; + + u->field_set |= (1 << uf); + old_uf = uf; + } + + /* host must be present if there is a schema */ + /* parsing http:///toto will fail */ + if ((u->field_set & (1 << UF_SCHEMA)) && + (u->field_set & (1 << UF_HOST)) == 0) { + return 1; + } + + if (u->field_set & (1 << UF_HOST)) { + if (http_parse_host(buf, u, found_at) != 0) { + return 1; + } + } + + /* CONNECT requests can only contain "hostname:port" */ + if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { + return 1; + } + + if (u->field_set & (1 << UF_PORT)) { + /* Don't bother with endp; we've already validated the string */ + unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); + + /* Ports have a max value of 2^16 */ + if (v > 0xffff) { + return 1; + } + + u->port = (uint16_t) v; + } + + return 0; +} + +void +http_parser_pause(http_parser *parser, int paused) { + /* Users should only be pausing/unpausing a parser that is not in an error + * state. In non-debug builds, there's not much that we can do about this + * other than ignore it. + */ + if (HTTP_PARSER_ERRNO(parser) == HPE_OK || + HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { + SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); + } else { + assert(0 && "Attempting to pause parser in error state"); + } +} + +int +http_body_is_final(const struct http_parser *parser) { + return parser->state == s_message_done; +} + +unsigned long +http_parser_version(void) { + return HTTP_PARSER_VERSION_MAJOR * 0x10000 | + HTTP_PARSER_VERSION_MINOR * 0x00100 | + HTTP_PARSER_VERSION_PATCH * 0x00001; +} diff --git a/ext/http-parser/http_parser.h b/ext/http-parser/http_parser.h new file mode 100644 index 0000000..45c72a0 --- /dev/null +++ b/ext/http-parser/http_parser.h @@ -0,0 +1,432 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef http_parser_h +#define http_parser_h +#ifdef __cplusplus +extern "C" { +#endif + +/* Also update SONAME in the Makefile whenever you change these. */ +#define HTTP_PARSER_VERSION_MAJOR 2 +#define HTTP_PARSER_VERSION_MINOR 7 +#define HTTP_PARSER_VERSION_PATCH 1 + +#include +#if defined(_WIN32) && !defined(__MINGW32__) && \ + (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__) +#include +#include +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif + +/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run + * faster + */ +#ifndef HTTP_PARSER_STRICT +# define HTTP_PARSER_STRICT 1 +#endif + +/* Maximium header size allowed. If the macro is not defined + * before including this header then the default is used. To + * change the maximum header size, define the macro in the build + * environment (e.g. -DHTTP_MAX_HEADER_SIZE=). To remove + * the effective limit on the size of the header, define the macro + * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff) + */ +#ifndef HTTP_MAX_HEADER_SIZE +# define HTTP_MAX_HEADER_SIZE (80*1024) +#endif + +typedef struct http_parser http_parser; +typedef struct http_parser_settings http_parser_settings; + + +/* Callbacks should return non-zero to indicate an error. The parser will + * then halt execution. + * + * The one exception is on_headers_complete. In a HTTP_RESPONSE parser + * returning '1' from on_headers_complete will tell the parser that it + * should not expect a body. This is used when receiving a response to a + * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: + * chunked' headers that indicate the presence of a body. + * + * Returning `2` from on_headers_complete will tell parser that it should not + * expect neither a body nor any futher responses on this connection. This is + * useful for handling responses to a CONNECT request which may not contain + * `Upgrade` or `Connection: upgrade` headers. + * + * http_data_cb does not return data chunks. It will be called arbitrarily + * many times for each string. E.G. you might get 10 callbacks for "on_url" + * each providing just a few characters more data. + */ +typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); +typedef int (*http_cb) (http_parser*); + + +/* Status Codes */ +#define HTTP_STATUS_MAP(XX) \ + XX(100, CONTINUE, Continue) \ + XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \ + XX(102, PROCESSING, Processing) \ + XX(200, OK, OK) \ + XX(201, CREATED, Created) \ + XX(202, ACCEPTED, Accepted) \ + XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \ + XX(204, NO_CONTENT, No Content) \ + XX(205, RESET_CONTENT, Reset Content) \ + XX(206, PARTIAL_CONTENT, Partial Content) \ + XX(207, MULTI_STATUS, Multi-Status) \ + XX(208, ALREADY_REPORTED, Already Reported) \ + XX(226, IM_USED, IM Used) \ + XX(300, MULTIPLE_CHOICES, Multiple Choices) \ + XX(301, MOVED_PERMANENTLY, Moved Permanently) \ + XX(302, FOUND, Found) \ + XX(303, SEE_OTHER, See Other) \ + XX(304, NOT_MODIFIED, Not Modified) \ + XX(305, USE_PROXY, Use Proxy) \ + XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \ + XX(308, PERMANENT_REDIRECT, Permanent Redirect) \ + XX(400, BAD_REQUEST, Bad Request) \ + XX(401, UNAUTHORIZED, Unauthorized) \ + XX(402, PAYMENT_REQUIRED, Payment Required) \ + XX(403, FORBIDDEN, Forbidden) \ + XX(404, NOT_FOUND, Not Found) \ + XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \ + XX(406, NOT_ACCEPTABLE, Not Acceptable) \ + XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \ + XX(408, REQUEST_TIMEOUT, Request Timeout) \ + XX(409, CONFLICT, Conflict) \ + XX(410, GONE, Gone) \ + XX(411, LENGTH_REQUIRED, Length Required) \ + XX(412, PRECONDITION_FAILED, Precondition Failed) \ + XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \ + XX(414, URI_TOO_LONG, URI Too Long) \ + XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \ + XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \ + XX(417, EXPECTATION_FAILED, Expectation Failed) \ + XX(421, MISDIRECTED_REQUEST, Misdirected Request) \ + XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \ + XX(423, LOCKED, Locked) \ + XX(424, FAILED_DEPENDENCY, Failed Dependency) \ + XX(426, UPGRADE_REQUIRED, Upgrade Required) \ + XX(428, PRECONDITION_REQUIRED, Precondition Required) \ + XX(429, TOO_MANY_REQUESTS, Too Many Requests) \ + XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \ + XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \ + XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \ + XX(501, NOT_IMPLEMENTED, Not Implemented) \ + XX(502, BAD_GATEWAY, Bad Gateway) \ + XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \ + XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \ + XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \ + XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \ + XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ + XX(508, LOOP_DETECTED, Loop Detected) \ + XX(510, NOT_EXTENDED, Not Extended) \ + XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \ + +enum http_status + { +#define XX(num, name, string) HTTP_STATUS_##name = num, + HTTP_STATUS_MAP(XX) +#undef XX + }; + + +/* Request Methods */ +#define HTTP_METHOD_MAP(XX) \ + XX(0, DELETE, DELETE) \ + XX(1, GET, GET) \ + XX(2, HEAD, HEAD) \ + XX(3, POST, POST) \ + XX(4, PUT, PUT) \ + /* pathological */ \ + XX(5, CONNECT, CONNECT) \ + XX(6, OPTIONS, OPTIONS) \ + XX(7, TRACE, TRACE) \ + /* WebDAV */ \ + XX(8, COPY, COPY) \ + XX(9, LOCK, LOCK) \ + XX(10, MKCOL, MKCOL) \ + XX(11, MOVE, MOVE) \ + XX(12, PROPFIND, PROPFIND) \ + XX(13, PROPPATCH, PROPPATCH) \ + XX(14, SEARCH, SEARCH) \ + XX(15, UNLOCK, UNLOCK) \ + XX(16, BIND, BIND) \ + XX(17, REBIND, REBIND) \ + XX(18, UNBIND, UNBIND) \ + XX(19, ACL, ACL) \ + /* subversion */ \ + XX(20, REPORT, REPORT) \ + XX(21, MKACTIVITY, MKACTIVITY) \ + XX(22, CHECKOUT, CHECKOUT) \ + XX(23, MERGE, MERGE) \ + /* upnp */ \ + XX(24, MSEARCH, M-SEARCH) \ + XX(25, NOTIFY, NOTIFY) \ + XX(26, SUBSCRIBE, SUBSCRIBE) \ + XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ + /* RFC-5789 */ \ + XX(28, PATCH, PATCH) \ + XX(29, PURGE, PURGE) \ + /* CalDAV */ \ + XX(30, MKCALENDAR, MKCALENDAR) \ + /* RFC-2068, section 19.6.1.2 */ \ + XX(31, LINK, LINK) \ + XX(32, UNLINK, UNLINK) \ + +enum http_method + { +#define XX(num, name, string) HTTP_##name = num, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; + + +/* Flag values for http_parser.flags field */ +enum flags + { F_CHUNKED = 1 << 0 + , F_CONNECTION_KEEP_ALIVE = 1 << 1 + , F_CONNECTION_CLOSE = 1 << 2 + , F_CONNECTION_UPGRADE = 1 << 3 + , F_TRAILING = 1 << 4 + , F_UPGRADE = 1 << 5 + , F_SKIPBODY = 1 << 6 + , F_CONTENTLENGTH = 1 << 7 + }; + + +/* Map for errno-related constants + * + * The provided argument should be a macro that takes 2 arguments. + */ +#define HTTP_ERRNO_MAP(XX) \ + /* No error */ \ + XX(OK, "success") \ + \ + /* Callback-related errors */ \ + XX(CB_message_begin, "the on_message_begin callback failed") \ + XX(CB_url, "the on_url callback failed") \ + XX(CB_header_field, "the on_header_field callback failed") \ + XX(CB_header_value, "the on_header_value callback failed") \ + XX(CB_headers_complete, "the on_headers_complete callback failed") \ + XX(CB_body, "the on_body callback failed") \ + XX(CB_message_complete, "the on_message_complete callback failed") \ + XX(CB_status, "the on_status callback failed") \ + XX(CB_chunk_header, "the on_chunk_header callback failed") \ + XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ + \ + /* Parsing-related errors */ \ + XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ + XX(HEADER_OVERFLOW, \ + "too many header bytes seen; overflow detected") \ + XX(CLOSED_CONNECTION, \ + "data received after completed connection: close message") \ + XX(INVALID_VERSION, "invalid HTTP version") \ + XX(INVALID_STATUS, "invalid HTTP status code") \ + XX(INVALID_METHOD, "invalid HTTP method") \ + XX(INVALID_URL, "invalid URL") \ + XX(INVALID_HOST, "invalid host") \ + XX(INVALID_PORT, "invalid port") \ + XX(INVALID_PATH, "invalid path") \ + XX(INVALID_QUERY_STRING, "invalid query string") \ + XX(INVALID_FRAGMENT, "invalid fragment") \ + XX(LF_EXPECTED, "LF character expected") \ + XX(INVALID_HEADER_TOKEN, "invalid character in header") \ + XX(INVALID_CONTENT_LENGTH, \ + "invalid character in content-length header") \ + XX(UNEXPECTED_CONTENT_LENGTH, \ + "unexpected content-length header") \ + XX(INVALID_CHUNK_SIZE, \ + "invalid character in chunk size header") \ + XX(INVALID_CONSTANT, "invalid constant string") \ + XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ + XX(STRICT, "strict mode assertion failed") \ + XX(PAUSED, "parser is paused") \ + XX(UNKNOWN, "an unknown error occurred") + + +/* Define HPE_* values for each errno value above */ +#define HTTP_ERRNO_GEN(n, s) HPE_##n, +enum http_errno { + HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) +}; +#undef HTTP_ERRNO_GEN + + +/* Get an http_errno value from an http_parser */ +#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) + + +struct http_parser { + /** PRIVATE **/ + unsigned int type : 2; /* enum http_parser_type */ + unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */ + unsigned int state : 7; /* enum state from http_parser.c */ + unsigned int header_state : 7; /* enum header_state from http_parser.c */ + unsigned int index : 7; /* index into current matcher */ + unsigned int lenient_http_headers : 1; + + uint32_t nread; /* # bytes read in various scenarios */ + uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ + + /** READ-ONLY **/ + unsigned short http_major; + unsigned short http_minor; + unsigned int status_code : 16; /* responses only */ + unsigned int method : 8; /* requests only */ + unsigned int http_errno : 7; + + /* 1 = Upgrade header was present and the parser has exited because of that. + * 0 = No upgrade header present. + * Should be checked when http_parser_execute() returns in addition to + * error checking. + */ + unsigned int upgrade : 1; + + /** PUBLIC **/ + void *data; /* A pointer to get hook to the "connection" or "socket" object */ +}; + + +struct http_parser_settings { + http_cb on_message_begin; + http_data_cb on_url; + http_data_cb on_status; + http_data_cb on_header_field; + http_data_cb on_header_value; + http_cb on_headers_complete; + http_data_cb on_body; + http_cb on_message_complete; + /* When on_chunk_header is called, the current chunk length is stored + * in parser->content_length. + */ + http_cb on_chunk_header; + http_cb on_chunk_complete; +}; + + +enum http_parser_url_fields + { UF_SCHEMA = 0 + , UF_HOST = 1 + , UF_PORT = 2 + , UF_PATH = 3 + , UF_QUERY = 4 + , UF_FRAGMENT = 5 + , UF_USERINFO = 6 + , UF_MAX = 7 + }; + + +/* Result structure for http_parser_parse_url(). + * + * Callers should index into field_data[] with UF_* values iff field_set + * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and + * because we probably have padding left over), we convert any port to + * a uint16_t. + */ +struct http_parser_url { + uint16_t field_set; /* Bitmask of (1 << UF_*) values */ + uint16_t port; /* Converted UF_PORT string */ + + struct { + uint16_t off; /* Offset into buffer in which field starts */ + uint16_t len; /* Length of run in buffer */ + } field_data[UF_MAX]; +}; + + +/* Returns the library version. Bits 16-23 contain the major version number, + * bits 8-15 the minor version number and bits 0-7 the patch level. + * Usage example: + * + * unsigned long version = http_parser_version(); + * unsigned major = (version >> 16) & 255; + * unsigned minor = (version >> 8) & 255; + * unsigned patch = version & 255; + * printf("http_parser v%u.%u.%u\n", major, minor, patch); + */ +unsigned long http_parser_version(void); + +void http_parser_init(http_parser *parser, enum http_parser_type type); + + +/* Initialize http_parser_settings members to 0 + */ +void http_parser_settings_init(http_parser_settings *settings); + + +/* Executes the parser. Returns number of parsed bytes. Sets + * `parser->http_errno` on error. */ +size_t http_parser_execute(http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len); + + +/* If http_should_keep_alive() in the on_headers_complete or + * on_message_complete callback returns 0, then this should be + * the last message on the connection. + * If you are the server, respond with the "Connection: close" header. + * If you are the client, close the connection. + */ +int http_should_keep_alive(const http_parser *parser); + +/* Returns a string version of the HTTP method. */ +const char *http_method_str(enum http_method m); + +/* Return a string name of the given error */ +const char *http_errno_name(enum http_errno err); + +/* Return a string description of the given error */ +const char *http_errno_description(enum http_errno err); + +/* Initialize all http_parser_url members to 0 */ +void http_parser_url_init(struct http_parser_url *u); + +/* Parse a URL; return nonzero on failure */ +int http_parser_parse_url(const char *buf, size_t buflen, + int is_connect, + struct http_parser_url *u); + +/* Pause or un-pause the parser; a nonzero value pauses */ +void http_parser_pause(http_parser *parser, int paused); + +/* Checks if this is the final chunk of the body. */ +int http_body_is_final(const http_parser *parser); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ext/inja/LICENSE b/ext/inja/LICENSE new file mode 100644 index 0000000..9e06bea --- /dev/null +++ b/ext/inja/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018-2021 Berscheid + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ext/inja/README.md b/ext/inja/README.md new file mode 100644 index 0000000..9d66a2c --- /dev/null +++ b/ext/inja/README.md @@ -0,0 +1,391 @@ +[

    ](https://github.com/pantor/inja/releases) + +

    + + CI Status + + + + Documentation Status + + + + + + + + Github Releases + + + + Github Issues + + + + GitHub License + +

    + +Inja is a template engine for modern C++, loosely inspired by [jinja](http://jinja.pocoo.org) for python. It has an easy and yet powerful template syntax with all variables, loops, conditions, includes, callbacks, and comments you need, nested and combined as you like. Inja uses the wonderful [json](https://github.com/nlohmann/json) library by nlohmann for data input. Most importantly, inja needs only two header files, which is (nearly) as trivial as integration in C++ can get. Of course, everything is tested on all relevant compilers. Here is what it looks like: + +```.cpp +json data; +data["name"] = "world"; + +inja::render("Hello {{ name }}!", data); // Returns "Hello world!" +``` + +## Integration + +Inja is a headers only library, which can be downloaded from the [releases](https://github.com/pantor/inja/releases) or directly from the `include/` or `single_include/` folder. Inja uses `nlohmann/json.hpp` (>= v3.8.0) as its single dependency, so make sure it can be included from `inja.hpp`. json can be downloaded [here](https://github.com/nlohmann/json/releases). Then integration is as easy as: + +```.cpp +#include + +// Just for convenience +using namespace inja; +``` + +If you are using the [Meson Build System](http://mesonbuild.com), then you can wrap this repository as a subproject. + +If you are using [Conan](https://conan.io) to manage your dependencies, have a look at [this repository](https://github.com/DEGoodmanWilson/conan-inja). Please file issues [here](https://github.com/DEGoodmanWilson/conan-inja/issues) if you experience problems with the packages. + +You can also integrate inja in your project using [Hunter](https://github.com/cpp-pm/hunter), a package manager for C++. + +If you are using [vcpkg](https://github.com/Microsoft/vcpkg) on your project for external dependencies, then you can use the [inja package](https://github.com/Microsoft/vcpkg/tree/master/ports/inja). Please see the vcpkg project for any issues regarding the packaging. + +If you are using [cget](https://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install pantor/inja`. A specific version can be installed with `cget install pantor/inja@v2.1.0`. + +On macOS, you can install inja via [Homebrew](https://formulae.brew.sh/formula/inja#default) and `brew install inja`. + +If you are using [conda](https://docs.conda.io/en/latest/), you can install the latest version from [conda-forge](https://anaconda.org/conda-forge/inja) with `conda install -c conda-forge inja`. + +## Tutorial + +This tutorial will give you an idea how to use inja. It will explain the most important concepts and give practical advices using examples and executable code. Beside this tutorial, you may check out the [documentation](https://pantor.github.io/inja). + +### Template Rendering + +The basic template rendering takes a template as a `std::string` and a `json` object for all data. It returns the rendered template as an `std::string`. + +```.cpp +json data; +data["name"] = "world"; + +render("Hello {{ name }}!", data); // Returns std::string "Hello world!" +render_to(std::cout, "Hello {{ name }}!", data); // Writes "Hello world!" to stream +``` + +For more advanced usage, an environment is recommended. +```.cpp +Environment env; + +// Render a string with json data +std::string result = env.render("Hello {{ name }}!", data); // "Hello world!" + +// Or directly read a template file +Template temp = env.parse_template("./templates/greeting.txt"); +std::string result = env.render(temp, data); // "Hello world!" + +data["name"] = "Inja"; +std::string result = env.render(temp, data); // "Hello Inja!" + +// Or read the template file (and/or the json file) directly from the environment +result = env.render_file("./templates/greeting.txt", data); +result = env.render_file_with_json_file("./templates/greeting.txt", "./data.json"); + +// Or write a rendered template file +env.write(temp, data, "./result.txt"); +env.write_with_json_file("./templates/greeting.txt", "./data.json", "./result.txt"); +``` + +The environment class can be configured to your needs. +```.cpp +// With default settings +Environment env_default; + +// With global path to template files and where files will be saved +Environment env_1 {"../path/templates/"}; + +// With separate input and output path +Environment env_2 {"../path/templates/", "../path/results/"}; + +// With other opening and closing strings (here the defaults) +env.set_expression("{{", "}}"); // Expressions +env.set_comment("{#", "#}"); // Comments +env.set_statement("{%", "%}"); // Statements {% %} for many things, see below +env.set_line_statement("##"); // Line statements ## (just an opener) +``` + +### Variables + +Variables are rendered within the `{{ ... }}` expressions. +```.cpp +json data; +data["neighbour"] = "Peter"; +data["guests"] = {"Jeff", "Tom", "Patrick"}; +data["time"]["start"] = 16; +data["time"]["end"] = 22; + +// Indexing in array +render("{{ guests.1 }}", data); // "Tom" + +// Objects +render("{{ time.start }} to {{ time.end + 1 }}pm", data); // "16 to 23pm" +``` +If no variable is found, valid JSON is printed directly, otherwise an `inja::RenderError` is thrown. + +### Statements + +Statements can be written either with the `{% ... %}` syntax or the `##` syntax for entire lines. Note that `##` needs to start the line without indentation. The most important statements are loops, conditions and file includes. All statements can be nested. + +#### Loops + +```.cpp +// Combining loops and line statements +render(R"(Guest List: +## for guest in guests + {{ loop.index1 }}: {{ guest }} +## endfor )", data) + +/* Guest List: + 1: Jeff + 2: Tom + 3: Patrick */ +``` +In a loop, the special variables `loop.index (number)`, `loop.index1 (number)`, `loop.is_first (boolean)` and `loop.is_last (boolean)` are defined. In nested loops, the parent loop variables are available e.g. via `loop.parent.index`. You can also iterate over objects like `{% for key, value in time %}`. + +#### Conditions + +Conditions support the typical if, else if and else statements. Following conditions are for example possible: +```.cpp +// Standard comparisons with a variable +render("{% if time.hour >= 20 %}Serve{% else if time.hour >= 18 %}Make{% endif %} dinner.", data); // Serve dinner. + +// Variable in list +render("{% if neighbour in guests %}Turn up the music!{% endif %}", data); // Turn up the music! + +// Logical operations +render("{% if guest_count < (3+2) and all_tired %}Sleepy...{% else %}Keep going...{% endif %}", data); // Sleepy... + +// Negations +render("{% if not guest_count %}The End{% endif %}", data); // The End +``` + +#### Includes + +You can either include other in-memory templates or from the file system. +```.cpp +// To include in-memory templates, add them to the environment first +inja::Template content_template = env.parse("Hello {{ neighbour }}!"); +env.include_template("content", content_template); +env.render("Content: {% include \"content\" %}", data); // "Content: Hello Peter!" + +// Other template files are included relative from the current file location +render("{% include \"footer.html\" %}", data); +``` +If a corresponding template could not be found in the file system, the *include callback* is called: +```.cpp +// The callback takes the current path and the wanted include name and returns a template +env.set_include_callback([&env](const std::string& path, const std::string& template_name) { + return env.parse("Hello {{ neighbour }} from " + template_name); +}); + +// You can disable to search for templates in the file system via +env.set_search_included_templates_in_files(false); +``` + +Inja will throw an `inja::RenderError` if an included file is not found and no callback is specified. To disable this error, you can call `env.set_throw_at_missing_includes(false)`. + +#### Assignments + +Variables can also be defined within the template using the set statment. +```.cpp +render("{% set new_hour=23 %}{{ new_hour }}pm", data); // "23pm" +render("{% set time.start=18 %}{{ time.start }}pm", data); // using json pointers +``` + +Assignments only set the value within the rendering context; they do not modify the json object passed into the `render` call. + +### Functions + +A few functions are implemented within the inja template syntax. They can be called with +```.cpp +// Upper and lower function, for string cases +render("Hello {{ upper(neighbour) }}!", data); // "Hello PETER!" +render("Hello {{ lower(neighbour) }}!", data); // "Hello peter!" + +// Range function, useful for loops +render("{% for i in range(4) %}{{ loop.index1 }}{% endfor %}", data); // "1234" +render("{% for i in range(3) %}{{ at(guests, i) }} {% endfor %}", data); // "Jeff Tom Patrick " + +// Length function (please don't combine with range, use list directly...) +render("I count {{ length(guests) }} guests.", data); // "I count 3 guests." + +// Get first and last element in a list +render("{{ first(guests) }} was first.", data); // "Jeff was first." +render("{{ last(guests) }} was last.", data); // "Patir was last." + +// Sort a list +render("{{ sort([3,2,1]) }}", data); // "[1,2,3]" +render("{{ sort(guests) }}", data); // "[\"Jeff\", \"Patrick\", \"Tom\"]" + +// Join a list with a separator +render("{{ join([1,2,3], \" + \") }}", data); // "1 + 2 + 3" +render("{{ join(guests, \", \") }}", data); // "Jeff, Patrick, Tom" + +// Round numbers to a given precision +render("{{ round(3.1415, 0) }}", data); // 3 +render("{{ round(3.1415, 3) }}", data); // 3.142 + +// Check if a value is odd, even or divisible by a number +render("{{ odd(42) }}", data); // false +render("{{ even(42) }}", data); // true +render("{{ divisibleBy(42, 7) }}", data); // true + +// Maximum and minimum values from a list +render("{{ max([1, 2, 3]) }}", data); // 3 +render("{{ min([-2.4, -1.2, 4.5]) }}", data); // -2.4 + +// Convert strings to numbers +render("{{ int(\"2\") == 2 }}", data); // true +render("{{ float(\"1.8\") > 2 }}", data); // false + +// Set default values if variables are not defined +render("Hello {{ default(neighbour, \"my friend\") }}!", data); // "Hello Peter!" +render("Hello {{ default(colleague, \"my friend\") }}!", data); // "Hello my friend!" + +// Access an objects value dynamically +render("{{ at(time, \"start\") }} to {{ time.end }}", data); // "16 to 22" + +// Check if a key exists in an object +render("{{ exists(\"guests\") }}", data); // "true" +render("{{ exists(\"city\") }}", data); // "false" +render("{{ existsIn(time, \"start\") }}", data); // "true" +render("{{ existsIn(time, neighbour) }}", data); // "false" + +// Check if a key is a specific type +render("{{ isString(neighbour) }}", data); // "true" +render("{{ isArray(guests) }}", data); // "true" +// Implemented type checks: isArray, isBoolean, isFloat, isInteger, isNumber, isObject, isString, +``` + +### Callbacks + +You can create your own and more complex functions with callbacks. These are implemented with `std::function`, so you can for example use C++ lambdas. Inja `Arguments` are a vector of json pointers. +```.cpp +Environment env; + +/* + * Callbacks are defined by its: + * - name, + * - (optional) number of arguments, + * - callback function. + */ +env.add_callback("double", 1, [](Arguments& args) { + int number = args.at(0)->get(); // Adapt the index and type of the argument + return 2 * number; +}); + +// You can then use a callback like a regular function +env.render("{{ double(16) }}", data); // "32" + +// Inja falls back to variadic callbacks if the number of expected arguments is omitted. +env.add_callback("argmax", [](Arguments& args) { + auto result = std::max_element(args.begin(), args.end(), [](const json* a, const json* b) { return *a < *b;}); + return std::distance(args.begin(), result); +}); +env.render("{{ argmax(4, 2, 6) }}", data); // "2" +env.render("{{ argmax(0, 2, 6, 8, 3) }}", data); // "3" + +// A callback without argument can be used like a dynamic variable: +std::string greet = "Hello"; +env.add_callback("double-greetings", 0, [greet](Arguments args) { + return greet + " " + greet + "!"; +}); +env.render("{{ double-greetings }}", data); // "Hello Hello!" +``` +You can also add a void callback without return variable, e.g. for debugging: +```.cpp +env.add_void_callback("log", 1, [greet](Arguments args) { + std::cout << "logging: " << args[0] << std::endl; +}); +env.render("{{ log(neighbour) }}", data); // Prints nothing to result, only to cout... +``` + +### Template Inheritance + +Template inheritance allows you to build a base *skeleton* template that contains all the common elements and defines blocks that child templates can override. Lets show an example: The base template +```.html + + + + {% block head %} + + {% block title %}{% endblock %} - My Webpage + {% endblock %} + + +
    {% block content %}{% endblock %}
    + + +``` +contains three `blocks` that child templates can fill in. The child template +```.html +{% extends "base.html" %} +{% block title %}Index{% endblock %} +{% block head %} + {{ super() }} + +{% endblock %} +{% block content %} +

    Index

    +

    + Welcome to my blog! +

    +{% endblock %} +``` +calls a parent template with the `extends` keyword; it should be the first element in the template. It is possible to render the contents of the parent block by calling `super()`. In the case of multiple levels of `{% extends %}`, super references may be called with an argument (e.g. `super(2)`) to skip levels in the inheritance tree. + +### Whitespace Control + +In the default configuration, no whitespace is removed while rendering the file. To support a more readable template style, you can configure the environment to control whitespaces before and after a statement automatically. While enabling `set_trim_blocks` removes the first newline after a statement, `set_lstrip_blocks` strips tabs and spaces from the beginning of a line to the start of a block. + +```.cpp +Environment env; +env.set_trim_blocks(true); +env.set_lstrip_blocks(true); +``` + +With both `trim_blocks` and `lstrip_blocks` enabled, you can put statements on their own lines. Furthermore, you can also strip whitespaces for both statements and expressions by hand. If you add a minus sign (`-`) to the start or end, the whitespaces before or after that block will be removed: + +```.cpp +render("Hello {{- name -}} !", data); // "Hello Inja!" +render("{% if neighbour in guests -%} I was there{% endif -%} !", data); // Renders without any whitespaces +``` + +Stripping behind a statement or expression also removes any newlines. + +### Comments + +Comments can be written with the `{# ... #}` syntax. +```.cpp +render("Hello{# Todo #}!", data); // "Hello!" +``` + +### Exceptions + +Inja uses exceptions to handle ill-formed template input. However, exceptions can be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `INJA_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. + + +## Supported compilers + +Inja uses the `string_view` feature of the C++17 STL. Currently, the following compilers are tested: + +- GCC 7 - 11 (and possibly later) +- Clang 5 - 12 (and possibly later) +- Microsoft Visual C++ 2017 15.0 - 2022 (and possibly later) + +A list of supported compiler / os versions can be found in the [CI definition](https://github.com/pantor/inja/blob/master/.github/workflows/ci.yml). diff --git a/ext/inja/inja.hpp b/ext/inja/inja.hpp new file mode 100644 index 0000000..5b46974 --- /dev/null +++ b/ext/inja/inja.hpp @@ -0,0 +1,2949 @@ +/* + ___ _ Version 3.3 + |_ _|_ __ (_) __ _ https://github.com/pantor/inja + | || '_ \ | |/ _` | Licensed under the MIT License . + | || | | || | (_| | + |___|_| |_|/ |\__,_| Copyright (c) 2018-2021 Lars Berscheid + |__/ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef INCLUDE_INJA_INJA_HPP_ +#define INCLUDE_INJA_INJA_HPP_ + +#include + +namespace inja { +#ifndef INJA_DATA_TYPE +using json = nlohmann::json; +#else +using json = INJA_DATA_TYPE; +#endif +} // namespace inja + +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(INJA_NOEXCEPTION) +#ifndef INJA_THROW +#define INJA_THROW(exception) throw exception +#endif +#else +#include +#ifndef INJA_THROW +#define INJA_THROW(exception) \ + std::abort(); \ + std::ignore = exception +#endif +#ifndef INJA_NOEXCEPTION +#define INJA_NOEXCEPTION +#endif +#endif + +// #include "environment.hpp" +#ifndef INCLUDE_INJA_ENVIRONMENT_HPP_ +#define INCLUDE_INJA_ENVIRONMENT_HPP_ + +#include +#include +#include +#include +#include +#include + +// #include "config.hpp" +#ifndef INCLUDE_INJA_CONFIG_HPP_ +#define INCLUDE_INJA_CONFIG_HPP_ + +#include +#include + +// #include "template.hpp" +#ifndef INCLUDE_INJA_TEMPLATE_HPP_ +#define INCLUDE_INJA_TEMPLATE_HPP_ + +#include +#include +#include +#include + +// #include "node.hpp" +#ifndef INCLUDE_INJA_NODE_HPP_ +#define INCLUDE_INJA_NODE_HPP_ + +#include +#include +#include + +// #include "function_storage.hpp" +#ifndef INCLUDE_INJA_FUNCTION_STORAGE_HPP_ +#define INCLUDE_INJA_FUNCTION_STORAGE_HPP_ + +#include +#include + +namespace inja { + +using Arguments = std::vector; +using CallbackFunction = std::function; +using VoidCallbackFunction = std::function; + +/*! + * \brief Class for builtin functions and user-defined callbacks. + */ +class FunctionStorage { +public: + enum class Operation { + Not, + And, + Or, + In, + Equal, + NotEqual, + Greater, + GreaterEqual, + Less, + LessEqual, + Add, + Subtract, + Multiplication, + Division, + Power, + Modulo, + AtId, + At, + Default, + DivisibleBy, + Even, + Exists, + ExistsInObject, + First, + Float, + Int, + IsArray, + IsBoolean, + IsFloat, + IsInteger, + IsNumber, + IsObject, + IsString, + Last, + Length, + Lower, + Max, + Min, + Odd, + Range, + Round, + Sort, + Upper, + Super, + Join, + Callback, + ParenLeft, + ParenRight, + None, + }; + + struct FunctionData { + explicit FunctionData(const Operation& op, const CallbackFunction& cb = CallbackFunction {}): operation(op), callback(cb) {} + const Operation operation; + const CallbackFunction callback; + }; + +private: + const int VARIADIC {-1}; + + std::map, FunctionData> function_storage = { + {std::make_pair("at", 2), FunctionData {Operation::At}}, + {std::make_pair("default", 2), FunctionData {Operation::Default}}, + {std::make_pair("divisibleBy", 2), FunctionData {Operation::DivisibleBy}}, + {std::make_pair("even", 1), FunctionData {Operation::Even}}, + {std::make_pair("exists", 1), FunctionData {Operation::Exists}}, + {std::make_pair("existsIn", 2), FunctionData {Operation::ExistsInObject}}, + {std::make_pair("first", 1), FunctionData {Operation::First}}, + {std::make_pair("float", 1), FunctionData {Operation::Float}}, + {std::make_pair("int", 1), FunctionData {Operation::Int}}, + {std::make_pair("isArray", 1), FunctionData {Operation::IsArray}}, + {std::make_pair("isBoolean", 1), FunctionData {Operation::IsBoolean}}, + {std::make_pair("isFloat", 1), FunctionData {Operation::IsFloat}}, + {std::make_pair("isInteger", 1), FunctionData {Operation::IsInteger}}, + {std::make_pair("isNumber", 1), FunctionData {Operation::IsNumber}}, + {std::make_pair("isObject", 1), FunctionData {Operation::IsObject}}, + {std::make_pair("isString", 1), FunctionData {Operation::IsString}}, + {std::make_pair("last", 1), FunctionData {Operation::Last}}, + {std::make_pair("length", 1), FunctionData {Operation::Length}}, + {std::make_pair("lower", 1), FunctionData {Operation::Lower}}, + {std::make_pair("max", 1), FunctionData {Operation::Max}}, + {std::make_pair("min", 1), FunctionData {Operation::Min}}, + {std::make_pair("odd", 1), FunctionData {Operation::Odd}}, + {std::make_pair("range", 1), FunctionData {Operation::Range}}, + {std::make_pair("round", 2), FunctionData {Operation::Round}}, + {std::make_pair("sort", 1), FunctionData {Operation::Sort}}, + {std::make_pair("upper", 1), FunctionData {Operation::Upper}}, + {std::make_pair("super", 0), FunctionData {Operation::Super}}, + {std::make_pair("super", 1), FunctionData {Operation::Super}}, + {std::make_pair("join", 2), FunctionData {Operation::Join}}, + }; + +public: + void add_builtin(std::string_view name, int num_args, Operation op) { + function_storage.emplace(std::make_pair(static_cast(name), num_args), FunctionData {op}); + } + + void add_callback(std::string_view name, int num_args, const CallbackFunction& callback) { + function_storage.emplace(std::make_pair(static_cast(name), num_args), FunctionData {Operation::Callback, callback}); + } + + FunctionData find_function(std::string_view name, int num_args) const { + auto it = function_storage.find(std::make_pair(static_cast(name), num_args)); + if (it != function_storage.end()) { + return it->second; + + // Find variadic function + } else if (num_args > 0) { + it = function_storage.find(std::make_pair(static_cast(name), VARIADIC)); + if (it != function_storage.end()) { + return it->second; + } + } + + return FunctionData {Operation::None}; + } +}; + +} // namespace inja + +#endif // INCLUDE_INJA_FUNCTION_STORAGE_HPP_ + +// #include "utils.hpp" +#ifndef INCLUDE_INJA_UTILS_HPP_ +#define INCLUDE_INJA_UTILS_HPP_ + +#include +#include +#include +#include +#include + +// #include "exceptions.hpp" +#ifndef INCLUDE_INJA_EXCEPTIONS_HPP_ +#define INCLUDE_INJA_EXCEPTIONS_HPP_ + +#include +#include + +namespace inja { + +struct SourceLocation { + size_t line; + size_t column; +}; + +struct InjaError : public std::runtime_error { + const std::string type; + const std::string message; + + const SourceLocation location; + + explicit InjaError(const std::string& type, const std::string& message) + : std::runtime_error("[inja.exception." + type + "] " + message), type(type), message(message), location({0, 0}) {} + + explicit InjaError(const std::string& type, const std::string& message, SourceLocation location) + : std::runtime_error("[inja.exception." + type + "] (at " + std::to_string(location.line) + ":" + std::to_string(location.column) + ") " + message), + type(type), message(message), location(location) {} +}; + +struct ParserError : public InjaError { + explicit ParserError(const std::string& message, SourceLocation location): InjaError("parser_error", message, location) {} +}; + +struct RenderError : public InjaError { + explicit RenderError(const std::string& message, SourceLocation location): InjaError("render_error", message, location) {} +}; + +struct FileError : public InjaError { + explicit FileError(const std::string& message): InjaError("file_error", message) {} + explicit FileError(const std::string& message, SourceLocation location): InjaError("file_error", message, location) {} +}; + +struct DataError : public InjaError { + explicit DataError(const std::string& message, SourceLocation location): InjaError("data_error", message, location) {} +}; + +} // namespace inja + +#endif // INCLUDE_INJA_EXCEPTIONS_HPP_ + + +namespace inja { + +namespace string_view { +inline std::string_view slice(std::string_view view, size_t start, size_t end) { + start = std::min(start, view.size()); + end = std::min(std::max(start, end), view.size()); + return view.substr(start, end - start); +} + +inline std::pair split(std::string_view view, char Separator) { + size_t idx = view.find(Separator); + if (idx == std::string_view::npos) { + return std::make_pair(view, std::string_view()); + } + return std::make_pair(slice(view, 0, idx), slice(view, idx + 1, std::string_view::npos)); +} + +inline bool starts_with(std::string_view view, std::string_view prefix) { + return (view.size() >= prefix.size() && view.compare(0, prefix.size(), prefix) == 0); +} +} // namespace string_view + +inline SourceLocation get_source_location(std::string_view content, size_t pos) { + // Get line and offset position (starts at 1:1) + auto sliced = string_view::slice(content, 0, pos); + std::size_t last_newline = sliced.rfind("\n"); + + if (last_newline == std::string_view::npos) { + return {1, sliced.length() + 1}; + } + + // Count newlines + size_t count_lines = 0; + size_t search_start = 0; + while (search_start <= sliced.size()) { + search_start = sliced.find("\n", search_start) + 1; + if (search_start == 0) { + break; + } + count_lines += 1; + } + + return {count_lines + 1, sliced.length() - last_newline}; +} + +inline void replace_substring(std::string& s, const std::string& f, const std::string& t) { + if (f.empty()) { + return; + } + for (auto pos = s.find(f); // find first occurrence of f + pos != std::string::npos; // make sure f was found + s.replace(pos, f.size(), t), // replace with t, and + pos = s.find(f, pos + t.size())) // find next occurrence of f + {} +} + +} // namespace inja + +#endif // INCLUDE_INJA_UTILS_HPP_ + + +namespace inja { + +class NodeVisitor; +class BlockNode; +class TextNode; +class ExpressionNode; +class LiteralNode; +class DataNode; +class FunctionNode; +class ExpressionListNode; +class StatementNode; +class ForStatementNode; +class ForArrayStatementNode; +class ForObjectStatementNode; +class IfStatementNode; +class IncludeStatementNode; +class ExtendsStatementNode; +class BlockStatementNode; +class SetStatementNode; + +class NodeVisitor { +public: + virtual ~NodeVisitor() = default; + + virtual void visit(const BlockNode& node) = 0; + virtual void visit(const TextNode& node) = 0; + virtual void visit(const ExpressionNode& node) = 0; + virtual void visit(const LiteralNode& node) = 0; + virtual void visit(const DataNode& node) = 0; + virtual void visit(const FunctionNode& node) = 0; + virtual void visit(const ExpressionListNode& node) = 0; + virtual void visit(const StatementNode& node) = 0; + virtual void visit(const ForStatementNode& node) = 0; + virtual void visit(const ForArrayStatementNode& node) = 0; + virtual void visit(const ForObjectStatementNode& node) = 0; + virtual void visit(const IfStatementNode& node) = 0; + virtual void visit(const IncludeStatementNode& node) = 0; + virtual void visit(const ExtendsStatementNode& node) = 0; + virtual void visit(const BlockStatementNode& node) = 0; + virtual void visit(const SetStatementNode& node) = 0; +}; + +/*! + * \brief Base node class for the abstract syntax tree (AST). + */ +class AstNode { +public: + virtual void accept(NodeVisitor& v) const = 0; + + size_t pos; + + AstNode(size_t pos): pos(pos) {} + virtual ~AstNode() {} +}; + +class BlockNode : public AstNode { +public: + std::vector> nodes; + + explicit BlockNode(): AstNode(0) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class TextNode : public AstNode { +public: + const size_t length; + + explicit TextNode(size_t pos, size_t length): AstNode(pos), length(length) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class ExpressionNode : public AstNode { +public: + explicit ExpressionNode(size_t pos): AstNode(pos) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class LiteralNode : public ExpressionNode { +public: + const json value; + + explicit LiteralNode(std::string_view data_text, size_t pos): ExpressionNode(pos), value(json::parse(data_text)) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class DataNode : public ExpressionNode { +public: + const std::string name; + const json::json_pointer ptr; + + static std::string convert_dot_to_ptr(std::string_view ptr_name) { + std::string result; + do { + std::string_view part; + std::tie(part, ptr_name) = string_view::split(ptr_name, '.'); + result.push_back('/'); + result.append(part.begin(), part.end()); + } while (!ptr_name.empty()); + return result; + } + + explicit DataNode(std::string_view ptr_name, size_t pos): ExpressionNode(pos), name(ptr_name), ptr(json::json_pointer(convert_dot_to_ptr(ptr_name))) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class FunctionNode : public ExpressionNode { + using Op = FunctionStorage::Operation; + +public: + enum class Associativity { + Left, + Right, + }; + + unsigned int precedence; + Associativity associativity; + + Op operation; + + std::string name; + int number_args; // Should also be negative -> -1 for unknown number + std::vector> arguments; + CallbackFunction callback; + + explicit FunctionNode(std::string_view name, size_t pos) + : ExpressionNode(pos), precedence(8), associativity(Associativity::Left), operation(Op::Callback), name(name), number_args(1) {} + explicit FunctionNode(Op operation, size_t pos): ExpressionNode(pos), operation(operation), number_args(1) { + switch (operation) { + case Op::Not: { + number_args = 1; + precedence = 4; + associativity = Associativity::Left; + } break; + case Op::And: { + number_args = 2; + precedence = 1; + associativity = Associativity::Left; + } break; + case Op::Or: { + number_args = 2; + precedence = 1; + associativity = Associativity::Left; + } break; + case Op::In: { + number_args = 2; + precedence = 2; + associativity = Associativity::Left; + } break; + case Op::Equal: { + number_args = 2; + precedence = 2; + associativity = Associativity::Left; + } break; + case Op::NotEqual: { + number_args = 2; + precedence = 2; + associativity = Associativity::Left; + } break; + case Op::Greater: { + number_args = 2; + precedence = 2; + associativity = Associativity::Left; + } break; + case Op::GreaterEqual: { + number_args = 2; + precedence = 2; + associativity = Associativity::Left; + } break; + case Op::Less: { + number_args = 2; + precedence = 2; + associativity = Associativity::Left; + } break; + case Op::LessEqual: { + number_args = 2; + precedence = 2; + associativity = Associativity::Left; + } break; + case Op::Add: { + number_args = 2; + precedence = 3; + associativity = Associativity::Left; + } break; + case Op::Subtract: { + number_args = 2; + precedence = 3; + associativity = Associativity::Left; + } break; + case Op::Multiplication: { + number_args = 2; + precedence = 4; + associativity = Associativity::Left; + } break; + case Op::Division: { + number_args = 2; + precedence = 4; + associativity = Associativity::Left; + } break; + case Op::Power: { + number_args = 2; + precedence = 5; + associativity = Associativity::Right; + } break; + case Op::Modulo: { + number_args = 2; + precedence = 4; + associativity = Associativity::Left; + } break; + case Op::AtId: { + number_args = 2; + precedence = 8; + associativity = Associativity::Left; + } break; + default: { + precedence = 1; + associativity = Associativity::Left; + } + } + } + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class ExpressionListNode : public AstNode { +public: + std::shared_ptr root; + + explicit ExpressionListNode(): AstNode(0) {} + explicit ExpressionListNode(size_t pos): AstNode(pos) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class StatementNode : public AstNode { +public: + StatementNode(size_t pos): AstNode(pos) {} + + virtual void accept(NodeVisitor& v) const = 0; +}; + +class ForStatementNode : public StatementNode { +public: + ExpressionListNode condition; + BlockNode body; + BlockNode* const parent; + + ForStatementNode(BlockNode* const parent, size_t pos): StatementNode(pos), parent(parent) {} + + virtual void accept(NodeVisitor& v) const = 0; +}; + +class ForArrayStatementNode : public ForStatementNode { +public: + const std::string value; + + explicit ForArrayStatementNode(const std::string& value, BlockNode* const parent, size_t pos): ForStatementNode(parent, pos), value(value) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class ForObjectStatementNode : public ForStatementNode { +public: + const std::string key; + const std::string value; + + explicit ForObjectStatementNode(const std::string& key, const std::string& value, BlockNode* const parent, size_t pos) + : ForStatementNode(parent, pos), key(key), value(value) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class IfStatementNode : public StatementNode { +public: + ExpressionListNode condition; + BlockNode true_statement; + BlockNode false_statement; + BlockNode* const parent; + + const bool is_nested; + bool has_false_statement {false}; + + explicit IfStatementNode(BlockNode* const parent, size_t pos): StatementNode(pos), parent(parent), is_nested(false) {} + explicit IfStatementNode(bool is_nested, BlockNode* const parent, size_t pos): StatementNode(pos), parent(parent), is_nested(is_nested) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class IncludeStatementNode : public StatementNode { +public: + const std::string file; + + explicit IncludeStatementNode(const std::string& file, size_t pos): StatementNode(pos), file(file) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +class ExtendsStatementNode : public StatementNode { +public: + const std::string file; + + explicit ExtendsStatementNode(const std::string& file, size_t pos): StatementNode(pos), file(file) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + }; +}; + +class BlockStatementNode : public StatementNode { +public: + const std::string name; + BlockNode block; + BlockNode* const parent; + + explicit BlockStatementNode(BlockNode* const parent, const std::string& name, size_t pos): StatementNode(pos), name(name), parent(parent) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + }; +}; + +class SetStatementNode : public StatementNode { +public: + const std::string key; + ExpressionListNode expression; + + explicit SetStatementNode(const std::string& key, size_t pos): StatementNode(pos), key(key) {} + + void accept(NodeVisitor& v) const { + v.visit(*this); + } +}; + +} // namespace inja + +#endif // INCLUDE_INJA_NODE_HPP_ + +// #include "statistics.hpp" +#ifndef INCLUDE_INJA_STATISTICS_HPP_ +#define INCLUDE_INJA_STATISTICS_HPP_ + +// #include "node.hpp" + + +namespace inja { + +/*! + * \brief A class for counting statistics on a Template. + */ +class StatisticsVisitor : public NodeVisitor { + void visit(const BlockNode& node) { + for (auto& n : node.nodes) { + n->accept(*this); + } + } + + void visit(const TextNode&) {} + void visit(const ExpressionNode&) {} + void visit(const LiteralNode&) {} + + void visit(const DataNode&) { + variable_counter += 1; + } + + void visit(const FunctionNode& node) { + for (auto& n : node.arguments) { + n->accept(*this); + } + } + + void visit(const ExpressionListNode& node) { + node.root->accept(*this); + } + + void visit(const StatementNode&) {} + void visit(const ForStatementNode&) {} + + void visit(const ForArrayStatementNode& node) { + node.condition.accept(*this); + node.body.accept(*this); + } + + void visit(const ForObjectStatementNode& node) { + node.condition.accept(*this); + node.body.accept(*this); + } + + void visit(const IfStatementNode& node) { + node.condition.accept(*this); + node.true_statement.accept(*this); + node.false_statement.accept(*this); + } + + void visit(const IncludeStatementNode&) {} + + void visit(const ExtendsStatementNode&) {} + + void visit(const BlockStatementNode& node) { + node.block.accept(*this); + } + + void visit(const SetStatementNode&) {} + +public: + unsigned int variable_counter; + + explicit StatisticsVisitor(): variable_counter(0) {} +}; + +} // namespace inja + +#endif // INCLUDE_INJA_STATISTICS_HPP_ + + +namespace inja { + +/*! + * \brief The main inja Template. + */ +struct Template { + BlockNode root; + std::string content; + std::map> block_storage; + + explicit Template() {} + explicit Template(const std::string& content): content(content) {} + + /// Return number of variables (total number, not distinct ones) in the template + int count_variables() { + auto statistic_visitor = StatisticsVisitor(); + root.accept(statistic_visitor); + return statistic_visitor.variable_counter; + } +}; + +using TemplateStorage = std::map; + +} // namespace inja + +#endif // INCLUDE_INJA_TEMPLATE_HPP_ + + +namespace inja { + +/*! + * \brief Class for lexer configuration. + */ +struct LexerConfig { + std::string statement_open {"{%"}; + std::string statement_open_no_lstrip {"{%+"}; + std::string statement_open_force_lstrip {"{%-"}; + std::string statement_close {"%}"}; + std::string statement_close_force_rstrip {"-%}"}; + std::string line_statement {"##"}; + std::string expression_open {"{{"}; + std::string expression_open_force_lstrip {"{{-"}; + std::string expression_close {"}}"}; + std::string expression_close_force_rstrip {"-}}"}; + std::string comment_open {"{#"}; + std::string comment_open_force_lstrip {"{#-"}; + std::string comment_close {"#}"}; + std::string comment_close_force_rstrip {"-#}"}; + std::string open_chars {"#{"}; + + bool trim_blocks {false}; + bool lstrip_blocks {false}; + + void update_open_chars() { + open_chars = ""; + if (open_chars.find(line_statement[0]) == std::string::npos) { + open_chars += line_statement[0]; + } + if (open_chars.find(statement_open[0]) == std::string::npos) { + open_chars += statement_open[0]; + } + if (open_chars.find(statement_open_no_lstrip[0]) == std::string::npos) { + open_chars += statement_open_no_lstrip[0]; + } + if (open_chars.find(statement_open_force_lstrip[0]) == std::string::npos) { + open_chars += statement_open_force_lstrip[0]; + } + if (open_chars.find(expression_open[0]) == std::string::npos) { + open_chars += expression_open[0]; + } + if (open_chars.find(expression_open_force_lstrip[0]) == std::string::npos) { + open_chars += expression_open_force_lstrip[0]; + } + if (open_chars.find(comment_open[0]) == std::string::npos) { + open_chars += comment_open[0]; + } + if (open_chars.find(comment_open_force_lstrip[0]) == std::string::npos) { + open_chars += comment_open_force_lstrip[0]; + } + } +}; + +/*! + * \brief Class for parser configuration. + */ +struct ParserConfig { + bool search_included_templates_in_files {true}; + + std::function include_callback; +}; + +/*! + * \brief Class for render configuration. + */ +struct RenderConfig { + bool throw_at_missing_includes {true}; +}; + +} // namespace inja + +#endif // INCLUDE_INJA_CONFIG_HPP_ + +// #include "function_storage.hpp" + +// #include "parser.hpp" +#ifndef INCLUDE_INJA_PARSER_HPP_ +#define INCLUDE_INJA_PARSER_HPP_ + +#include +#include +#include +#include +#include + +// #include "config.hpp" + +// #include "exceptions.hpp" + +// #include "function_storage.hpp" + +// #include "lexer.hpp" +#ifndef INCLUDE_INJA_LEXER_HPP_ +#define INCLUDE_INJA_LEXER_HPP_ + +#include +#include + +// #include "config.hpp" + +// #include "token.hpp" +#ifndef INCLUDE_INJA_TOKEN_HPP_ +#define INCLUDE_INJA_TOKEN_HPP_ + +#include +#include + +namespace inja { + +/*! + * \brief Helper-class for the inja Lexer. + */ +struct Token { + enum class Kind { + Text, + ExpressionOpen, // {{ + ExpressionClose, // }} + LineStatementOpen, // ## + LineStatementClose, // \n + StatementOpen, // {% + StatementClose, // %} + CommentOpen, // {# + CommentClose, // #} + Id, // this, this.foo + Number, // 1, 2, -1, 5.2, -5.3 + String, // "this" + Plus, // + + Minus, // - + Times, // * + Slash, // / + Percent, // % + Power, // ^ + Comma, // , + Dot, // . + Colon, // : + LeftParen, // ( + RightParen, // ) + LeftBracket, // [ + RightBracket, // ] + LeftBrace, // { + RightBrace, // } + Equal, // == + NotEqual, // != + GreaterThan, // > + GreaterEqual, // >= + LessThan, // < + LessEqual, // <= + Unknown, + Eof, + }; + + Kind kind {Kind::Unknown}; + std::string_view text; + + explicit constexpr Token() = default; + explicit constexpr Token(Kind kind, std::string_view text): kind(kind), text(text) {} + + std::string describe() const { + switch (kind) { + case Kind::Text: + return ""; + case Kind::LineStatementClose: + return ""; + case Kind::Eof: + return ""; + default: + return static_cast(text); + } + } +}; + +} // namespace inja + +#endif // INCLUDE_INJA_TOKEN_HPP_ + +// #include "utils.hpp" + + +namespace inja { + +/*! + * \brief Class for lexing an inja Template. + */ +class Lexer { + enum class State { + Text, + ExpressionStart, + ExpressionStartForceLstrip, + ExpressionBody, + LineStart, + LineBody, + StatementStart, + StatementStartNoLstrip, + StatementStartForceLstrip, + StatementBody, + CommentStart, + CommentStartForceLstrip, + CommentBody, + }; + + enum class MinusState { + Operator, + Number, + }; + + const LexerConfig& config; + + State state; + MinusState minus_state; + std::string_view m_in; + size_t tok_start; + size_t pos; + + Token scan_body(std::string_view close, Token::Kind closeKind, std::string_view close_trim = std::string_view(), bool trim = false) { + again: + // skip whitespace (except for \n as it might be a close) + if (tok_start >= m_in.size()) { + return make_token(Token::Kind::Eof); + } + const char ch = m_in[tok_start]; + if (ch == ' ' || ch == '\t' || ch == '\r') { + tok_start += 1; + goto again; + } + + // check for close + if (!close_trim.empty() && inja::string_view::starts_with(m_in.substr(tok_start), close_trim)) { + state = State::Text; + pos = tok_start + close_trim.size(); + const Token tok = make_token(closeKind); + skip_whitespaces_and_newlines(); + return tok; + } + + if (inja::string_view::starts_with(m_in.substr(tok_start), close)) { + state = State::Text; + pos = tok_start + close.size(); + const Token tok = make_token(closeKind); + if (trim) { + skip_whitespaces_and_first_newline(); + } + return tok; + } + + // skip \n + if (ch == '\n') { + tok_start += 1; + goto again; + } + + pos = tok_start + 1; + if (std::isalpha(ch)) { + minus_state = MinusState::Operator; + return scan_id(); + } + + const MinusState current_minus_state = minus_state; + if (minus_state == MinusState::Operator) { + minus_state = MinusState::Number; + } + + switch (ch) { + case '+': + return make_token(Token::Kind::Plus); + case '-': + if (current_minus_state == MinusState::Operator) { + return make_token(Token::Kind::Minus); + } + return scan_number(); + case '*': + return make_token(Token::Kind::Times); + case '/': + return make_token(Token::Kind::Slash); + case '^': + return make_token(Token::Kind::Power); + case '%': + return make_token(Token::Kind::Percent); + case '.': + return make_token(Token::Kind::Dot); + case ',': + return make_token(Token::Kind::Comma); + case ':': + return make_token(Token::Kind::Colon); + case '(': + return make_token(Token::Kind::LeftParen); + case ')': + minus_state = MinusState::Operator; + return make_token(Token::Kind::RightParen); + case '[': + return make_token(Token::Kind::LeftBracket); + case ']': + minus_state = MinusState::Operator; + return make_token(Token::Kind::RightBracket); + case '{': + return make_token(Token::Kind::LeftBrace); + case '}': + minus_state = MinusState::Operator; + return make_token(Token::Kind::RightBrace); + case '>': + if (pos < m_in.size() && m_in[pos] == '=') { + pos += 1; + return make_token(Token::Kind::GreaterEqual); + } + return make_token(Token::Kind::GreaterThan); + case '<': + if (pos < m_in.size() && m_in[pos] == '=') { + pos += 1; + return make_token(Token::Kind::LessEqual); + } + return make_token(Token::Kind::LessThan); + case '=': + if (pos < m_in.size() && m_in[pos] == '=') { + pos += 1; + return make_token(Token::Kind::Equal); + } + return make_token(Token::Kind::Unknown); + case '!': + if (pos < m_in.size() && m_in[pos] == '=') { + pos += 1; + return make_token(Token::Kind::NotEqual); + } + return make_token(Token::Kind::Unknown); + case '\"': + return scan_string(); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + minus_state = MinusState::Operator; + return scan_number(); + case '_': + case '@': + case '$': + minus_state = MinusState::Operator; + return scan_id(); + default: + return make_token(Token::Kind::Unknown); + } + } + + Token scan_id() { + for (;;) { + if (pos >= m_in.size()) { + break; + } + const char ch = m_in[pos]; + if (!std::isalnum(ch) && ch != '.' && ch != '/' && ch != '_' && ch != '-') { + break; + } + pos += 1; + } + return make_token(Token::Kind::Id); + } + + Token scan_number() { + for (;;) { + if (pos >= m_in.size()) { + break; + } + const char ch = m_in[pos]; + // be very permissive in lexer (we'll catch errors when conversion happens) + if (!(std::isdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' || (ch == '+' && (pos == 0 || m_in[pos-1] == 'e' || m_in[pos-1] == 'E')) || (ch == '-' && (pos == 0 || m_in[pos-1] == 'e' || m_in[pos-1] == 'E')))) { + break; + } + pos += 1; + } + return make_token(Token::Kind::Number); + } + + Token scan_string() { + bool escape {false}; + for (;;) { + if (pos >= m_in.size()) { + break; + } + const char ch = m_in[pos++]; + if (ch == '\\') { + escape = true; + } else if (!escape && ch == m_in[tok_start]) { + break; + } else { + escape = false; + } + } + return make_token(Token::Kind::String); + } + + Token make_token(Token::Kind kind) const { + return Token(kind, string_view::slice(m_in, tok_start, pos)); + } + + void skip_whitespaces_and_newlines() { + if (pos < m_in.size()) { + while (pos < m_in.size() && (m_in[pos] == ' ' || m_in[pos] == '\t' || m_in[pos] == '\n' || m_in[pos] == '\r')) { + pos += 1; + } + } + } + + void skip_whitespaces_and_first_newline() { + if (pos < m_in.size()) { + while (pos < m_in.size() && (m_in[pos] == ' ' || m_in[pos] == '\t')) { + pos += 1; + } + } + + if (pos < m_in.size()) { + const char ch = m_in[pos]; + if (ch == '\n') { + pos += 1; + } else if (ch == '\r') { + pos += 1; + if (pos < m_in.size() && m_in[pos] == '\n') { + pos += 1; + } + } + } + } + + static std::string_view clear_final_line_if_whitespace(std::string_view text) { + std::string_view result = text; + while (!result.empty()) { + const char ch = result.back(); + if (ch == ' ' || ch == '\t') { + result.remove_suffix(1); + } else if (ch == '\n' || ch == '\r') { + break; + } else { + return text; + } + } + return result; + } + +public: + explicit Lexer(const LexerConfig& config): config(config), state(State::Text), minus_state(MinusState::Number) {} + + SourceLocation current_position() const { + return get_source_location(m_in, tok_start); + } + + void start(std::string_view input) { + m_in = input; + tok_start = 0; + pos = 0; + state = State::Text; + minus_state = MinusState::Number; + + // Consume byte order mark (BOM) for UTF-8 + if (inja::string_view::starts_with(m_in, "\xEF\xBB\xBF")) { + m_in = m_in.substr(3); + } + } + + Token scan() { + tok_start = pos; + + again: + if (tok_start >= m_in.size()) { + return make_token(Token::Kind::Eof); + } + + switch (state) { + default: + case State::Text: { + // fast-scan to first open character + const size_t open_start = m_in.substr(pos).find_first_of(config.open_chars); + if (open_start == std::string_view::npos) { + // didn't find open, return remaining text as text token + pos = m_in.size(); + return make_token(Token::Kind::Text); + } + pos += open_start; + + // try to match one of the opening sequences, and get the close + std::string_view open_str = m_in.substr(pos); + bool must_lstrip = false; + if (inja::string_view::starts_with(open_str, config.expression_open)) { + if (inja::string_view::starts_with(open_str, config.expression_open_force_lstrip)) { + state = State::ExpressionStartForceLstrip; + must_lstrip = true; + } else { + state = State::ExpressionStart; + } + } else if (inja::string_view::starts_with(open_str, config.statement_open)) { + if (inja::string_view::starts_with(open_str, config.statement_open_no_lstrip)) { + state = State::StatementStartNoLstrip; + } else if (inja::string_view::starts_with(open_str, config.statement_open_force_lstrip)) { + state = State::StatementStartForceLstrip; + must_lstrip = true; + } else { + state = State::StatementStart; + must_lstrip = config.lstrip_blocks; + } + } else if (inja::string_view::starts_with(open_str, config.comment_open)) { + if (inja::string_view::starts_with(open_str, config.comment_open_force_lstrip)) { + state = State::CommentStartForceLstrip; + must_lstrip = true; + } else { + state = State::CommentStart; + must_lstrip = config.lstrip_blocks; + } + } else if ((pos == 0 || m_in[pos - 1] == '\n') && inja::string_view::starts_with(open_str, config.line_statement)) { + state = State::LineStart; + } else { + pos += 1; // wasn't actually an opening sequence + goto again; + } + + std::string_view text = string_view::slice(m_in, tok_start, pos); + if (must_lstrip) { + text = clear_final_line_if_whitespace(text); + } + + if (text.empty()) { + goto again; // don't generate empty token + } + return Token(Token::Kind::Text, text); + } + case State::ExpressionStart: { + state = State::ExpressionBody; + pos += config.expression_open.size(); + return make_token(Token::Kind::ExpressionOpen); + } + case State::ExpressionStartForceLstrip: { + state = State::ExpressionBody; + pos += config.expression_open_force_lstrip.size(); + return make_token(Token::Kind::ExpressionOpen); + } + case State::LineStart: { + state = State::LineBody; + pos += config.line_statement.size(); + return make_token(Token::Kind::LineStatementOpen); + } + case State::StatementStart: { + state = State::StatementBody; + pos += config.statement_open.size(); + return make_token(Token::Kind::StatementOpen); + } + case State::StatementStartNoLstrip: { + state = State::StatementBody; + pos += config.statement_open_no_lstrip.size(); + return make_token(Token::Kind::StatementOpen); + } + case State::StatementStartForceLstrip: { + state = State::StatementBody; + pos += config.statement_open_force_lstrip.size(); + return make_token(Token::Kind::StatementOpen); + } + case State::CommentStart: { + state = State::CommentBody; + pos += config.comment_open.size(); + return make_token(Token::Kind::CommentOpen); + } + case State::CommentStartForceLstrip: { + state = State::CommentBody; + pos += config.comment_open_force_lstrip.size(); + return make_token(Token::Kind::CommentOpen); + } + case State::ExpressionBody: + return scan_body(config.expression_close, Token::Kind::ExpressionClose, config.expression_close_force_rstrip); + case State::LineBody: + return scan_body("\n", Token::Kind::LineStatementClose); + case State::StatementBody: + return scan_body(config.statement_close, Token::Kind::StatementClose, config.statement_close_force_rstrip, config.trim_blocks); + case State::CommentBody: { + // fast-scan to comment close + const size_t end = m_in.substr(pos).find(config.comment_close); + if (end == std::string_view::npos) { + pos = m_in.size(); + return make_token(Token::Kind::Eof); + } + + // Check for trim pattern + const bool must_rstrip = inja::string_view::starts_with(m_in.substr(pos + end - 1), config.comment_close_force_rstrip); + + // return the entire comment in the close token + state = State::Text; + pos += end + config.comment_close.size(); + Token tok = make_token(Token::Kind::CommentClose); + + if (must_rstrip || config.trim_blocks) { + skip_whitespaces_and_first_newline(); + } + return tok; + } + } + } + + const LexerConfig& get_config() const { + return config; + } +}; + +} // namespace inja + +#endif // INCLUDE_INJA_LEXER_HPP_ + +// #include "node.hpp" + +// #include "template.hpp" + +// #include "token.hpp" + +// #include "utils.hpp" + + +namespace inja { + +/*! + * \brief Class for parsing an inja Template. + */ +class Parser { + const ParserConfig& config; + + Lexer lexer; + TemplateStorage& template_storage; + const FunctionStorage& function_storage; + + Token tok, peek_tok; + bool have_peek_tok {false}; + + size_t current_paren_level {0}; + size_t current_bracket_level {0}; + size_t current_brace_level {0}; + + std::string_view literal_start; + + BlockNode* current_block {nullptr}; + ExpressionListNode* current_expression_list {nullptr}; + std::stack> function_stack; + std::vector> arguments; + + std::stack> operator_stack; + std::stack if_statement_stack; + std::stack for_statement_stack; + std::stack block_statement_stack; + + inline void throw_parser_error(const std::string& message) const { + INJA_THROW(ParserError(message, lexer.current_position())); + } + + inline void get_next_token() { + if (have_peek_tok) { + tok = peek_tok; + have_peek_tok = false; + } else { + tok = lexer.scan(); + } + } + + inline void get_peek_token() { + if (!have_peek_tok) { + peek_tok = lexer.scan(); + have_peek_tok = true; + } + } + + inline void add_literal(const char* content_ptr) { + std::string_view data_text(literal_start.data(), tok.text.data() - literal_start.data() + tok.text.size()); + arguments.emplace_back(std::make_shared(data_text, data_text.data() - content_ptr)); + } + + inline void add_operator() { + auto function = operator_stack.top(); + operator_stack.pop(); + + for (int i = 0; i < function->number_args; ++i) { + function->arguments.insert(function->arguments.begin(), arguments.back()); + arguments.pop_back(); + } + arguments.emplace_back(function); + } + + void add_to_template_storage(std::string_view path, std::string& template_name) { + if (template_storage.find(template_name) != template_storage.end()) { + return; + } + + std::string original_path = static_cast(path); + std::string original_name = template_name; + + if (config.search_included_templates_in_files) { + // Build the relative path + template_name = original_path + original_name; + if (template_name.compare(0, 2, "./") == 0) { + template_name.erase(0, 2); + } + + if (template_storage.find(template_name) == template_storage.end()) { + // Load file + std::ifstream file; + file.open(template_name); + if (!file.fail()) { + std::string text((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + + auto include_template = Template(text); + template_storage.emplace(template_name, include_template); + parse_into_template(template_storage[template_name], template_name); + return; + } else if (!config.include_callback) { + INJA_THROW(FileError("failed accessing file at '" + template_name + "'")); + } + } + } + + // Try include callback + if (config.include_callback) { + auto include_template = config.include_callback(original_path, original_name); + template_storage.emplace(template_name, include_template); + } + } + + std::string parse_filename(const Token& tok) const { + if (tok.kind != Token::Kind::String) { + throw_parser_error("expected string, got '" + tok.describe() + "'"); + } + + if (tok.text.length() < 2) { + throw_parser_error("expected filename, got '" + static_cast(tok.text) + "'"); + } + + // Remove first and last character "" + return std::string {tok.text.substr(1, tok.text.length() - 2)}; + } + + bool parse_expression(Template& tmpl, Token::Kind closing) { + while (tok.kind != closing && tok.kind != Token::Kind::Eof) { + // Literals + switch (tok.kind) { + case Token::Kind::String: { + if (current_brace_level == 0 && current_bracket_level == 0) { + literal_start = tok.text; + add_literal(tmpl.content.c_str()); + } + } break; + case Token::Kind::Number: { + if (current_brace_level == 0 && current_bracket_level == 0) { + literal_start = tok.text; + add_literal(tmpl.content.c_str()); + } + } break; + case Token::Kind::LeftBracket: { + if (current_brace_level == 0 && current_bracket_level == 0) { + literal_start = tok.text; + } + current_bracket_level += 1; + } break; + case Token::Kind::LeftBrace: { + if (current_brace_level == 0 && current_bracket_level == 0) { + literal_start = tok.text; + } + current_brace_level += 1; + } break; + case Token::Kind::RightBracket: { + if (current_bracket_level == 0) { + throw_parser_error("unexpected ']'"); + } + + current_bracket_level -= 1; + if (current_brace_level == 0 && current_bracket_level == 0) { + add_literal(tmpl.content.c_str()); + } + } break; + case Token::Kind::RightBrace: { + if (current_brace_level == 0) { + throw_parser_error("unexpected '}'"); + } + + current_brace_level -= 1; + if (current_brace_level == 0 && current_bracket_level == 0) { + add_literal(tmpl.content.c_str()); + } + } break; + case Token::Kind::Id: { + get_peek_token(); + + // Data Literal + if (tok.text == static_cast("true") || tok.text == static_cast("false") || + tok.text == static_cast("null")) { + if (current_brace_level == 0 && current_bracket_level == 0) { + literal_start = tok.text; + add_literal(tmpl.content.c_str()); + } + + // Operator + } else if (tok.text == "and" || tok.text == "or" || tok.text == "in" || tok.text == "not") { + goto parse_operator; + + // Functions + } else if (peek_tok.kind == Token::Kind::LeftParen) { + operator_stack.emplace(std::make_shared(static_cast(tok.text), tok.text.data() - tmpl.content.c_str())); + function_stack.emplace(operator_stack.top().get(), current_paren_level); + + // Variables + } else { + arguments.emplace_back(std::make_shared(static_cast(tok.text), tok.text.data() - tmpl.content.c_str())); + } + + // Operators + } break; + case Token::Kind::Equal: + case Token::Kind::NotEqual: + case Token::Kind::GreaterThan: + case Token::Kind::GreaterEqual: + case Token::Kind::LessThan: + case Token::Kind::LessEqual: + case Token::Kind::Plus: + case Token::Kind::Minus: + case Token::Kind::Times: + case Token::Kind::Slash: + case Token::Kind::Power: + case Token::Kind::Percent: + case Token::Kind::Dot: { + + parse_operator: + FunctionStorage::Operation operation; + switch (tok.kind) { + case Token::Kind::Id: { + if (tok.text == "and") { + operation = FunctionStorage::Operation::And; + } else if (tok.text == "or") { + operation = FunctionStorage::Operation::Or; + } else if (tok.text == "in") { + operation = FunctionStorage::Operation::In; + } else if (tok.text == "not") { + operation = FunctionStorage::Operation::Not; + } else { + throw_parser_error("unknown operator in parser."); + } + } break; + case Token::Kind::Equal: { + operation = FunctionStorage::Operation::Equal; + } break; + case Token::Kind::NotEqual: { + operation = FunctionStorage::Operation::NotEqual; + } break; + case Token::Kind::GreaterThan: { + operation = FunctionStorage::Operation::Greater; + } break; + case Token::Kind::GreaterEqual: { + operation = FunctionStorage::Operation::GreaterEqual; + } break; + case Token::Kind::LessThan: { + operation = FunctionStorage::Operation::Less; + } break; + case Token::Kind::LessEqual: { + operation = FunctionStorage::Operation::LessEqual; + } break; + case Token::Kind::Plus: { + operation = FunctionStorage::Operation::Add; + } break; + case Token::Kind::Minus: { + operation = FunctionStorage::Operation::Subtract; + } break; + case Token::Kind::Times: { + operation = FunctionStorage::Operation::Multiplication; + } break; + case Token::Kind::Slash: { + operation = FunctionStorage::Operation::Division; + } break; + case Token::Kind::Power: { + operation = FunctionStorage::Operation::Power; + } break; + case Token::Kind::Percent: { + operation = FunctionStorage::Operation::Modulo; + } break; + case Token::Kind::Dot: { + operation = FunctionStorage::Operation::AtId; + } break; + default: { + throw_parser_error("unknown operator in parser."); + } + } + auto function_node = std::make_shared(operation, tok.text.data() - tmpl.content.c_str()); + + while (!operator_stack.empty() && + ((operator_stack.top()->precedence > function_node->precedence) || + (operator_stack.top()->precedence == function_node->precedence && function_node->associativity == FunctionNode::Associativity::Left)) && + (operator_stack.top()->operation != FunctionStorage::Operation::ParenLeft)) { + add_operator(); + } + + operator_stack.emplace(function_node); + } break; + case Token::Kind::Comma: { + if (current_brace_level == 0 && current_bracket_level == 0) { + if (function_stack.empty()) { + throw_parser_error("unexpected ','"); + } + + function_stack.top().first->number_args += 1; + } + } break; + case Token::Kind::Colon: { + if (current_brace_level == 0 && current_bracket_level == 0) { + throw_parser_error("unexpected ':'"); + } + } break; + case Token::Kind::LeftParen: { + current_paren_level += 1; + operator_stack.emplace(std::make_shared(FunctionStorage::Operation::ParenLeft, tok.text.data() - tmpl.content.c_str())); + + get_peek_token(); + if (peek_tok.kind == Token::Kind::RightParen) { + if (!function_stack.empty() && function_stack.top().second == current_paren_level - 1) { + function_stack.top().first->number_args = 0; + } + } + } break; + case Token::Kind::RightParen: { + current_paren_level -= 1; + while (!operator_stack.empty() && operator_stack.top()->operation != FunctionStorage::Operation::ParenLeft) { + add_operator(); + } + + if (!operator_stack.empty() && operator_stack.top()->operation == FunctionStorage::Operation::ParenLeft) { + operator_stack.pop(); + } + + if (!function_stack.empty() && function_stack.top().second == current_paren_level) { + auto func = function_stack.top().first; + auto function_data = function_storage.find_function(func->name, func->number_args); + if (function_data.operation == FunctionStorage::Operation::None) { + throw_parser_error("unknown function " + func->name); + } + func->operation = function_data.operation; + if (function_data.operation == FunctionStorage::Operation::Callback) { + func->callback = function_data.callback; + } + + if (operator_stack.empty()) { + throw_parser_error("internal error at function " + func->name); + } + + add_operator(); + function_stack.pop(); + } + } + default: + break; + } + + get_next_token(); + } + + while (!operator_stack.empty()) { + add_operator(); + } + + if (arguments.size() == 1) { + current_expression_list->root = arguments[0]; + arguments = {}; + } else if (arguments.size() > 1) { + throw_parser_error("malformed expression"); + } + + return true; + } + + bool parse_statement(Template& tmpl, Token::Kind closing, std::string_view path) { + if (tok.kind != Token::Kind::Id) { + return false; + } + + if (tok.text == static_cast("if")) { + get_next_token(); + + auto if_statement_node = std::make_shared(current_block, tok.text.data() - tmpl.content.c_str()); + current_block->nodes.emplace_back(if_statement_node); + if_statement_stack.emplace(if_statement_node.get()); + current_block = &if_statement_node->true_statement; + current_expression_list = &if_statement_node->condition; + + if (!parse_expression(tmpl, closing)) { + return false; + } + } else if (tok.text == static_cast("else")) { + if (if_statement_stack.empty()) { + throw_parser_error("else without matching if"); + } + auto& if_statement_data = if_statement_stack.top(); + get_next_token(); + + if_statement_data->has_false_statement = true; + current_block = &if_statement_data->false_statement; + + // Chained else if + if (tok.kind == Token::Kind::Id && tok.text == static_cast("if")) { + get_next_token(); + + auto if_statement_node = std::make_shared(true, current_block, tok.text.data() - tmpl.content.c_str()); + current_block->nodes.emplace_back(if_statement_node); + if_statement_stack.emplace(if_statement_node.get()); + current_block = &if_statement_node->true_statement; + current_expression_list = &if_statement_node->condition; + + if (!parse_expression(tmpl, closing)) { + return false; + } + } + } else if (tok.text == static_cast("endif")) { + if (if_statement_stack.empty()) { + throw_parser_error("endif without matching if"); + } + + // Nested if statements + while (if_statement_stack.top()->is_nested) { + if_statement_stack.pop(); + } + + auto& if_statement_data = if_statement_stack.top(); + get_next_token(); + + current_block = if_statement_data->parent; + if_statement_stack.pop(); + } else if (tok.text == static_cast("block")) { + get_next_token(); + + if (tok.kind != Token::Kind::Id) { + throw_parser_error("expected block name, got '" + tok.describe() + "'"); + } + + const std::string block_name = static_cast(tok.text); + + auto block_statement_node = std::make_shared(current_block, block_name, tok.text.data() - tmpl.content.c_str()); + current_block->nodes.emplace_back(block_statement_node); + block_statement_stack.emplace(block_statement_node.get()); + current_block = &block_statement_node->block; + auto success = tmpl.block_storage.emplace(block_name, block_statement_node); + if (!success.second) { + throw_parser_error("block with the name '" + block_name + "' does already exist"); + } + + get_next_token(); + } else if (tok.text == static_cast("endblock")) { + if (block_statement_stack.empty()) { + throw_parser_error("endblock without matching block"); + } + + auto& block_statement_data = block_statement_stack.top(); + get_next_token(); + + current_block = block_statement_data->parent; + block_statement_stack.pop(); + } else if (tok.text == static_cast("for")) { + get_next_token(); + + // options: for a in arr; for a, b in obj + if (tok.kind != Token::Kind::Id) { + throw_parser_error("expected id, got '" + tok.describe() + "'"); + } + + Token value_token = tok; + get_next_token(); + + // Object type + std::shared_ptr for_statement_node; + if (tok.kind == Token::Kind::Comma) { + get_next_token(); + if (tok.kind != Token::Kind::Id) { + throw_parser_error("expected id, got '" + tok.describe() + "'"); + } + + Token key_token = std::move(value_token); + value_token = tok; + get_next_token(); + + for_statement_node = std::make_shared(static_cast(key_token.text), static_cast(value_token.text), + current_block, tok.text.data() - tmpl.content.c_str()); + + // Array type + } else { + for_statement_node = + std::make_shared(static_cast(value_token.text), current_block, tok.text.data() - tmpl.content.c_str()); + } + + current_block->nodes.emplace_back(for_statement_node); + for_statement_stack.emplace(for_statement_node.get()); + current_block = &for_statement_node->body; + current_expression_list = &for_statement_node->condition; + + if (tok.kind != Token::Kind::Id || tok.text != static_cast("in")) { + throw_parser_error("expected 'in', got '" + tok.describe() + "'"); + } + get_next_token(); + + if (!parse_expression(tmpl, closing)) { + return false; + } + } else if (tok.text == static_cast("endfor")) { + if (for_statement_stack.empty()) { + throw_parser_error("endfor without matching for"); + } + + auto& for_statement_data = for_statement_stack.top(); + get_next_token(); + + current_block = for_statement_data->parent; + for_statement_stack.pop(); + } else if (tok.text == static_cast("include")) { + get_next_token(); + + std::string template_name = parse_filename(tok); + add_to_template_storage(path, template_name); + + current_block->nodes.emplace_back(std::make_shared(template_name, tok.text.data() - tmpl.content.c_str())); + + get_next_token(); + } else if (tok.text == static_cast("extends")) { + get_next_token(); + + std::string template_name = parse_filename(tok); + add_to_template_storage(path, template_name); + + current_block->nodes.emplace_back(std::make_shared(template_name, tok.text.data() - tmpl.content.c_str())); + + get_next_token(); + } else if (tok.text == static_cast("set")) { + get_next_token(); + + if (tok.kind != Token::Kind::Id) { + throw_parser_error("expected variable name, got '" + tok.describe() + "'"); + } + + std::string key = static_cast(tok.text); + get_next_token(); + + auto set_statement_node = std::make_shared(key, tok.text.data() - tmpl.content.c_str()); + current_block->nodes.emplace_back(set_statement_node); + current_expression_list = &set_statement_node->expression; + + if (tok.text != static_cast("=")) { + throw_parser_error("expected '=', got '" + tok.describe() + "'"); + } + get_next_token(); + + if (!parse_expression(tmpl, closing)) { + return false; + } + } else { + return false; + } + return true; + } + + void parse_into(Template& tmpl, std::string_view path) { + lexer.start(tmpl.content); + current_block = &tmpl.root; + + for (;;) { + get_next_token(); + switch (tok.kind) { + case Token::Kind::Eof: { + if (!if_statement_stack.empty()) { + throw_parser_error("unmatched if"); + } + if (!for_statement_stack.empty()) { + throw_parser_error("unmatched for"); + } + } + return; + case Token::Kind::Text: { + current_block->nodes.emplace_back(std::make_shared(tok.text.data() - tmpl.content.c_str(), tok.text.size())); + } break; + case Token::Kind::StatementOpen: { + get_next_token(); + if (!parse_statement(tmpl, Token::Kind::StatementClose, path)) { + throw_parser_error("expected statement, got '" + tok.describe() + "'"); + } + if (tok.kind != Token::Kind::StatementClose) { + throw_parser_error("expected statement close, got '" + tok.describe() + "'"); + } + } break; + case Token::Kind::LineStatementOpen: { + get_next_token(); + if (!parse_statement(tmpl, Token::Kind::LineStatementClose, path)) { + throw_parser_error("expected statement, got '" + tok.describe() + "'"); + } + if (tok.kind != Token::Kind::LineStatementClose && tok.kind != Token::Kind::Eof) { + throw_parser_error("expected line statement close, got '" + tok.describe() + "'"); + } + } break; + case Token::Kind::ExpressionOpen: { + get_next_token(); + + auto expression_list_node = std::make_shared(tok.text.data() - tmpl.content.c_str()); + current_block->nodes.emplace_back(expression_list_node); + current_expression_list = expression_list_node.get(); + + if (!parse_expression(tmpl, Token::Kind::ExpressionClose)) { + throw_parser_error("expected expression, got '" + tok.describe() + "'"); + } + + if (tok.kind != Token::Kind::ExpressionClose) { + throw_parser_error("expected expression close, got '" + tok.describe() + "'"); + } + } break; + case Token::Kind::CommentOpen: { + get_next_token(); + if (tok.kind != Token::Kind::CommentClose) { + throw_parser_error("expected comment close, got '" + tok.describe() + "'"); + } + } break; + default: { + throw_parser_error("unexpected token '" + tok.describe() + "'"); + } break; + } + } + } + +public: + explicit Parser(const ParserConfig& parser_config, const LexerConfig& lexer_config, TemplateStorage& template_storage, + const FunctionStorage& function_storage) + : config(parser_config), lexer(lexer_config), template_storage(template_storage), function_storage(function_storage) {} + + Template parse(std::string_view input, std::string_view path) { + auto result = Template(static_cast(input)); + parse_into(result, path); + return result; + } + + Template parse(std::string_view input) { + return parse(input, "./"); + } + + void parse_into_template(Template& tmpl, std::string_view filename) { + std::string_view path = filename.substr(0, filename.find_last_of("/\\") + 1); + + // StringRef path = sys::path::parent_path(filename); + auto sub_parser = Parser(config, lexer.get_config(), template_storage, function_storage); + sub_parser.parse_into(tmpl, path); + } + + std::string load_file(const std::string& filename) { + std::ifstream file; + file.open(filename); + if (file.fail()) { + INJA_THROW(FileError("failed accessing file at '" + filename + "'")); + } + std::string text((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + return text; + } +}; + +} // namespace inja + +#endif // INCLUDE_INJA_PARSER_HPP_ + +// #include "renderer.hpp" +#ifndef INCLUDE_INJA_RENDERER_HPP_ +#define INCLUDE_INJA_RENDERER_HPP_ + +#include +#include +#include +#include +#include + +// #include "config.hpp" + +// #include "exceptions.hpp" + +// #include "node.hpp" + +// #include "template.hpp" + +// #include "utils.hpp" + + +namespace inja { + +/*! + * \brief Class for rendering a Template with data. + */ +class Renderer : public NodeVisitor { + using Op = FunctionStorage::Operation; + + const RenderConfig config; + const TemplateStorage& template_storage; + const FunctionStorage& function_storage; + + const Template* current_template; + size_t current_level {0}; + std::vector template_stack; + std::vector block_statement_stack; + + const json* data_input; + std::ostream* output_stream; + + json additional_data; + json* current_loop_data = &additional_data["loop"]; + + std::vector> data_tmp_stack; + std::stack data_eval_stack; + std::stack not_found_stack; + + bool break_rendering {false}; + + static bool truthy(const json* data) { + if (data->is_boolean()) { + return data->get(); + } else if (data->is_number()) { + return (*data != 0); + } else if (data->is_null()) { + return false; + } + return !data->empty(); + } + + void print_data(const std::shared_ptr value) { + if (value->is_string()) { + *output_stream << value->get_ref(); + } else if (value->is_number_integer()) { + *output_stream << value->get(); + } else if (value->is_null()) { + } else { + *output_stream << value->dump(); + } + } + + const std::shared_ptr eval_expression_list(const ExpressionListNode& expression_list) { + if (!expression_list.root) { + throw_renderer_error("empty expression", expression_list); + } + + expression_list.root->accept(*this); + + if (data_eval_stack.empty()) { + throw_renderer_error("empty expression", expression_list); + } else if (data_eval_stack.size() != 1) { + throw_renderer_error("malformed expression", expression_list); + } + + const auto result = data_eval_stack.top(); + data_eval_stack.pop(); + + if (!result) { + if (not_found_stack.empty()) { + throw_renderer_error("expression could not be evaluated", expression_list); + } + + auto node = not_found_stack.top(); + not_found_stack.pop(); + + throw_renderer_error("variable '" + static_cast(node->name) + "' not found", *node); + } + return std::make_shared(*result); + } + + void throw_renderer_error(const std::string& message, const AstNode& node) { + SourceLocation loc = get_source_location(current_template->content, node.pos); + INJA_THROW(RenderError(message, loc)); + } + + void make_result(const json&& result) { + auto result_ptr = std::make_shared(result); + data_tmp_stack.push_back(result_ptr); + data_eval_stack.push(result_ptr.get()); + } + + template std::array get_arguments(const FunctionNode& node) { + if (node.arguments.size() < N_start + N) { + throw_renderer_error("function needs " + std::to_string(N_start + N) + " variables, but has only found " + std::to_string(node.arguments.size()), node); + } + + for (size_t i = N_start; i < N_start + N; i += 1) { + node.arguments[i]->accept(*this); + } + + if (data_eval_stack.size() < N) { + throw_renderer_error("function needs " + std::to_string(N) + " variables, but has only found " + std::to_string(data_eval_stack.size()), node); + } + + std::array result; + for (size_t i = 0; i < N; i += 1) { + result[N - i - 1] = data_eval_stack.top(); + data_eval_stack.pop(); + + if (!result[N - i - 1]) { + const auto data_node = not_found_stack.top(); + not_found_stack.pop(); + + if (throw_not_found) { + throw_renderer_error("variable '" + static_cast(data_node->name) + "' not found", *data_node); + } + } + } + return result; + } + + template Arguments get_argument_vector(const FunctionNode& node) { + const size_t N = node.arguments.size(); + for (auto a : node.arguments) { + a->accept(*this); + } + + if (data_eval_stack.size() < N) { + throw_renderer_error("function needs " + std::to_string(N) + " variables, but has only found " + std::to_string(data_eval_stack.size()), node); + } + + Arguments result {N}; + for (size_t i = 0; i < N; i += 1) { + result[N - i - 1] = data_eval_stack.top(); + data_eval_stack.pop(); + + if (!result[N - i - 1]) { + const auto data_node = not_found_stack.top(); + not_found_stack.pop(); + + if (throw_not_found) { + throw_renderer_error("variable '" + static_cast(data_node->name) + "' not found", *data_node); + } + } + } + return result; + } + + void visit(const BlockNode& node) { + for (auto& n : node.nodes) { + n->accept(*this); + + if (break_rendering) { + break; + } + } + } + + void visit(const TextNode& node) { + output_stream->write(current_template->content.c_str() + node.pos, node.length); + } + + void visit(const ExpressionNode&) {} + + void visit(const LiteralNode& node) { + data_eval_stack.push(&node.value); + } + + void visit(const DataNode& node) { + if (additional_data.contains(node.ptr)) { + data_eval_stack.push(&(additional_data[node.ptr])); + } else if (data_input->contains(node.ptr)) { + data_eval_stack.push(&(*data_input)[node.ptr]); + } else { + // Try to evaluate as a no-argument callback + const auto function_data = function_storage.find_function(node.name, 0); + if (function_data.operation == FunctionStorage::Operation::Callback) { + Arguments empty_args {}; + const auto value = std::make_shared(function_data.callback(empty_args)); + data_tmp_stack.push_back(value); + data_eval_stack.push(value.get()); + } else { + data_eval_stack.push(nullptr); + not_found_stack.emplace(&node); + } + } + } + + void visit(const FunctionNode& node) { + switch (node.operation) { + case Op::Not: { + const auto args = get_arguments<1>(node); + make_result(!truthy(args[0])); + } break; + case Op::And: { + make_result(truthy(get_arguments<1, 0>(node)[0]) && truthy(get_arguments<1, 1>(node)[0])); + } break; + case Op::Or: { + make_result(truthy(get_arguments<1, 0>(node)[0]) || truthy(get_arguments<1, 1>(node)[0])); + } break; + case Op::In: { + const auto args = get_arguments<2>(node); + make_result(std::find(args[1]->begin(), args[1]->end(), *args[0]) != args[1]->end()); + } break; + case Op::Equal: { + const auto args = get_arguments<2>(node); + make_result(*args[0] == *args[1]); + } break; + case Op::NotEqual: { + const auto args = get_arguments<2>(node); + make_result(*args[0] != *args[1]); + } break; + case Op::Greater: { + const auto args = get_arguments<2>(node); + make_result(*args[0] > *args[1]); + } break; + case Op::GreaterEqual: { + const auto args = get_arguments<2>(node); + make_result(*args[0] >= *args[1]); + } break; + case Op::Less: { + const auto args = get_arguments<2>(node); + make_result(*args[0] < *args[1]); + } break; + case Op::LessEqual: { + const auto args = get_arguments<2>(node); + make_result(*args[0] <= *args[1]); + } break; + case Op::Add: { + const auto args = get_arguments<2>(node); + if (args[0]->is_string() && args[1]->is_string()) { + make_result(args[0]->get_ref() + args[1]->get_ref()); + } else if (args[0]->is_number_integer() && args[1]->is_number_integer()) { + make_result(args[0]->get() + args[1]->get()); + } else { + make_result(args[0]->get() + args[1]->get()); + } + } break; + case Op::Subtract: { + const auto args = get_arguments<2>(node); + if (args[0]->is_number_integer() && args[1]->is_number_integer()) { + make_result(args[0]->get() - args[1]->get()); + } else { + make_result(args[0]->get() - args[1]->get()); + } + } break; + case Op::Multiplication: { + const auto args = get_arguments<2>(node); + if (args[0]->is_number_integer() && args[1]->is_number_integer()) { + make_result(args[0]->get() * args[1]->get()); + } else { + make_result(args[0]->get() * args[1]->get()); + } + } break; + case Op::Division: { + const auto args = get_arguments<2>(node); + if (args[1]->get() == 0) { + throw_renderer_error("division by zero", node); + } + make_result(args[0]->get() / args[1]->get()); + } break; + case Op::Power: { + const auto args = get_arguments<2>(node); + if (args[0]->is_number_integer() && args[1]->get() >= 0) { + int result = static_cast(std::pow(args[0]->get(), args[1]->get())); + make_result(result); + } else { + double result = std::pow(args[0]->get(), args[1]->get()); + make_result(result); + } + } break; + case Op::Modulo: { + const auto args = get_arguments<2>(node); + make_result(args[0]->get() % args[1]->get()); + } break; + case Op::AtId: { + const auto container = get_arguments<1, 0, false>(node)[0]; + node.arguments[1]->accept(*this); + if (not_found_stack.empty()) { + throw_renderer_error("could not find element with given name", node); + } + const auto id_node = not_found_stack.top(); + not_found_stack.pop(); + data_eval_stack.pop(); + data_eval_stack.push(&container->at(id_node->name)); + } break; + case Op::At: { + const auto args = get_arguments<2>(node); + if (args[0]->is_object()) { + data_eval_stack.push(&args[0]->at(args[1]->get())); + } else { + data_eval_stack.push(&args[0]->at(args[1]->get())); + } + } break; + case Op::Default: { + const auto test_arg = get_arguments<1, 0, false>(node)[0]; + data_eval_stack.push(test_arg ? test_arg : get_arguments<1, 1>(node)[0]); + } break; + case Op::DivisibleBy: { + const auto args = get_arguments<2>(node); + const int divisor = args[1]->get(); + make_result((divisor != 0) && (args[0]->get() % divisor == 0)); + } break; + case Op::Even: { + make_result(get_arguments<1>(node)[0]->get() % 2 == 0); + } break; + case Op::Exists: { + auto&& name = get_arguments<1>(node)[0]->get_ref(); + make_result(data_input->contains(json::json_pointer(DataNode::convert_dot_to_ptr(name)))); + } break; + case Op::ExistsInObject: { + const auto args = get_arguments<2>(node); + auto&& name = args[1]->get_ref(); + make_result(args[0]->find(name) != args[0]->end()); + } break; + case Op::First: { + const auto result = &get_arguments<1>(node)[0]->front(); + data_eval_stack.push(result); + } break; + case Op::Float: { + make_result(std::stod(get_arguments<1>(node)[0]->get_ref())); + } break; + case Op::Int: { + make_result(std::stoi(get_arguments<1>(node)[0]->get_ref())); + } break; + case Op::Last: { + const auto result = &get_arguments<1>(node)[0]->back(); + data_eval_stack.push(result); + } break; + case Op::Length: { + const auto val = get_arguments<1>(node)[0]; + if (val->is_string()) { + make_result(val->get_ref().length()); + } else { + make_result(val->size()); + } + } break; + case Op::Lower: { + std::string result = get_arguments<1>(node)[0]->get(); + std::transform(result.begin(), result.end(), result.begin(), ::tolower); + make_result(std::move(result)); + } break; + case Op::Max: { + const auto args = get_arguments<1>(node); + const auto result = std::max_element(args[0]->begin(), args[0]->end()); + data_eval_stack.push(&(*result)); + } break; + case Op::Min: { + const auto args = get_arguments<1>(node); + const auto result = std::min_element(args[0]->begin(), args[0]->end()); + data_eval_stack.push(&(*result)); + } break; + case Op::Odd: { + make_result(get_arguments<1>(node)[0]->get() % 2 != 0); + } break; + case Op::Range: { + std::vector result(get_arguments<1>(node)[0]->get()); + std::iota(result.begin(), result.end(), 0); + make_result(std::move(result)); + } break; + case Op::Round: { + const auto args = get_arguments<2>(node); + const int precision = args[1]->get(); + const double result = std::round(args[0]->get() * std::pow(10.0, precision)) / std::pow(10.0, precision); + if (precision == 0) { + make_result(int(result)); + } else { + make_result(result); + } + } break; + case Op::Sort: { + auto result_ptr = std::make_shared(get_arguments<1>(node)[0]->get>()); + std::sort(result_ptr->begin(), result_ptr->end()); + data_tmp_stack.push_back(result_ptr); + data_eval_stack.push(result_ptr.get()); + } break; + case Op::Upper: { + std::string result = get_arguments<1>(node)[0]->get(); + std::transform(result.begin(), result.end(), result.begin(), ::toupper); + make_result(std::move(result)); + } break; + case Op::IsBoolean: { + make_result(get_arguments<1>(node)[0]->is_boolean()); + } break; + case Op::IsNumber: { + make_result(get_arguments<1>(node)[0]->is_number()); + } break; + case Op::IsInteger: { + make_result(get_arguments<1>(node)[0]->is_number_integer()); + } break; + case Op::IsFloat: { + make_result(get_arguments<1>(node)[0]->is_number_float()); + } break; + case Op::IsObject: { + make_result(get_arguments<1>(node)[0]->is_object()); + } break; + case Op::IsArray: { + make_result(get_arguments<1>(node)[0]->is_array()); + } break; + case Op::IsString: { + make_result(get_arguments<1>(node)[0]->is_string()); + } break; + case Op::Callback: { + auto args = get_argument_vector(node); + make_result(node.callback(args)); + } break; + case Op::Super: { + const auto args = get_argument_vector(node); + const size_t old_level = current_level; + const size_t level_diff = (args.size() == 1) ? args[0]->get() : 1; + const size_t level = current_level + level_diff; + + if (block_statement_stack.empty()) { + throw_renderer_error("super() call is not within a block", node); + } + + if (level < 1 || level > template_stack.size() - 1) { + throw_renderer_error("level of super() call does not match parent templates (between 1 and " + std::to_string(template_stack.size() - 1) + ")", node); + } + + const auto current_block_statement = block_statement_stack.back(); + const Template* new_template = template_stack.at(level); + const Template* old_template = current_template; + const auto block_it = new_template->block_storage.find(current_block_statement->name); + if (block_it != new_template->block_storage.end()) { + current_template = new_template; + current_level = level; + block_it->second->block.accept(*this); + current_level = old_level; + current_template = old_template; + } else { + throw_renderer_error("could not find block with name '" + current_block_statement->name + "'", node); + } + make_result(nullptr); + } break; + case Op::Join: { + const auto args = get_arguments<2>(node); + const auto separator = args[1]->get(); + std::ostringstream os; + std::string sep; + for (const auto& value : *args[0]) { + os << sep; + if (value.is_string()) { + os << value.get(); // otherwise the value is surrounded with "" + } else { + os << value.dump(); + } + sep = separator; + } + make_result(os.str()); + } break; + case Op::ParenLeft: + case Op::ParenRight: + case Op::None: + break; + } + } + + void visit(const ExpressionListNode& node) { + print_data(eval_expression_list(node)); + } + + void visit(const StatementNode&) {} + + void visit(const ForStatementNode&) {} + + void visit(const ForArrayStatementNode& node) { + const auto result = eval_expression_list(node.condition); + if (!result->is_array()) { + throw_renderer_error("object must be an array", node); + } + + if (!current_loop_data->empty()) { + auto tmp = *current_loop_data; // Because of clang-3 + (*current_loop_data)["parent"] = std::move(tmp); + } + + size_t index = 0; + (*current_loop_data)["is_first"] = true; + (*current_loop_data)["is_last"] = (result->size() <= 1); + for (auto it = result->begin(); it != result->end(); ++it) { + additional_data[static_cast(node.value)] = *it; + + (*current_loop_data)["index"] = index; + (*current_loop_data)["index1"] = index + 1; + if (index == 1) { + (*current_loop_data)["is_first"] = false; + } + if (index == result->size() - 1) { + (*current_loop_data)["is_last"] = true; + } + + node.body.accept(*this); + ++index; + } + + additional_data[static_cast(node.value)].clear(); + if (!(*current_loop_data)["parent"].empty()) { + const auto tmp = (*current_loop_data)["parent"]; + *current_loop_data = std::move(tmp); + } else { + current_loop_data = &additional_data["loop"]; + } + } + + void visit(const ForObjectStatementNode& node) { + const auto result = eval_expression_list(node.condition); + if (!result->is_object()) { + throw_renderer_error("object must be an object", node); + } + + if (!current_loop_data->empty()) { + (*current_loop_data)["parent"] = std::move(*current_loop_data); + } + + size_t index = 0; + (*current_loop_data)["is_first"] = true; + (*current_loop_data)["is_last"] = (result->size() <= 1); + for (auto it = result->begin(); it != result->end(); ++it) { + additional_data[static_cast(node.key)] = it.key(); + additional_data[static_cast(node.value)] = it.value(); + + (*current_loop_data)["index"] = index; + (*current_loop_data)["index1"] = index + 1; + if (index == 1) { + (*current_loop_data)["is_first"] = false; + } + if (index == result->size() - 1) { + (*current_loop_data)["is_last"] = true; + } + + node.body.accept(*this); + ++index; + } + + additional_data[static_cast(node.key)].clear(); + additional_data[static_cast(node.value)].clear(); + if (!(*current_loop_data)["parent"].empty()) { + *current_loop_data = std::move((*current_loop_data)["parent"]); + } else { + current_loop_data = &additional_data["loop"]; + } + } + + void visit(const IfStatementNode& node) { + const auto result = eval_expression_list(node.condition); + if (truthy(result.get())) { + node.true_statement.accept(*this); + } else if (node.has_false_statement) { + node.false_statement.accept(*this); + } + } + + void visit(const IncludeStatementNode& node) { + auto sub_renderer = Renderer(config, template_storage, function_storage); + const auto included_template_it = template_storage.find(node.file); + if (included_template_it != template_storage.end()) { + sub_renderer.render_to(*output_stream, included_template_it->second, *data_input, &additional_data); + } else if (config.throw_at_missing_includes) { + throw_renderer_error("include '" + node.file + "' not found", node); + } + } + + void visit(const ExtendsStatementNode& node) { + const auto included_template_it = template_storage.find(node.file); + if (included_template_it != template_storage.end()) { + const Template* parent_template = &included_template_it->second; + render_to(*output_stream, *parent_template, *data_input, &additional_data); + break_rendering = true; + } else if (config.throw_at_missing_includes) { + throw_renderer_error("extends '" + node.file + "' not found", node); + } + } + + void visit(const BlockStatementNode& node) { + const size_t old_level = current_level; + current_level = 0; + current_template = template_stack.front(); + const auto block_it = current_template->block_storage.find(node.name); + if (block_it != current_template->block_storage.end()) { + block_statement_stack.emplace_back(&node); + block_it->second->block.accept(*this); + block_statement_stack.pop_back(); + } + current_level = old_level; + current_template = template_stack.back(); + } + + void visit(const SetStatementNode& node) { + std::string ptr = node.key; + replace_substring(ptr, ".", "/"); + ptr = "/" + ptr; + additional_data[json::json_pointer(ptr)] = *eval_expression_list(node.expression); + } + +public: + Renderer(const RenderConfig& config, const TemplateStorage& template_storage, const FunctionStorage& function_storage) + : config(config), template_storage(template_storage), function_storage(function_storage) {} + + void render_to(std::ostream& os, const Template& tmpl, const json& data, json* loop_data = nullptr) { + output_stream = &os; + current_template = &tmpl; + data_input = &data; + if (loop_data) { + additional_data = *loop_data; + current_loop_data = &additional_data["loop"]; + } + + template_stack.emplace_back(current_template); + current_template->root.accept(*this); + + data_tmp_stack.clear(); + } +}; + +} // namespace inja + +#endif // INCLUDE_INJA_RENDERER_HPP_ + +// #include "template.hpp" + +// #include "utils.hpp" + + +namespace inja { + +/*! + * \brief Class for changing the configuration. + */ +class Environment { + std::string input_path; + std::string output_path; + + LexerConfig lexer_config; + ParserConfig parser_config; + RenderConfig render_config; + + FunctionStorage function_storage; + TemplateStorage template_storage; + +public: + Environment(): Environment("") {} + + explicit Environment(const std::string& global_path): input_path(global_path), output_path(global_path) {} + + Environment(const std::string& input_path, const std::string& output_path): input_path(input_path), output_path(output_path) {} + + /// Sets the opener and closer for template statements + void set_statement(const std::string& open, const std::string& close) { + lexer_config.statement_open = open; + lexer_config.statement_open_no_lstrip = open + "+"; + lexer_config.statement_open_force_lstrip = open + "-"; + lexer_config.statement_close = close; + lexer_config.statement_close_force_rstrip = "-" + close; + lexer_config.update_open_chars(); + } + + /// Sets the opener for template line statements + void set_line_statement(const std::string& open) { + lexer_config.line_statement = open; + lexer_config.update_open_chars(); + } + + /// Sets the opener and closer for template expressions + void set_expression(const std::string& open, const std::string& close) { + lexer_config.expression_open = open; + lexer_config.expression_open_force_lstrip = open + "-"; + lexer_config.expression_close = close; + lexer_config.expression_close_force_rstrip = "-" + close; + lexer_config.update_open_chars(); + } + + /// Sets the opener and closer for template comments + void set_comment(const std::string& open, const std::string& close) { + lexer_config.comment_open = open; + lexer_config.comment_open_force_lstrip = open + "-"; + lexer_config.comment_close = close; + lexer_config.comment_close_force_rstrip = "-" + close; + lexer_config.update_open_chars(); + } + + /// Sets whether to remove the first newline after a block + void set_trim_blocks(bool trim_blocks) { + lexer_config.trim_blocks = trim_blocks; + } + + /// Sets whether to strip the spaces and tabs from the start of a line to a block + void set_lstrip_blocks(bool lstrip_blocks) { + lexer_config.lstrip_blocks = lstrip_blocks; + } + + /// Sets the element notation syntax + void set_search_included_templates_in_files(bool search_in_files) { + parser_config.search_included_templates_in_files = search_in_files; + } + + /// Sets whether a missing include will throw an error + void set_throw_at_missing_includes(bool will_throw) { + render_config.throw_at_missing_includes = will_throw; + } + + Template parse(std::string_view input) { + Parser parser(parser_config, lexer_config, template_storage, function_storage); + return parser.parse(input); + } + + Template parse_template(const std::string& filename) { + Parser parser(parser_config, lexer_config, template_storage, function_storage); + auto result = Template(parser.load_file(input_path + static_cast(filename))); + parser.parse_into_template(result, input_path + static_cast(filename)); + return result; + } + + Template parse_file(const std::string& filename) { + return parse_template(filename); + } + + std::string render(std::string_view input, const json& data) { + return render(parse(input), data); + } + + std::string render(const Template& tmpl, const json& data) { + std::stringstream os; + render_to(os, tmpl, data); + return os.str(); + } + + std::string render_file(const std::string& filename, const json& data) { + return render(parse_template(filename), data); + } + + std::string render_file_with_json_file(const std::string& filename, const std::string& filename_data) { + const json data = load_json(filename_data); + return render_file(filename, data); + } + + void write(const std::string& filename, const json& data, const std::string& filename_out) { + std::ofstream file(output_path + filename_out); + file << render_file(filename, data); + file.close(); + } + + void write(const Template& temp, const json& data, const std::string& filename_out) { + std::ofstream file(output_path + filename_out); + file << render(temp, data); + file.close(); + } + + void write_with_json_file(const std::string& filename, const std::string& filename_data, const std::string& filename_out) { + const json data = load_json(filename_data); + write(filename, data, filename_out); + } + + void write_with_json_file(const Template& temp, const std::string& filename_data, const std::string& filename_out) { + const json data = load_json(filename_data); + write(temp, data, filename_out); + } + + std::ostream& render_to(std::ostream& os, const Template& tmpl, const json& data) { + Renderer(render_config, template_storage, function_storage).render_to(os, tmpl, data); + return os; + } + + std::string load_file(const std::string& filename) { + Parser parser(parser_config, lexer_config, template_storage, function_storage); + return parser.load_file(input_path + filename); + } + + json load_json(const std::string& filename) { + std::ifstream file; + file.open(input_path + filename); + if (file.fail()) { + INJA_THROW(FileError("failed accessing file at '" + input_path + filename + "'")); + } + + return json::parse(std::istreambuf_iterator(file), std::istreambuf_iterator()); + } + + /*! + @brief Adds a variadic callback + */ + void add_callback(const std::string& name, const CallbackFunction& callback) { + add_callback(name, -1, callback); + } + + /*! + @brief Adds a variadic void callback + */ + void add_void_callback(const std::string& name, const VoidCallbackFunction& callback) { + add_void_callback(name, -1, callback); + } + + /*! + @brief Adds a callback with given number or arguments + */ + void add_callback(const std::string& name, int num_args, const CallbackFunction& callback) { + function_storage.add_callback(name, num_args, callback); + } + + /*! + @brief Adds a void callback with given number or arguments + */ + void add_void_callback(const std::string& name, int num_args, const VoidCallbackFunction& callback) { + function_storage.add_callback(name, num_args, [callback](Arguments& args) { + callback(args); + return json(); + }); + } + + /** Includes a template with a given name into the environment. + * Then, a template can be rendered in another template using the + * include "" syntax. + */ + void include_template(const std::string& name, const Template& tmpl) { + template_storage[name] = tmpl; + } + + /*! + @brief Sets a function that is called when an included file is not found + */ + void set_include_callback(const std::function& callback) { + parser_config.include_callback = callback; + } +}; + +/*! +@brief render with default settings to a string +*/ +inline std::string render(std::string_view input, const json& data) { + return Environment().render(input, data); +} + +/*! +@brief render with default settings to the given output stream +*/ +inline void render_to(std::ostream& os, std::string_view input, const json& data) { + Environment env; + env.render_to(os, env.parse(input), data); +} + +} // namespace inja + +#endif // INCLUDE_INJA_ENVIRONMENT_HPP_ + +// #include "exceptions.hpp" + +// #include "parser.hpp" + +// #include "renderer.hpp" + +// #include "template.hpp" + + +#endif // INCLUDE_INJA_INJA_HPP_ diff --git a/ext/installfiles/linux/zerotier-containerized/Dockerfile b/ext/installfiles/linux/zerotier-containerized/Dockerfile new file mode 100644 index 0000000..7758faf --- /dev/null +++ b/ext/installfiles/linux/zerotier-containerized/Dockerfile @@ -0,0 +1,28 @@ +## NOTE: to retain configuration; mount a Docker volume, or use a bind-mount, on /var/lib/zerotier-one + +FROM debian:buster-slim as builder + +## Supports x86_64, x86, arm, and arm64 + +RUN apt-get update && apt-get install -y curl gnupg +RUN apt-key adv --keyserver pgp.mit.edu --recv-keys 0x1657198823e52a61 && \ + echo "deb http://download.zerotier.com/debian/buster buster main" > /etc/apt/sources.list.d/zerotier.list +RUN apt-get update && apt-get install -y zerotier-one=1.8.6 +COPY ext/installfiles/linux/zerotier-containerized/main.sh /var/lib/zerotier-one/main.sh + +FROM debian:buster-slim +LABEL version="1.8.6" +LABEL description="Containerized ZeroTier One for use on CoreOS or other Docker-only Linux hosts." + +# ZeroTier relies on UDP port 9993 +EXPOSE 9993/udp + +RUN mkdir -p /var/lib/zerotier-one +COPY --from=builder /usr/sbin/zerotier-cli /usr/sbin/zerotier-cli +COPY --from=builder /usr/sbin/zerotier-idtool /usr/sbin/zerotier-idtool +COPY --from=builder /usr/sbin/zerotier-one /usr/sbin/zerotier-one +COPY --from=builder /var/lib/zerotier-one/main.sh /main.sh + +RUN chmod 0755 /main.sh +ENTRYPOINT ["/main.sh"] +CMD ["zerotier-one"] diff --git a/ext/installfiles/linux/zerotier-containerized/main.sh b/ext/installfiles/linux/zerotier-containerized/main.sh new file mode 100755 index 0000000..a338903 --- /dev/null +++ b/ext/installfiles/linux/zerotier-containerized/main.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin + +if [ ! -e /dev/net/tun ]; then + echo 'FATAL: cannot start ZeroTier One in container: /dev/net/tun not present.' + exit 1 +fi + +exec "$@" diff --git a/ext/installfiles/linux/zerotier-one.init.rhel6 b/ext/installfiles/linux/zerotier-one.init.rhel6 new file mode 100755 index 0000000..3ff2f18 --- /dev/null +++ b/ext/installfiles/linux/zerotier-one.init.rhel6 @@ -0,0 +1,138 @@ +#!/bin/bash +# +# zerotier-one Start the ZeroTier One network virtualization service +# +# chkconfig: 2345 55 25 +# description: ZeroTier One allows systems to join and participate in \ +# ZeroTier virtual networks. See https://www.zerotier.com/ +# +# processname: zerotier-one +# config: /var/lib/zerotier-one/identity.public +# config: /var/lib/zerotier-one/identity.secret +# config: /var/lib/zerotier-one/local.conf +# config: /var/lib/zerotier-one/authtoken.secret +# pidfile: /var/lib/zerotier-one/zerotier-one.pid + +### BEGIN INIT INFO +# Provides: zerotier-one +# Required-Start: $local_fs $network $syslog +# Required-Stop: $local_fs $syslog +# Should-Start: $syslog +# Should-Stop: $network $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start the ZeroTier One network virtualization service +# Description: ZeroTier One allows systems to join and participate in +# ZeroTier virtual networks. See https://www.zerotier.com/ +### END INIT INFO + +# source function library +. /etc/rc.d/init.d/functions + +# pull in sysconfig settings +[ -f /etc/sysconfig/zerotier-one ] && . /etc/sysconfig/zerotier-one + +RETVAL=0 +prog="zerotier-one" +lockfile=/var/lock/subsys/$prog +ZT="/usr/sbin/zerotier-one" +PID_FILE=/var/lib/zerotier-one/zerotier-one.pid + +runlevel=$(set -- $(runlevel); eval "echo \$$#" ) + +start() +{ + [ -x $ZT ] || exit 5 + echo -n $"Starting $prog: " + $ZT $ZT_OPTIONS -d && success || failure + RETVAL=$? + [ $RETVAL -eq 0 ] && touch $lockfile + echo + return $RETVAL +} + +stop() +{ + echo -n $"Stopping $prog: " + killproc -p $PID_FILE $ZT + RETVAL=$? + if [ "x$runlevel" = x0 -o "x$runlevel" = x6 ] ; then + trap '' TERM + killall $prog 2>/dev/null + trap TERM + fi + [ $RETVAL -eq 0 ] && rm -f $lockfile + echo +} + +reload() +{ + stop + start +} + +restart() { + stop + start +} + +force_reload() { + restart +} + +rh_status() { + status -p $PID_FILE zerotier-one +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + +case "$1" in + start) + rh_status_q && exit 0 + start + ;; + stop) + if ! rh_status_q; then + rm -f $lockfile + exit 0 + fi + stop + ;; + restart) + restart + ;; + reload) + rh_status_q || exit 7 + reload + ;; + force-reload) + force_reload + ;; + condrestart|try-restart) + rh_status_q || exit 0 + if [ -f $lockfile ] ; then + do_restart_sanity_check + if [ $RETVAL -eq 0 ] ; then + stop + # avoid race + sleep 3 + start + else + RETVAL=6 + fi + fi + ;; + status) + rh_status + RETVAL=$? + if [ $RETVAL -eq 3 -a -f $lockfile ] ; then + RETVAL=2 + fi + ;; + *) + echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}" + RETVAL=2 +esac +exit $RETVAL diff --git a/ext/installfiles/linux/zerotier-one.te b/ext/installfiles/linux/zerotier-one.te new file mode 100644 index 0000000..978df0b --- /dev/null +++ b/ext/installfiles/linux/zerotier-one.te @@ -0,0 +1,14 @@ + +module zerotier-one 1.0; + +require { + type unconfined_t; + type initrc_t; + class memprotect mmap_zero; +} + +#============= initrc_t ============== +allow initrc_t self:memprotect mmap_zero; + +#============= unconfined_t ============== +allow unconfined_t self:memprotect mmap_zero; diff --git a/ext/installfiles/mac-update/updater.tmpl.sh b/ext/installfiles/mac-update/updater.tmpl.sh new file mode 100644 index 0000000..867792e --- /dev/null +++ b/ext/installfiles/mac-update/updater.tmpl.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin:/sbin:/usr/sbin +shopt -s expand_aliases + +if [ "$UID" -ne 0 ]; then + echo '*** Auto-updater must be run as root.' + exit 1 +fi + +scriptPath="`dirname "$0"`/`basename "$0"`" +if [ ! -s "$scriptPath" ]; then + scriptPath="$0" + if [ ! -s "$scriptPath" ]; then + echo "*** Auto-updater cannot determine its own path; $scriptPath is not readable." + exit 2 + fi +fi + +endMarkerIndex=`grep -a -b -E '^################' "$scriptPath" | head -c 16 | cut -d : -f 1` +if [ "$endMarkerIndex" -le 100 ]; then + echo 'Internal error: unable to find end of script / start of binary data marker.' + exit 2 +fi +blobStart=`expr $endMarkerIndex + 17` +if [ "$blobStart" -le "$endMarkerIndex" ]; then + echo 'Internal error: unable to find end of script / start of binary data marker.' + exit 2 +fi + +rm -f /tmp/BackOne-update.pkg +tail -c +$blobStart "$scriptPath" >/tmp/BackOne-update.pkg +chmod 0600 /tmp/BackOne-update.pkg + +if [ -s /tmp/BackOne-update.pkg ]; then + rm -f '/Library/Application Support/BackOne/latest-update.exe' '/Library/Application Support/BackOne/latest-update.json' /tmp/BackOne-update.log + installer -verbose -pkg /tmp/BackOne-update.pkg -target / >/tmp/BackOne-update.log 2>&1 + rm -f /tmp/BackOne-update.pkg + exit 0 +else + echo '*** Error self-unpacking update!' + exit 3 +fi + +# Do not remove the last line or add a carriage return to it! The installer +# looks for an unterminated line beginning with 16 #'s in itself to find +# the binary blob data, which is appended after it. + +################ diff --git a/ext/installfiles/mac/BackOne.pkgproj b/ext/installfiles/mac/BackOne.pkgproj new file mode 100755 index 0000000..3920a1d --- /dev/null +++ b/ext/installfiles/mac/BackOne.pkgproj @@ -0,0 +1,1119 @@ + + + + + PACKAGES + + + MUST-CLOSE-APPLICATION-ITEMS + + MUST-CLOSE-APPLICATIONS + + PACKAGE_FILES + + DEFAULT_INSTALL_LOCATION + / + HIERARCHY + + CHILDREN + + + CHILDREN + + + CHILDREN + + GID + 80 + PATH + Utilities + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + BUNDLE_CAN_DOWNGRADE + + BUNDLE_POSTINSTALL_PATH + + PATH_TYPE + 0 + + BUNDLE_PREINSTALL_PATH + + PATH_TYPE + 0 + + CHILDREN + + GID + 80 + PATH + ../../../../DesktopUI/BackOne.app + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + GID + 80 + PATH + Applications + PATH_TYPE + 0 + PERMISSIONS + 509 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + + CHILDREN + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + get-proxy-settings.sh + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + launch.sh + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 80 + PATH + ../../../MacEthernetTapAgent + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + uninstall.sh + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + ../../../backone + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + GID + 80 + PATH + + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 2 + UID + 0 + + + GID + 80 + PATH + BackOne + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 2 + UID + 0 + + + GID + 80 + PATH + Application Support + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Automator + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Documentation + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Filesystems + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Frameworks + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Input Methods + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Internet Plug-Ins + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + LaunchAgents + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + com.backone.plist + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + GID + 0 + PATH + LaunchDaemons + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + PreferencePanes + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Preferences + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 80 + PATH + Printers + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + PrivilegedHelperTools + PATH_TYPE + 0 + PERMISSIONS + 1005 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + QuickLook + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + QuickTime + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Screen Savers + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Scripts + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Services + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Widgets + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Extensions + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + Library + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + Extensions + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + Library + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + System + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + Shared + PATH_TYPE + 0 + PERMISSIONS + 1023 + TYPE + 1 + UID + 0 + + + GID + 80 + PATH + Users + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + / + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + PAYLOAD_TYPE + 0 + PRESERVE_EXTENDED_ATTRIBUTES + + SHOW_INVISIBLE + + SPLIT_FORKS + + TREAT_MISSING_FILES_AS_WARNING + + VERSION + 5 + + PACKAGE_SCRIPTS + + POSTINSTALL_PATH + + PATH + postinst.sh + PATH_TYPE + 1 + + PREINSTALL_PATH + + PATH + preinst.sh + PATH_TYPE + 1 + + RESOURCES + + + PACKAGE_SETTINGS + + AUTHENTICATION + 1 + CONCLUSION_ACTION + 0 + FOLLOW_SYMBOLIC_LINKS + + IDENTIFIER + com.backone.pkg.BackOne + LOCATION + 0 + NAME + BackOne + OVERWRITE_PERMISSIONS + + PAYLOAD_SIZE + -1 + REFERENCE_PATH + + RELOCATABLE + + USE_HFS+_COMPRESSION + + VERSION + 1.14.1 + + TYPE + 0 + UUID + 1B6AFC3A-9EA5-4401-83D4-37F06CD13CD6 + + + PROJECT + + PROJECT_COMMENTS + + NOTES + + PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1M + IDQuMDEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQv + c3RyaWN0LmR0ZCI+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1l + cXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7 + IGNoYXJzZXQ9VVRGLTgiPgo8bWV0YSBodHRwLWVxdWl2PSJDb250 + ZW50LVN0eWxlLVR5cGUiIGNvbnRlbnQ9InRleHQvY3NzIj4KPHRp + dGxlPjwvdGl0bGU+CjxtZXRhIG5hbWU9IkdlbmVyYXRvciIgY29u + dGVudD0iQ29jb2EgSFRNTCBXcml0ZXIiPgo8bWV0YSBuYW1lPSJD + b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjE1MDQuNzYiPgo8c3R5bGUg + dHlwZT0idGV4dC9jc3MiPgpwLnAxIHttYXJnaW46IDAuMHB4IDAu + MHB4IDAuMHB4IDAuMHB4OyBsaW5lLWhlaWdodDogMTQuMHB4OyBm + b250OiAxMi4wcHggSGVsdmV0aWNhOyBjb2xvcjogIzAwMDAwMDsg + LXdlYmtpdC10ZXh0LXN0cm9rZTogIzAwMDAwMH0Kc3Bhbi5zMSB7 + Zm9udC1rZXJuaW5nOiBub25lfQo8L3N0eWxlPgo8L2hlYWQ+Cjxi + b2R5Pgo8cCBjbGFzcz0icDEiPjxzcGFuIGNsYXNzPSJzMSI+WmVy + b1RpZXIgT25lIC0gTmV0d29yayBWaXJ0dWFsaXphdGlvbiBFdmVy + eXdoZXJlPC9zcGFuPjwvcD4KPHAgY2xhc3M9InAxIj48c3BhbiBj + bGFzcz0iczEiPihjKTIwMTEtMjAxNyBaZXJvVGllciwgSW5jLjwv + c3Bhbj48L3A+CjxwIGNsYXNzPSJwMSI+PHNwYW4gY2xhc3M9InMx + Ij5jb250YWN0QHplcm90aWVyLmNvbTwvc3Bhbj48L3A+CjxwIGNs + YXNzPSJwMSI+PHNwYW4gY2xhc3M9InMxIj48YnI+Cjwvc3Bhbj48 + L3A+CjxwIGNsYXNzPSJwMSI+PHNwYW4gY2xhc3M9InMxIj5UbyB1 + bmluc3RhbGwgbWFudWFsbHksIHR5cGUgdGhlIGZvbGxvd2luZyBp + biBhIHRlcm1pbmFsIHdpbmRvdzo8L3NwYW4+PC9wPgo8cCBjbGFz + cz0icDEiPjxzcGFuIGNsYXNzPSJzMSI+PGJyPgo8L3NwYW4+PC9w + Pgo8cCBjbGFzcz0icDEiPjxzcGFuIGNsYXNzPSJzMSI+c3VkbyAi + L0xpYnJhcnkvQXBwbGljYXRpb24gU3VwcG9ydC9aZXJvVGllci9P + bmUvdW5pbnN0YWxsLnNoIjwvc3Bhbj48L3A+CjwvYm9keT4KPC9o + dG1sPgo= + + + PROJECT_PRESENTATION + + BACKGROUND + + APPAREANCES + + DARK_AQUA + + LIGHT_AQUA + + + SHARED_SETTINGS_FOR_ALL_APPAREANCES + + + INSTALLATION TYPE + + HIERARCHIES + + INSTALLER + + LIST + + + CHILDREN + + DESCRIPTION + + OPTIONS + + HIDDEN + + STATE + 1 + + PACKAGE_UUID + 1B6AFC3A-9EA5-4401-83D4-37F06CD13CD6 + TITLE + + TYPE + 0 + UUID + 0FC7D07B-9BA9-4711-BB08-A05099C9E2B9 + + + REMOVED + + + + MODE + 0 + + INSTALLATION_STEPS + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewIntroductionController + INSTALLER_PLUGIN + Introduction + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewReadMeController + INSTALLER_PLUGIN + ReadMe + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewLicenseController + INSTALLER_PLUGIN + License + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewDestinationSelectController + INSTALLER_PLUGIN + TargetSelect + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewInstallationTypeController + INSTALLER_PLUGIN + PackageSelection + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewInstallationController + INSTALLER_PLUGIN + Install + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewSummaryController + INSTALLER_PLUGIN + Summary + LIST_TITLE_KEY + InstallerSectionTitle + + + INTRODUCTION + + LOCALIZATIONS + + + LICENSE + + LOCALIZATIONS + + MODE + 0 + + README + + LOCALIZATIONS + + + TITLE + + LOCALIZATIONS + + + + PROJECT_REQUIREMENTS + + LIST + + + BEHAVIOR + 3 + DICTIONARY + + IC_REQUIREMENT_OS_DISK_TYPE + 0 + IC_REQUIREMENT_OS_DISTRIBUTION_TYPE + 0 + IC_REQUIREMENT_OS_MINIMUM_VERSION + 101300 + + IC_REQUIREMENT_CHECK_TYPE + 1 + IDENTIFIER + fr.whitebox.Packages.requirement.os + MESSAGE + + NAME + Operating System + STATE + + + + RESOURCES + + ROOT_VOLUME_ONLY + + + PROJECT_SETTINGS + + ADVANCED_OPTIONS + + installer-script.options:hostArchitectures + + x86_64,arm64 + + + BUILD_FORMAT + 0 + BUILD_PATH + + PATH + ../../.. + PATH_TYPE + 1 + + EXCLUDED_FILES + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + .DS_Store + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove .DS_Store files + PROXY_TOOLTIP + Remove ".DS_Store" files created by the Finder. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + .pbdevelopment + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove .pbdevelopment files + PROXY_TOOLTIP + Remove ".pbdevelopment" files created by ProjectBuilder or Xcode. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + CVS + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .cvsignore + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + .cvspass + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + .svn + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .git + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .gitignore + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove SCM metadata + PROXY_TOOLTIP + Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + classes.nib + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + designable.db + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + info.nib + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Optimize nib files + PROXY_TOOLTIP + Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + Resources Disabled + TYPE + 1 + + + PROTECTED + + PROXY_NAME + Remove Resources Disabled folders + PROXY_TOOLTIP + Remove "Resources Disabled" folders. + STATE + + + + SEPARATOR + + + + NAME + BackOne + PAYLOAD_ONLY + + TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING + + + + SHARED_GLOBAL_DATA + + IC_REQUIREMENT_JAVASCRIPT_SHARED_SOURCE_CODE + + + TYPE + 0 + VERSION + 2 + + diff --git a/ext/installfiles/mac/com.backone.plist b/ext/installfiles/mac/com.backone.plist new file mode 100644 index 0000000..f8f9816 --- /dev/null +++ b/ext/installfiles/mac/com.backone.plist @@ -0,0 +1,22 @@ + + + + + Label + com.backone + UserName + root + ProgramArguments + + /Library/Application Support/BackOne/launch.sh + + WorkingDirectory + /Library/Application Support/BackOne + StandardOutPath + /dev/null + StandardErrorPath + /dev/null + KeepAlive + + + diff --git a/ext/installfiles/mac/get-proxy-settings.sh b/ext/installfiles/mac/get-proxy-settings.sh new file mode 100755 index 0000000..16ba0b4 --- /dev/null +++ b/ext/installfiles/mac/get-proxy-settings.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Outputs host and port for system HTTP proxy or zeroes if none or not +# configured. + +export PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin + +enabled=`system_profiler SPNetworkDataType|grep "HTTP Proxy Enabled"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null` +port=`system_profiler SPNetworkDataType|grep "HTTP Proxy Port"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null` +serv=`system_profiler SPNetworkDataType|grep "HTTP Proxy Server"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null` + +if [ "$enabled" = "Yes" ]; then + if [ "$serv" ]; then + if [ ! "$port" ]; then + port=80 + fi + + echo $serv $port + else + echo 0.0.0.0 0 + fi +else + echo 0.0.0.0 0 +fi + +exit 0 diff --git a/ext/installfiles/mac/launch.sh b/ext/installfiles/mac/launch.sh new file mode 100755 index 0000000..07bbbda --- /dev/null +++ b/ext/installfiles/mac/launch.sh @@ -0,0 +1,4 @@ +#!/bin/bash +export PATH="/Library/Application Support/BackOne:/bin:/usr/bin:/sbin:/usr/sbin" +/usr/bin/killall MacEthernetTapAgent >>/dev/null 2>&1 +exec backone diff --git a/ext/installfiles/mac/postinst.sh b/ext/installfiles/mac/postinst.sh new file mode 100755 index 0000000..33f4776 --- /dev/null +++ b/ext/installfiles/mac/postinst.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin + +cd "/Library/Application Support/BackOne" + +if [ ! -f authtoken.secret ]; then + head -c 1024 /dev/urandom | md5 | head -c 24 >authtoken.secret + chown 0 authtoken.secret + chgrp 0 authtoken.secret + chmod 0600 authtoken.secret +fi + +if [ -f backone.pid ]; then + kill `cat backone.pid` + sleep 1 + killall MacEthernetTapAgent + sleep 1 + killall -9 MacEthernetTapAgent + sleep 1 + if [ -f backone.pid ]; then + kill -9 `cat backone.pid` + rm -f backone.pid + fi +fi +launchctl load /Library/LaunchDaemons/com.backone.plist >>/dev/null 2>&1 +sleep 1 + +rm -f backone-cli backone-idtool +ln -sf backone backone-cli +ln -sf backone backone-idtool +if [ ! -d /usr/local/bin ]; then + mkdir -p /usr/local/bin +fi +cd /usr/local/bin +rm -f backone-cli backone-idtool +ln -sf "/Library/Application Support/BackOne/backone" backone-cli +ln -sf "/Library/Application Support/BackOne/backone" backone-idtool + +if [ -f /tmp/zt1-gui-restart.tmp ]; then + for u in `cat /tmp/zt1-gui-restart.tmp`; do + if [ -f '/Applications/BackOne.app/Contents/MacOS/BackOne' ]; then + su $u -c '/usr/bin/open /Applications/BackOne.app &' >>/dev/null 2>&1 & + else + su $u -c '/usr/bin/open /Applications/BackOne.app &' >>/dev/null 2>&1 & + fi + done +fi +rm -f /tmp/zt1-gui-restart.tmp + +exit 0 diff --git a/ext/installfiles/mac/preinst.sh b/ext/installfiles/mac/preinst.sh new file mode 100755 index 0000000..bf0a0fb --- /dev/null +++ b/ext/installfiles/mac/preinst.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin:/sbin:/usr/sbin + +rm -f /tmp/zt1-gui-restart.tmp +for i in `ps axuwww | tr -s ' ' ',' | grep -F '/Applications/BackOne.app' | grep -F -v grep | cut -d , -f 1,2 | xargs`; do + u=`echo $i | cut -d , -f 1` + p=`echo $i | cut -d , -f 2` + if [ ! -z "$u" -a "0$p" -gt 0 ]; then + kill $p >>/dev/null 2>&1 + sleep 0.5 + kill -9 $p >>/dev/null 2>&1 + echo "$u" >>/tmp/zt1-gui-restart.tmp + fi +done +for i in `ps axuwww | tr -s ' ' ',' | grep -F '/Applications/BackOne.app' | grep -F -v grep | cut -d , -f 1,2 | xargs`; do + u=`echo $i | cut -d , -f 1` + p=`echo $i | cut -d , -f 2` + if [ ! -z "$u" -a "0$p" -gt 0 ]; then + kill $p >>/dev/null 2>&1 + sleep 0.5 + kill -9 $p >>/dev/null 2>&1 + echo "$u" >>/tmp/zt1-gui-restart.tmp + fi +done +chmod 0600 /tmp/zt1-gui-restart.tmp + +cd "/Applications" +rm -rf "BackOne.app" +rm -rf "BackOne.app" + +if [ -d '/Library/Application Support/BackOne' ]; then + cd '/Library/Application Support/BackOne' + # ensure that file locking doesn't cause issues with replacing the binary + rm -f backone + rm -f MacEthernetTapAgent +fi + +exit 0 diff --git a/ext/installfiles/mac/uninstall.sh b/ext/installfiles/mac/uninstall.sh new file mode 100755 index 0000000..90ad8d3 --- /dev/null +++ b/ext/installfiles/mac/uninstall.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +export PATH=/bin:/usr/bin:/sbin:/usr/sbin + +if [ "$UID" -ne 0 ]; then + echo "Must be run as root; try: sudo $0" + exit 1 +fi + +if [ ! -f '/Library/LaunchDaemons/com.backone.plist' ]; then + echo 'BackOne does not seem to be installed.' + exit 1 +fi + +cd / + +echo 'Stopping any running BackOne service...' +launchctl unload '/Library/LaunchDaemons/com.backone.plist' >>/dev/null 2>&1 +sleep 1 +killall -TERM zerotier-one >>/dev/null 2>&1 +sleep 1 +killall -KILL zerotier-one >>/dev/null 2>&1 + +echo "Removing BackOne files..." + +rm -rf '/Applications/BackOne.app' +rm -rf '/Applications/BackOne.app' +rm -f '/usr/local/bin/backone' '/usr/local/bin/backone-idtool' '/usr/local/bin/backone-cli' '/Library/LaunchDaemons/com.backone.plist' + +cd '/Library/Application Support/BackOne' +if [ "`pwd`" = '/Library/Application Support/BackOne' ]; then + rm -rf *.d *.sh *.log *.old *.kext *.conf *.pkg *.dmg *.pid *.port *.save *.bin planet backone-* devicemap +fi + +echo 'Uninstall complete.' +echo +echo 'Your identity and secret authentication token have been preserved in:' +echo ' /Library/Application Support/BackOne' +echo +echo 'You can delete this folder and its contents if you do not intend to re-use' +echo 'them.' +echo + +exit 0 diff --git a/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x64).aip b/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x64).aip new file mode 100644 index 0000000..3c3d6a4 --- /dev/null +++ b/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x64).aip @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x86).aip b/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x86).aip new file mode 100644 index 0000000..50d5f55 --- /dev/null +++ b/ext/installfiles/windows/ZeroTier One Virtual Network Port (NDIS6_x86).aip @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/installfiles/windows/ZeroTier One.aip b/ext/installfiles/windows/ZeroTier One.aip new file mode 100644 index 0000000..0870201 --- /dev/null +++ b/ext/installfiles/windows/ZeroTier One.aip @@ -0,0 +1,528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/installfiles/windows/ZeroTier One.back.aip b/ext/installfiles/windows/ZeroTier One.back.aip new file mode 100644 index 0000000..9ad8182 --- /dev/null +++ b/ext/installfiles/windows/ZeroTier One.back.aip @@ -0,0 +1,558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/libnatpmp/Changelog.txt b/ext/libnatpmp/Changelog.txt new file mode 100644 index 0000000..be75a0b --- /dev/null +++ b/ext/libnatpmp/Changelog.txt @@ -0,0 +1,98 @@ +$Id: Changelog.txt,v 1.33 2013/11/26 08:47:36 nanard Exp $ + +2013/11/26: + enforce strict aliasing rules. + +2013/09/10: + small patch for MSVC >= 16 + rename win32 implementation of gettimeofday() to natpmp_gettimeofday() + +2012/08/21: + Little change in Makefile + removed warnings in testgetgateway.c + Fixed bugs in command line argumentparsing in natpmpc.c + +2011/08/07: + Patch to build on debian/kFreeBSD. + +2011/07/15: + Put 3 clauses BSD licence at the top of source files. + +2011/06/18: + --no-undefined => -Wl,--no-undefined + adding a natpmpc.1 man page + +2011/05/19: + Small fix in libnatpmpmodule.c thanks to Manuel Mausz + +2011/01/03: + Added an argument to initnatpmp() in order to force the gateway to be used + +2011/01/01: + fix in make install + +2010/05/21: + make install now working under MacOSX (and BSD) + +2010/04/12: + cplusplus stuff in natpmp.h + +2010/02/02: + Fixed compilation under Mac OS X + +2009/12/19: + improve and fix building under Windows. + Project files for MS Visual Studio 2008 + More simple (and working) code for Win32. + More checks in the /proc/net/route parsing. Add some comments. + +2009/08/04: + improving getgateway.c for windows + +2009/07/13: + Adding Haiku code in getgateway.c + +2009/06/04: + Adding Python module thanks to David Wu + +2009/03/10: + Trying to have windows get gateway working if not using DHCP + +2009/02/27: + dont include declspec.h if not under WIN32. + +2009/01/23: + Prefixed the libraries name with lib + +2008/10/06: + Fixed a memory leak in getdefaultgateway() (USE_SYSCTL_NET_ROUTE) + +2008/07/03: + Adding WIN32 code from Robbie Hanson + +2008/06/30: + added a Solaris implementation for getgateway(). + added a LICENCE file to the distribution + +2008/05/29: + Anonymous unions are forbidden in ANSI C. That was causing problems with + non-GCC compilers. + +2008/04/28: + introduced strnatpmperr() + improved natpmpc.c sample + make install now install the binary + +2007/12/13: + Fixed getgateway.c for working under OS X ;) + Fixed values for NATPMP_PROTOCOL_TCP and NATPMP_PROTOCOL_UDP + +2007/12/11: + Fixed getgateway.c for compilation under Mac OS X + +2007/12/01: + added some comments in .h + +2007/11/30: + implemented almost everything + diff --git a/ext/libnatpmp/JavaTest.java b/ext/libnatpmp/JavaTest.java new file mode 100644 index 0000000..0379c18 --- /dev/null +++ b/ext/libnatpmp/JavaTest.java @@ -0,0 +1,42 @@ +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; + +import fr.free.miniupnp.libnatpmp.NatPmp; +import fr.free.miniupnp.libnatpmp.NatPmpResponse; + +class JavaTest { + public static void main(String[] args) { + NatPmp natpmp = new NatPmp(); + + natpmp.sendPublicAddressRequest(); + NatPmpResponse response = new NatPmpResponse(); + + int result = -1; + do{ + result = natpmp.readNatPmpResponseOrRetry(response); + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + //fallthrough + } + } while (result != 0); + + byte[] bytes = intToByteArray(response.addr); + + try { + InetAddress inetAddress = InetAddress.getByAddress(bytes); + System.out.println("Public address is " + inetAddress); + } catch (UnknownHostException e) { + throw new RuntimeException(e); + } + } + + public static final byte[] intToByteArray(int value) { + return new byte[] { + (byte)value, + (byte)(value >>> 8), + (byte)(value >>> 16), + (byte)(value >>> 24)}; + } +} diff --git a/ext/libnatpmp/LICENSE b/ext/libnatpmp/LICENSE new file mode 100644 index 0000000..7fff2c2 --- /dev/null +++ b/ext/libnatpmp/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2007-2011, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/ext/libnatpmp/Makefile b/ext/libnatpmp/Makefile new file mode 100644 index 0000000..b67b3e8 --- /dev/null +++ b/ext/libnatpmp/Makefile @@ -0,0 +1,177 @@ +# $Id: Makefile,v 1.23 2013/11/26 16:38:15 nanard Exp $ +# This Makefile is designed for use with GNU make +# libnatpmp +# (c) 2007-2013 Thomas Bernard +# http://miniupnp.free.fr/libnatpmp.html + +OS = $(shell uname -s) +CC = gcc +INSTALL = install -p +ARCH = $(shell uname -m | sed -e s/i.86/i686/) +VERSION = $(shell cat VERSION) + +ifeq ($(OS), Darwin) +JARSUFFIX=mac +endif +ifeq ($(OS), Linux) +JARSUFFIX=linux +endif +ifneq (,$(findstring WIN,$(OS))) +JARSUFFIX=win32 +endif + +# APIVERSION is used in soname +APIVERSION = 1 +#LDFLAGS = -Wl,--no-undefined +CFLAGS ?= -Os +#CFLAGS = -g -O0 +CFLAGS += -fPIC +CFLAGS += -Wall +#CFLAGS += -Wextra +CFLAGS += -DENABLE_STRNATPMPERR +#CFLAGS += -Wstrict-aliasing + +LIBOBJS = natpmp.o getgateway.o + +OBJS = $(LIBOBJS) testgetgateway.o natpmpc.o natpmp-jni.o + +STATICLIB = libnatpmp.a +ifeq ($(OS), Darwin) + SHAREDLIB = libnatpmp.dylib + JNISHAREDLIB = libjninatpmp.dylib + SONAME = $(basename $(SHAREDLIB)).$(APIVERSION).dylib + CFLAGS := -DMACOSX -D_DARWIN_C_SOURCE $(CFLAGS) + SONAMEFLAGS=-Wl,-install_name,$(JNISHAREDLIB) -dynamiclib -framework JavaVM +else +ifneq (,$(findstring WIN,$(OS))) + SHAREDLIB = natpmp.dll + JNISHAREDLIB = jninatpmp.dll + CC = i686-w64-mingw32-gcc + EXTRA_LD = -lws2_32 -lIphlpapi -Wl,--no-undefined -Wl,--enable-runtime-pseudo-reloc --Wl,kill-at +else + SHAREDLIB = libnatpmp.so + JNISHAREDLIB = libjninatpmp.so + SONAME = $(SHAREDLIB).$(APIVERSION) + SONAMEFLAGS=-Wl,-soname,$(JNISHAREDLIB) +endif +endif + +HEADERS = natpmp.h + +EXECUTABLES = testgetgateway natpmpc-shared natpmpc-static + +INSTALLPREFIX ?= $(PREFIX)/usr +INSTALLDIRINC = $(INSTALLPREFIX)/include +INSTALLDIRLIB = $(INSTALLPREFIX)/lib +INSTALLDIRBIN = $(INSTALLPREFIX)/bin + +JAVA ?= java +JAVAC ?= javac +JAVAH ?= javah +JAVAPACKAGE = fr/free/miniupnp/libnatpmp +JAVACLASSES = $(JAVAPACKAGE)/NatPmp.class $(JAVAPACKAGE)/NatPmpResponse.class $(JAVAPACKAGE)/LibraryExtractor.class $(JAVAPACKAGE)/URLUtils.class +JNIHEADERS = fr_free_miniupnp_libnatpmp_NatPmp.h + +.PHONY: all clean depend install cleaninstall installpythonmodule + +all: $(STATICLIB) $(SHAREDLIB) $(EXECUTABLES) + +pythonmodule: $(STATICLIB) libnatpmpmodule.c setup.py + python setup.py build + touch $@ + +installpythonmodule: pythonmodule + python setup.py install + +clean: + $(RM) $(OBJS) $(EXECUTABLES) $(STATICLIB) $(SHAREDLIB) $(JAVACLASSES) $(JNISHAREDLIB) + $(RM) pythonmodule + $(RM) -r build/ dist/ libraries/ + +depend: + makedepend -f$(MAKEFILE_LIST) -Y $(OBJS:.o=.c) 2>/dev/null + +install: $(HEADERS) $(STATICLIB) $(SHAREDLIB) natpmpc-shared + $(INSTALL) -d $(INSTALLDIRINC) + $(INSTALL) -m 644 $(HEADERS) $(INSTALLDIRINC) + $(INSTALL) -d $(INSTALLDIRLIB) + $(INSTALL) -m 644 $(STATICLIB) $(INSTALLDIRLIB) + $(INSTALL) -m 644 $(SHAREDLIB) $(INSTALLDIRLIB)/$(SONAME) + $(INSTALL) -d $(INSTALLDIRBIN) + $(INSTALL) -m 755 natpmpc-shared $(INSTALLDIRBIN)/natpmpc + ln -s -f $(SONAME) $(INSTALLDIRLIB)/$(SHAREDLIB) + +$(JNIHEADERS): fr/free/miniupnp/libnatpmp/NatPmp.class + $(JAVAH) -jni fr.free.miniupnp.libnatpmp.NatPmp + +%.class: %.java + $(JAVAC) -cp . $< + +$(JNISHAREDLIB): $(SHAREDLIB) $(JNIHEADERS) $(JAVACLASSES) +ifeq (,$(JAVA_HOME)) + @echo "Check your JAVA_HOME environement variable" && false +endif +ifneq (,$(findstring WIN,$(OS))) + $(CC) -m32 -D_JNI_Implementation_ -Wl,--kill-at \ + -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" \ + natpmp-jni.c -shared \ + -o $(JNISHAREDLIB) -L. -lnatpmp -lws2_32 -lIphlpapi +else + $(CC) $(CFLAGS) -c -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" natpmp-jni.c + $(CC) $(CFLAGS) -o $(JNISHAREDLIB) -shared $(SONAMEFLAGS) natpmp-jni.o -lc -L. -lnatpmp +endif + +jar: $(JNISHAREDLIB) + find fr -name '*.class' -print > classes.list + $(eval JNISHAREDLIBPATH := $(shell java fr.free.miniupnp.libnatpmp.LibraryExtractor)) + mkdir -p libraries/$(JNISHAREDLIBPATH) + mv $(JNISHAREDLIB) libraries/$(JNISHAREDLIBPATH)/$(JNISHAREDLIB) + jar cf natpmp_$(JARSUFFIX).jar @classes.list libraries/$(JNISHAREDLIBPATH)/$(JNISHAREDLIB) + $(RM) classes.list + +jnitest: $(JNISHAREDLIB) JavaTest.class + $(RM) libjninatpmp.so + $(JAVA) -Djna.nosys=true -cp . JavaTest + +mvn_install: + mvn install:install-file -Dfile=java/natpmp_$(JARSUFFIX).jar \ + -DgroupId=com.github \ + -DartifactId=natpmp \ + -Dversion=$(VERSION) \ + -Dpackaging=jar \ + -Dclassifier=$(JARSUFFIX) \ + -DgeneratePom=true \ + -DcreateChecksum=true + +cleaninstall: + $(RM) $(addprefix $(INSTALLDIRINC), $(HEADERS)) + $(RM) $(INSTALLDIRLIB)/$(SONAME) + $(RM) $(INSTALLDIRLIB)/$(SHAREDLIB) + $(RM) $(INSTALLDIRLIB)/$(STATICLIB) + +testgetgateway: testgetgateway.o getgateway.o + $(CC) $(LDFLAGS) -o $@ $^ $(EXTRA_LD) + +natpmpc-static: natpmpc.o $(STATICLIB) + $(CC) $(LDFLAGS) -o $@ $^ $(EXTRA_LD) + +natpmpc-shared: natpmpc.o $(SHAREDLIB) + $(CC) $(LDFLAGS) -o $@ $^ $(EXTRA_LD) + +$(STATICLIB): $(LIBOBJS) + $(AR) crs $@ $? + +$(SHAREDLIB): $(LIBOBJS) +ifeq ($(OS), Darwin) + $(CC) -dynamiclib -Wl,-install_name,$(SONAME) -o $@ $^ +else + $(CC) -shared -Wl,-soname,$(SONAME) -o $@ $^ $(EXTRA_LD) +endif + + +# DO NOT DELETE + +natpmp.o: natpmp.h getgateway.h declspec.h +getgateway.o: getgateway.h declspec.h +testgetgateway.o: getgateway.h declspec.h +natpmpc.o: natpmp.h diff --git a/ext/libnatpmp/README b/ext/libnatpmp/README new file mode 100644 index 0000000..269392d --- /dev/null +++ b/ext/libnatpmp/README @@ -0,0 +1,7 @@ +libnatpmp (c) 2007-2009 Thomas Bernard +contact : miniupnp@free.fr + +see http://miniupnp.free.fr/libnatpmp.html +or http://miniupnp.tuxfamily.org/libnatpmp.html +for some documentation and code samples. + diff --git a/ext/libnatpmp/build.bat b/ext/libnatpmp/build.bat new file mode 100644 index 0000000..2d2f27c --- /dev/null +++ b/ext/libnatpmp/build.bat @@ -0,0 +1,30 @@ +@echo Compiling with MinGW +@SET LIBS=-lws2_32 -liphlpapi + +@echo Compile getgateway +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR testgetgateway.c +gcc -o testgetgateway getgateway.o testgetgateway.o %LIBS% +del testgetgateway.o + +@echo Compile natpmp-static: +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmp.c +gcc -c -Wall -Os -DWIN32 wingettimeofday.c +ar cr natpmp.a getgateway.o natpmp.o wingettimeofday.o +del getgateway.o natpmp.o +gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmpc.c +gcc -o natpmpc-static natpmpc.o natpmp.a %LIBS% +upx --best natpmpc-static.exe +del natpmpc.o + +@echo Create natpmp.dll: +gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS getgateway.c +gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmp.c +dllwrap -k --driver-name gcc --def natpmp.def --output-def natpmp.dll.def --implib natpmp.lib -o natpmp.dll getgateway.o natpmp.o wingettimeofday.o %LIBS% + +@echo Compile natpmp-shared: +gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmpc.c +gcc -o natpmpc-shared natpmpc.o natpmp.lib -lws2_32 +upx --best natpmpc-shared.exe +del *.o diff --git a/ext/libnatpmp/declspec.h b/ext/libnatpmp/declspec.h new file mode 100644 index 0000000..a76be02 --- /dev/null +++ b/ext/libnatpmp/declspec.h @@ -0,0 +1,21 @@ +#ifndef DECLSPEC_H_INCLUDED +#define DECLSPEC_H_INCLUDED + +#if defined(WIN32) && !defined(STATICLIB) + /* for windows dll */ + #ifdef NATPMP_EXPORTS + #define LIBSPEC __declspec(dllexport) + #else + #define LIBSPEC __declspec(dllimport) + #endif +#else + #if defined(__GNUC__) && __GNUC__ >= 4 + /* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */ + #define LIBSPEC __attribute__ ((visibility ("default"))) + #else + #define LIBSPEC + #endif +#endif + +#endif + diff --git a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/LibraryExtractor.java b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/LibraryExtractor.java new file mode 100644 index 0000000..5491d94 --- /dev/null +++ b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/LibraryExtractor.java @@ -0,0 +1,238 @@ +package fr.free.miniupnp.libnatpmp; + +/** I (Leah X Schmidt) copied this code from jnaerator, because +JNAerator's extractor requires you to buy into the whole JNA +concept. + +JNAErator is +Copyright (c) 2009 Olivier Chafik, All Rights Reserved + +JNAerator is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +JNAerator is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with JNAerator. If not, see . + +*/ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class LibraryExtractor { + + private static boolean libPathSet = false; + + public static String getLibraryPath(String libraryName, boolean extractAllLibraries, Class cl) { + try { + String customPath = System.getProperty("library." + libraryName); + if (customPath == null) + customPath = System.getenv(libraryName.toUpperCase() + "_LIBRARY"); + if (customPath != null) { + File f = new File(customPath); + if (!f.exists()) + System.err.println("Library file '" + customPath + "' does not exist !"); + else + return f.getAbsolutePath(); + } + //ClassLoader cl = LibraryExtractor.class.getClassLoader(); + String prefix = "(?i)" + (isWindows() ? "" : "lib") + libraryName + "[^A-Za-z_].*"; + String libsuffix = "(?i).*\\.(so|dll|dylib|jnilib)"; + //String othersuffix = "(?i).*\\.(pdb)"; + + URL sourceURL = null; + List otherURLs = new ArrayList(); + + + String arch = getCurrentOSAndArchString(); + //System.out.println("libURL = " + libURL); + List list = URLUtils.listFiles(URLUtils.getResource(cl, "libraries/" + arch)), + noArchList = URLUtils.listFiles(URLUtils.getResource(cl, "libraries/noarch")); + + Set names = new HashSet(); + for (URL url : list) { + String name = getFileName(url); + names.add(name); + } + for (URL url : noArchList) { + String name = getFileName(url); + if (names.add(name)) + list.add(url); + } + + for (File f : new File(".").listFiles()) + if (f.isFile()) + list.add(f.toURI().toURL()); + + for (URL url : list) { + String name = getFileName(url); + boolean pref = name.matches(prefix), suff = name.matches(libsuffix); + if (pref && suff) + sourceURL = url; + else //if (suff || fileName.matches(othersuffix)) + otherURLs.add(url); + } + List files = new ArrayList(); + if (extractAllLibraries) { + for (URL url : otherURLs) + files.add(extract(url)); + } + + if (System.getProperty("javawebstart.version") != null) { + if (isWindows()) { + //File f = new File("c:\\Windows\\" + (Platform.is64Bit() ? "SysWOW64\\" : "System32\\") + libraryName + ".dll"); + File f = new File("c:\\Windows\\" + "System32\\" + libraryName + ".dll"); + if (f.exists()) + return f.toString(); + } else if (isMac()) { + File f = new File("/System/Library/Frameworks/" + libraryName + ".framework/" + libraryName); + if (f.exists()) + return f.toString(); + } + } + + if (sourceURL == null) + return libraryName; + else { + File file = extract(sourceURL); + files.add(file); + + int lastSize; + do { + lastSize = files.size(); + for (Iterator it = files.iterator(); it.hasNext();) { + File f = it.next(); + if (!f.getName().matches(libsuffix)) + continue; + + try { + System.load(f.toString()); + it.remove(); + } catch (Throwable ex) { + System.err.println("Loading " + f.getName() + " failed (" + ex + ")"); + } + } + } while (files.size() < lastSize); + + return file.getCanonicalPath(); + } + } catch (Throwable ex) { + System.err.println("ERROR: Failed to extract library " + libraryName); + ex.printStackTrace(); + return libraryName; + } + } + + public static final boolean isWindows() { + String osName = System.getProperty("os.name"); + return osName.startsWith("Windows"); + } + + public static final boolean isMac() { + String osName = System.getProperty("os.name"); + return osName.startsWith("Mac") || osName.startsWith("Darwin"); + } + + //this code is from JNA, but JNA has a fallback to some native + //stuff in case this doesn't work. Since sun.arch.data.model is + //defined for Sun and IBM, this should work nearly everywhere. + public static final boolean is64Bit() { + String model = System.getProperty("sun.arch.data.model", + System.getProperty("com.ibm.vm.bitmode")); + if (model != null) { + return "64".equals(model); + } + String arch = System.getProperty("os.arch").toLowerCase(); + if ("x86_64".equals(arch) + || "ia64".equals(arch) + || "ppc64".equals(arch) + || "sparcv9".equals(arch) + || "amd64".equals(arch)) { + return true; + } + + return false; + } + + public static String getCurrentOSAndArchString() { + String os = System.getProperty("os.name"), arch = System.getProperty("os.arch"); + if (os.equals("Mac OS X")) { + os = "darwin"; + arch = "fat"; + } else if (os.startsWith("Windows")) { + return "win" + (is64Bit() ? "64" : "32"); + } else if (os.matches("SunOS|Solaris")) + os = "solaris"; + return os + "-" + arch; + } + + private static File extract(URL url) throws IOException { + File localFile; + if ("file".equals(url.getProtocol())) + localFile = new File(URLDecoder.decode(url.getFile(), "UTF-8")); + else { + File f = new File(System.getProperty("user.home")); + f = new File(f, ".jnaerator"); + f = new File(f, "extractedLibraries"); + if (!f.exists()) + f.mkdirs(); + + if (!libPathSet) { + String path = System.getProperty("java.library.path"); + if (path == null) { + System.setProperty("java.library.path", f.toString()); + } else { + System.setProperty("java.library.path", path + ":" + f); + } + + libPathSet = true; + } + localFile = new File(f, new File(url.getFile()).getName()); + URLConnection c = url.openConnection(); + if (localFile.exists() && localFile.lastModified() > c.getLastModified()) { + c.getInputStream().close(); + } else { + System.out.println("Extracting " + url); + InputStream in = c.getInputStream(); + OutputStream out = new FileOutputStream(localFile); + int len; + byte[] b = new byte[1024]; + while ((len = in.read(b)) > 0) + out.write(b, 0, len); + out.close(); + in.close(); + } + } + return localFile; + } + + private static String getFileName(URL url) { + return new File(url.getFile()).getName(); + } + + public static void main(String[] args) { + System.out.println(getCurrentOSAndArchString()); + } +} \ No newline at end of file diff --git a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmp.java b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmp.java new file mode 100644 index 0000000..2f1ddd3 --- /dev/null +++ b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmp.java @@ -0,0 +1,50 @@ +package fr.free.miniupnp.libnatpmp; + +import java.nio.ByteBuffer; + + +public class NatPmp { + private static final String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("jninatpmp", true, NatPmp.class); + + static { + String s = JNA_LIBRARY_NAME; + startup(); + } + + public ByteBuffer natpmp; + + public NatPmp() { + init(0, 0); + } + + public NatPmp(int forcedgw) { + init(1, forcedgw); + } + + /** Cleans up the native resources used by this object. + Attempting to use the object after this has been called + will lead to crashes.*/ + public void dispose() { + free(); + } + + + protected void finalize() { + if (natpmp != null) + free(); + } + + private native void init(int forcegw, int forcedgw); + private native void free(); + + private static native void startup(); + + public native int sendPublicAddressRequest(); + public native int sendNewPortMappingRequest(int protocol, int privateport, int publicport, int lifetime); + + //returns a number of milliseconds, in accordance with Java convention + public native long getNatPmpRequestTimeout(); + + public native int readNatPmpResponseOrRetry(NatPmpResponse response); + +} diff --git a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmpResponse.java b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmpResponse.java new file mode 100644 index 0000000..35c87ea --- /dev/null +++ b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmpResponse.java @@ -0,0 +1,28 @@ +package fr.free.miniupnp.libnatpmp; + +public class NatPmpResponse { + + public static final int TYPE_PUBLICADDRESS=0; + public static final int TYPE_UDPPORTMAPPING=1; + public static final int TYPE_TCPPORTMAPPING=2; + + /** see TYPE_* constants */ + public short type; + /** NAT-PMP response code */ + public short resultcode; + /** milliseconds since start of epoch */ + public long epoch; + + /** only defined if type == 0*/ + public int addr; + + /** only defined if type != 0 */ + public int privateport; + + /** only defined if type != 0 */ + public int mappedpublicport; + + /** only defined if type != 0 */ + public long lifetime; //milliseconds + +} \ No newline at end of file diff --git a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/URLUtils.java b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/URLUtils.java new file mode 100644 index 0000000..5b419ab --- /dev/null +++ b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/URLUtils.java @@ -0,0 +1,81 @@ +package fr.free.miniupnp.libnatpmp; + +/** I (Leah X Schmidt) copied this code from jnaerator, because +JNAerator's extractor requires you to buy into the whole JNA +concept. + +JNAErator is +Copyright (c) 2009 Olivier Chafik, All Rights Reserved + +JNAerator is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +JNAerator is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with JNAerator. If not, see . + +*/ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; + +public class URLUtils { + + public static URL getResource(Class cl, String path) throws IOException { + String clp = cl.getName().replace('.', '/') + ".class"; + URL clu = cl.getClassLoader().getResource(clp); + String s = clu.toString(); + if (s.endsWith(clp)) + return new URL(s.substring(0, s.length() - clp.length()) + path); + + if (s.startsWith("jar:")) { + String[] ss = s.split("!"); + return new URL(ss[1] + "!/" + path); + } + return null; + } + + public static List listFiles(URL directory) throws IOException { + List ret = new ArrayList(); + String s = directory.toString(); + if (s.startsWith("jar:")) { + String[] ss = s.substring("jar:".length()).split("!"); + String path = ss[1]; + URL target = new URL(ss[0]); + InputStream tin = target.openStream(); + try { + JarInputStream jin = new JarInputStream(tin); + JarEntry je; + while ((je = jin.getNextJarEntry()) != null) { + String p = "/" + je.getName(); + if (p.startsWith(path) && p.indexOf('/', path.length() + 1) < 0) + + ret.add(new URL("jar:" + target + "!" + p)); + } + } finally { + tin.close(); + } + } else if (s.startsWith("file:")) { + File f = new File(directory.getFile()); + File[] ffs = f.listFiles(); + if (ffs != null) + for (File ff : ffs) + ret.add(ff.toURI().toURL()); + } else + throw new IOException("Cannot list contents of " + directory); + + return ret; + } +} \ No newline at end of file diff --git a/ext/libnatpmp/getgateway.c b/ext/libnatpmp/getgateway.c new file mode 100644 index 0000000..0f06e1d --- /dev/null +++ b/ext/libnatpmp/getgateway.c @@ -0,0 +1,575 @@ +/* $Id: getgateway.c,v 1.25 2014/04/22 10:28:57 nanard Exp $ */ +/* libnatpmp + +Copyright (c) 2007-2014, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include +#ifndef WIN32 +#include +#endif +#if !defined(_MSC_VER) +#include +#endif +/* There is no portable method to get the default route gateway. + * So below are four (or five ?) differents functions implementing this. + * Parsing /proc/net/route is for linux. + * sysctl is the way to access such informations on BSD systems. + * Many systems should provide route information through raw PF_ROUTE + * sockets. + * In MS Windows, default gateway is found by looking into the registry + * or by using GetBestRoute(). */ +#ifdef __linux__ +#define USE_PROC_NET_ROUTE +#undef USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#endif + +#if defined(BSD) || defined(__FreeBSD_kernel__) +#undef USE_PROC_NET_ROUTE +#define USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#include +#endif + +#ifdef __APPLE__ +#undef USE_PROC_NET_ROUTE +#undef USE_SOCKET_ROUTE +#define USE_SYSCTL_NET_ROUTE +#endif + +#if (defined(sun) && defined(__SVR4)) +#undef USE_PROC_NET_ROUTE +#define USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#endif + +#ifdef WIN32 +#undef USE_PROC_NET_ROUTE +#undef USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +//#define USE_WIN32_CODE +#define USE_WIN32_CODE_2 +#endif + +#ifdef __CYGWIN__ +#undef USE_PROC_NET_ROUTE +#undef USE_SOCKET_ROUTE +#undef USE_SYSCTL_NET_ROUTE +#define USE_WIN32_CODE +#include +#include +#include +#include +#endif + +#ifdef __HAIKU__ +#include +#include +#include +#include +#define USE_HAIKU_CODE +#endif + +#ifdef USE_SYSCTL_NET_ROUTE +#include +#include +#include +#endif +#ifdef USE_SOCKET_ROUTE +#include +#include +#include +#include +#include +#endif + +#ifdef USE_WIN32_CODE +#include +#include +#define MAX_KEY_LENGTH 255 +#define MAX_VALUE_LENGTH 16383 +#endif + +#ifdef USE_WIN32_CODE_2 +#include +#include +#endif + +#include "getgateway.h" + +#ifndef WIN32 +#define SUCCESS (0) +#define FAILED (-1) +#endif + +#ifdef USE_PROC_NET_ROUTE +/* + parse /proc/net/route which is as follow : + +Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT +wlan0 0001A8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0 +eth0 0000FEA9 00000000 0001 0 0 0 0000FFFF 0 0 0 +wlan0 00000000 0101A8C0 0003 0 0 0 00000000 0 0 0 +eth0 00000000 00000000 0001 0 0 1000 00000000 0 0 0 + + One header line, and then one line by route by route table entry. +*/ +int getdefaultgateway(in_addr_t * addr) +{ + unsigned long d, g; + char buf[256]; + int line = 0; + FILE * f; + char * p; + f = fopen("/proc/net/route", "r"); + if(!f) + return FAILED; + while(fgets(buf, sizeof(buf), f)) { + if(line > 0) { /* skip the first line */ + p = buf; + /* skip the interface name */ + while(*p && !isspace(*p)) + p++; + while(*p && isspace(*p)) + p++; + if(sscanf(p, "%lx%lx", &d, &g)==2) { + if(d == 0 && g != 0) { /* default */ + *addr = g; + fclose(f); + return SUCCESS; + } + } + } + line++; + } + /* default route not found ! */ + if(f) + fclose(f); + return FAILED; +} +#endif /* #ifdef USE_PROC_NET_ROUTE */ + + +#ifdef USE_SYSCTL_NET_ROUTE + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + +int getdefaultgateway(in_addr_t * addr) +{ +#if 0 + /* net.route.0.inet.dump.0.0 ? */ + int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, + NET_RT_DUMP, 0, 0/*tableid*/}; +#endif + /* net.route.0.inet.flags.gateway */ + int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, + NET_RT_FLAGS, RTF_GATEWAY}; + size_t l; + char * buf, * p; + struct rt_msghdr * rt; + struct sockaddr * sa; + struct sockaddr * sa_tab[RTAX_MAX]; + int i; + int r = FAILED; + if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) { + return FAILED; + } + if(l>0) { + buf = malloc(l); + if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) { + free(buf); + return FAILED; + } + for(p=buf; prtm_msglen) { + rt = (struct rt_msghdr *)p; + sa = (struct sockaddr *)(rt + 1); + for(i=0; irtm_addrs & (1 << i)) { + sa_tab[i] = sa; + sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len)); + } else { + sa_tab[i] = NULL; + } + } + if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY)) + && sa_tab[RTAX_DST]->sa_family == AF_INET + && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) { + if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) { + *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr; + r = SUCCESS; + } + } + } + free(buf); + } + return r; +} +#endif /* #ifdef USE_SYSCTL_NET_ROUTE */ + + +#ifdef USE_SOCKET_ROUTE +/* Thanks to Darren Kenny for this code */ +#define NEXTADDR(w, u) \ + if (rtm_addrs & (w)) {\ + l = sizeof(struct sockaddr); memmove(cp, &(u), l); cp += l;\ + } + +#define rtm m_rtmsg.m_rtm + +struct { + struct rt_msghdr m_rtm; + char m_space[512]; +} m_rtmsg; + +int getdefaultgateway(in_addr_t *addr) +{ + int s, seq, l, rtm_addrs, i; + pid_t pid; + struct sockaddr so_dst, so_mask; + char *cp = m_rtmsg.m_space; + struct sockaddr *gate = NULL, *sa; + struct rt_msghdr *msg_hdr; + + pid = getpid(); + seq = 0; + rtm_addrs = RTA_DST | RTA_NETMASK; + + memset(&so_dst, 0, sizeof(so_dst)); + memset(&so_mask, 0, sizeof(so_mask)); + memset(&rtm, 0, sizeof(struct rt_msghdr)); + + rtm.rtm_type = RTM_GET; + rtm.rtm_flags = RTF_UP | RTF_GATEWAY; + rtm.rtm_version = RTM_VERSION; + rtm.rtm_seq = ++seq; + rtm.rtm_addrs = rtm_addrs; + + so_dst.sa_family = AF_INET; + so_dst.sa_len = sizeof(struct sockaddr); + so_mask.sa_family = AF_INET; + so_mask.sa_len = sizeof(struct sockaddr); + + NEXTADDR(RTA_DST, so_dst); + NEXTADDR(RTA_NETMASK, so_mask); + + rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; + + s = socket(PF_ROUTE, SOCK_RAW, 0); + + if (write(s, (char *)&m_rtmsg, l) < 0) { + close(s); + return FAILED; + } + + do { + l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); + } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); + + close(s); + + msg_hdr = &rtm; + + cp = ((char *)(msg_hdr + 1)); + if (msg_hdr->rtm_addrs) { + for (i = 1; i; i <<= 1) + if (i & msg_hdr->rtm_addrs) { + sa = (struct sockaddr *)cp; + if (i == RTA_GATEWAY ) + gate = sa; + + cp += sizeof(struct sockaddr); + } + } else { + return FAILED; + } + + + if (gate != NULL ) { + *addr = ((struct sockaddr_in *)gate)->sin_addr.s_addr; + return SUCCESS; + } else { + return FAILED; + } +} +#endif /* #ifdef USE_SOCKET_ROUTE */ + +#ifdef USE_WIN32_CODE +LIBSPEC int getdefaultgateway(in_addr_t * addr) +{ + HKEY networkCardsKey; + HKEY networkCardKey; + HKEY interfacesKey; + HKEY interfaceKey; + DWORD i = 0; + DWORD numSubKeys = 0; + TCHAR keyName[MAX_KEY_LENGTH]; + DWORD keyNameLength = MAX_KEY_LENGTH; + TCHAR keyValue[MAX_VALUE_LENGTH]; + DWORD keyValueLength = MAX_VALUE_LENGTH; + DWORD keyValueType = REG_SZ; + TCHAR gatewayValue[MAX_VALUE_LENGTH]; + DWORD gatewayValueLength = MAX_VALUE_LENGTH; + DWORD gatewayValueType = REG_MULTI_SZ; + int done = 0; + + //const char * networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + //const char * interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; +#ifdef UNICODE + LPCTSTR networkCardsPath = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + LPCTSTR interfacesPath = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; +#define STR_SERVICENAME L"ServiceName" +#define STR_DHCPDEFAULTGATEWAY L"DhcpDefaultGateway" +#define STR_DEFAULTGATEWAY L"DefaultGateway" +#else + LPCTSTR networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; + LPCTSTR interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; +#define STR_SERVICENAME "ServiceName" +#define STR_DHCPDEFAULTGATEWAY "DhcpDefaultGateway" +#define STR_DEFAULTGATEWAY "DefaultGateway" +#endif + // The windows registry lists its primary network devices in the following location: + // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards + // + // Each network device has its own subfolder, named with an index, with various properties: + // -NetworkCards + // -5 + // -Description = Broadcom 802.11n Network Adapter + // -ServiceName = {E35A72F8-5065-4097-8DFE-C7790774EE4D} + // -8 + // -Description = Marvell Yukon 88E8058 PCI-E Gigabit Ethernet Controller + // -ServiceName = {86226414-5545-4335-A9D1-5BD7120119AD} + // + // The above service name is the name of a subfolder within: + // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces + // + // There may be more subfolders in this interfaces path than listed in the network cards path above: + // -Interfaces + // -{3a539854-6a70-11db-887c-806e6f6e6963} + // -DhcpIPAddress = 0.0.0.0 + // -[more] + // -{E35A72F8-5065-4097-8DFE-C7790774EE4D} + // -DhcpIPAddress = 10.0.1.4 + // -DhcpDefaultGateway = 10.0.1.1 + // -[more] + // -{86226414-5545-4335-A9D1-5BD7120119AD} + // -DhcpIpAddress = 10.0.1.5 + // -DhcpDefaultGateay = 10.0.1.1 + // -[more] + // + // In order to extract this information, we enumerate each network card, and extract the ServiceName value. + // This is then used to open the interface subfolder, and attempt to extract a DhcpDefaultGateway value. + // Once one is found, we're done. + // + // It may be possible to simply enumerate the interface folders until we find one with a DhcpDefaultGateway value. + // However, the technique used is the technique most cited on the web, and we assume it to be more correct. + + if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predifined key + networkCardsPath, // Name of registry subkey to open + 0, // Reserved - must be zero + KEY_READ, // Mask - desired access rights + &networkCardsKey)) // Pointer to output key + { + // Unable to open network cards keys + return -1; + } + + if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predefined key + interfacesPath, // Name of registry subkey to open + 0, // Reserved - must be zero + KEY_READ, // Mask - desired access rights + &interfacesKey)) // Pointer to output key + { + // Unable to open interfaces key + RegCloseKey(networkCardsKey); + return -1; + } + + // Figure out how many subfolders are within the NetworkCards folder + RegQueryInfoKey(networkCardsKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + + //printf( "Number of subkeys: %u\n", (unsigned int)numSubKeys); + + // Enumrate through each subfolder within the NetworkCards folder + for(i = 0; i < numSubKeys && !done; i++) + { + keyNameLength = MAX_KEY_LENGTH; + if(ERROR_SUCCESS == RegEnumKeyEx(networkCardsKey, // Open registry key + i, // Index of subkey to retrieve + keyName, // Buffer that receives the name of the subkey + &keyNameLength, // Variable that receives the size of the above buffer + NULL, // Reserved - must be NULL + NULL, // Buffer that receives the class string + NULL, // Variable that receives the size of the above buffer + NULL)) // Variable that receives the last write time of subkey + { + if(RegOpenKeyEx(networkCardsKey, keyName, 0, KEY_READ, &networkCardKey) == ERROR_SUCCESS) + { + keyValueLength = MAX_VALUE_LENGTH; + if(ERROR_SUCCESS == RegQueryValueEx(networkCardKey, // Open registry key + STR_SERVICENAME, // Name of key to query + NULL, // Reserved - must be NULL + &keyValueType, // Receives value type + (LPBYTE)keyValue, // Receives value + &keyValueLength)) // Receives value length in bytes + { +// printf("keyValue: %s\n", keyValue); + if(RegOpenKeyEx(interfacesKey, keyValue, 0, KEY_READ, &interfaceKey) == ERROR_SUCCESS) + { + gatewayValueLength = MAX_VALUE_LENGTH; + if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key + STR_DHCPDEFAULTGATEWAY, // Name of key to query + NULL, // Reserved - must be NULL + &gatewayValueType, // Receives value type + (LPBYTE)gatewayValue, // Receives value + &gatewayValueLength)) // Receives value length in bytes + { + // Check to make sure it's a string + if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1)) + { + //printf("gatewayValue: %s\n", gatewayValue); + done = 1; + } + } + else if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key + STR_DEFAULTGATEWAY, // Name of key to query + NULL, // Reserved - must be NULL + &gatewayValueType, // Receives value type + (LPBYTE)gatewayValue,// Receives value + &gatewayValueLength)) // Receives value length in bytes + { + // Check to make sure it's a string + if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1)) + { + //printf("gatewayValue: %s\n", gatewayValue); + done = 1; + } + } + RegCloseKey(interfaceKey); + } + } + RegCloseKey(networkCardKey); + } + } + } + + RegCloseKey(interfacesKey); + RegCloseKey(networkCardsKey); + + if(done) + { +#if UNICODE + char tmp[32]; + for(i = 0; i < 32; i++) { + tmp[i] = (char)gatewayValue[i]; + if(!tmp[i]) + break; + } + tmp[31] = '\0'; + *addr = inet_addr(tmp); +#else + *addr = inet_addr(gatewayValue); +#endif + return 0; + } + + return -1; +} +#endif /* #ifdef USE_WIN32_CODE */ + +#ifdef USE_WIN32_CODE_2 +int getdefaultgateway(in_addr_t *addr) +{ + MIB_IPFORWARDROW ip_forward; + memset(&ip_forward, 0, sizeof(ip_forward)); + if(GetBestRoute(inet_addr("0.0.0.0"), 0, &ip_forward) != NO_ERROR) + return -1; + *addr = ip_forward.dwForwardNextHop; + return 0; +} +#endif /* #ifdef USE_WIN32_CODE_2 */ + +#ifdef USE_HAIKU_CODE +int getdefaultgateway(in_addr_t *addr) +{ + int fd, ret = -1; + struct ifconf config; + void *buffer = NULL; + struct ifreq *interface; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + return -1; + } + if (ioctl(fd, SIOCGRTSIZE, &config, sizeof(config)) != 0) { + goto fail; + } + if (config.ifc_value < 1) { + goto fail; /* No routes */ + } + if ((buffer = malloc(config.ifc_value)) == NULL) { + goto fail; + } + config.ifc_len = config.ifc_value; + config.ifc_buf = buffer; + if (ioctl(fd, SIOCGRTTABLE, &config, sizeof(config)) != 0) { + goto fail; + } + for (interface = buffer; + (uint8_t *)interface < (uint8_t *)buffer + config.ifc_len; ) { + struct route_entry route = interface->ifr_route; + int intfSize; + if (route.flags & (RTF_GATEWAY | RTF_DEFAULT)) { + *addr = ((struct sockaddr_in *)route.gateway)->sin_addr.s_addr; + ret = 0; + break; + } + intfSize = sizeof(route) + IF_NAMESIZE; + if (route.destination != NULL) { + intfSize += route.destination->sa_len; + } + if (route.mask != NULL) { + intfSize += route.mask->sa_len; + } + if (route.gateway != NULL) { + intfSize += route.gateway->sa_len; + } + interface = (struct ifreq *)((uint8_t *)interface + intfSize); + } +fail: + free(buffer); + close(fd); + return ret; +} +#endif /* #ifdef USE_HAIKU_CODE */ + +#if !defined(USE_PROC_NET_ROUTE) && !defined(USE_SOCKET_ROUTE) && !defined(USE_SYSCTL_NET_ROUTE) && !defined(USE_WIN32_CODE) && !defined(USE_WIN32_CODE_2) && !defined(USE_HAIKU_CODE) +int getdefaultgateway(in_addr_t * addr) +{ + return -1; +} +#endif diff --git a/ext/libnatpmp/getgateway.h b/ext/libnatpmp/getgateway.h new file mode 100644 index 0000000..5d3df73 --- /dev/null +++ b/ext/libnatpmp/getgateway.h @@ -0,0 +1,49 @@ +/* $Id: getgateway.h,v 1.8 2014/04/22 09:15:40 nanard Exp $ */ +/* libnatpmp +Copyright (c) 2007-2014, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef __GETGATEWAY_H__ +#define __GETGATEWAY_H__ + +#ifdef WIN32 +#if !defined(_MSC_VER) || _MSC_VER >= 1600 +#include +#else +typedef unsigned long uint32_t; +typedef unsigned short uint16_t; +#endif +#define in_addr_t uint32_t +#endif +/* #include "declspec.h" */ + +/* getdefaultgateway() : + * return value : + * 0 : success + * -1 : failure */ +/* LIBSPEC */int getdefaultgateway(in_addr_t * addr); + +#endif diff --git a/ext/libnatpmp/libnatpmpmodule.c b/ext/libnatpmp/libnatpmpmodule.c new file mode 100644 index 0000000..0fd9914 --- /dev/null +++ b/ext/libnatpmp/libnatpmpmodule.c @@ -0,0 +1,281 @@ +/* $Id: libnatpmpmodule.c,v 1.7 2012/03/05 19:38:37 nanard Exp $ */ +/* libnatpmp + * http://miniupnp.free.fr/libnatpmp.html +Copyright (c) 2007-2011, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#ifdef WIN32 +#include +#else +#include +#include +#endif + +#define STATICLIB +#include "structmember.h" +#include "natpmp.h" + +/* for compatibility with Python < 2.4 */ +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + +#ifndef Py_RETURN_TRUE +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#endif + +#ifndef Py_RETURN_FALSE +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +#endif + +typedef struct { + PyObject_HEAD + + /* Type-specific fields go here. */ + unsigned int discoverdelay; + + natpmp_t natpmp; +} NATPMPObject; + +static PyMemberDef NATPMP_members[] = { + {"discoverdelay", T_UINT, offsetof(NATPMPObject, discoverdelay), + 0/*READWRITE*/, "value in ms used to wait for NATPMP responses" + }, + {NULL} +}; + +static PyObject * +NATPMPObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + NATPMPObject *self; + + self = (NATPMPObject *)type->tp_alloc(type, 0); + if (self) { + initnatpmp(&self->natpmp, 0, 0); + } + + return (PyObject *)self; +} + +static void +NATPMPObject_dealloc(NATPMPObject *self) +{ + closenatpmp(&self->natpmp); + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject * +NATPMP_externalipaddress(NATPMPObject *self) +{ + int r; + struct timeval timeout; + fd_set fds; + natpmpresp_t response; + + r = sendpublicaddressrequest(&self->natpmp); + + if (r < 0) { +#ifdef ENABLE_STRNATPMPERR + PyErr_SetString(PyExc_Exception, strnatpmperr(r)); +#endif + return NULL; + } + + do { + FD_ZERO(&fds); + FD_SET(self->natpmp.s, &fds); + getnatpmprequesttimeout(&self->natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&self->natpmp, &response); + if (r < 0 && r != NATPMP_TRYAGAIN) { +#ifdef ENABLE_STRNATPMPERR + PyErr_SetString(PyExc_Exception, strnatpmperr(r)); +#endif + return NULL; + } + } while (r == NATPMP_TRYAGAIN); + + return Py_BuildValue("s", inet_ntoa(response.pnu.publicaddress.addr)); +} + +static PyObject * +NATPMP_domapping(natpmp_t *n, unsigned short eport, unsigned short iport, + const char *protocol, unsigned int lifetime) +{ + int proto; + struct timeval timeout; + fd_set fds; + natpmpresp_t response; + int r; + + if (!strncasecmp("tcp", protocol, 3)) { + proto = NATPMP_PROTOCOL_TCP; + } else if (!strncasecmp("udp", protocol, 3)) { + proto = NATPMP_PROTOCOL_UDP; + } else { + PyErr_SetString(PyExc_Exception, "Unknown protocol"); + return NULL; + } + + r = sendnewportmappingrequest(n, proto, iport, eport, + lifetime); + + if (r < 0) { +#ifdef ENABLE_STRNATPMPERR + PyErr_SetString(PyExc_Exception, strnatpmperr(r)); +#endif + return NULL; + } + + do { + FD_ZERO(&fds); + FD_SET(n->s, &fds); + getnatpmprequesttimeout(n, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(n, &response); + if (r < 0 && r != NATPMP_TRYAGAIN) { +#ifdef ENABLE_STRNATPMPERR + PyErr_SetString(PyExc_Exception, strnatpmperr(r)); +#endif + return NULL; + } + } while (r == NATPMP_TRYAGAIN); + + return Py_BuildValue("H", response.pnu.newportmapping.mappedpublicport); +} + + +/* AddPortMapping(externalPort, protocol, internalPort, lifetime) + * protocol is 'UDP' or 'TCP' */ +static PyObject * +NATPMP_addportmapping(NATPMPObject *self, PyObject *args) +{ + unsigned short eport; + unsigned short iport; + unsigned int lifetime; + const char *protocol; + + if (!PyArg_ParseTuple(args, "HsHI", &eport, &protocol, &iport, &lifetime)) + return NULL; + + return NATPMP_domapping(&self->natpmp, eport, iport, protocol, lifetime); +} + +/* DeletePortMapping(externalPort, protocol, internalPort) + * protocol is 'UDP' or 'TCP' */ +static PyObject * +NATPMP_deleteportmapping(NATPMPObject *self, PyObject *args) +{ + unsigned short eport; + unsigned short iport; + const char *protocol; + + if (!PyArg_ParseTuple(args, "HsH", &eport, &protocol, &iport)) + return NULL; + + return NATPMP_domapping(&self->natpmp, eport, iport, protocol, 0); +} + +/* natpmp.NATPMP object Method Table */ +static PyMethodDef NATPMP_methods[] = { + {"externalipaddress", (PyCFunction)NATPMP_externalipaddress, METH_NOARGS, + "return external IP address" + }, + {"addportmapping", (PyCFunction)NATPMP_addportmapping, METH_VARARGS, + "add a port mapping" + }, + {"deleteportmapping", (PyCFunction)NATPMP_deleteportmapping, METH_VARARGS, + "delete a port mapping" + }, + {NULL} /* Sentinel */ +}; + +static PyTypeObject NATPMPType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "libnatpmp.NATPMP", /*tp_name*/ + sizeof(NATPMPObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)NATPMPObject_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "NATPMP objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + NATPMP_methods, /* tp_methods */ + NATPMP_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + NATPMPObject_new, /* tp_new */ +}; + +/* module methods */ +static PyMethodDef libnatpmp_methods[] = { + {NULL} /* Sentinel */ +}; + +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ +#define PyMODINIT_FUNC void +#endif +PyMODINIT_FUNC +initlibnatpmp(void) +{ + PyObject* m; + + if (PyType_Ready(&NATPMPType) < 0) + return; + + m = Py_InitModule3("libnatpmp", libnatpmp_methods, + "libnatpmp module."); + + Py_INCREF(&NATPMPType); + PyModule_AddObject(m, "NATPMP", (PyObject *)&NATPMPType); +} + diff --git a/ext/libnatpmp/msvc/libnatpmp.sln b/ext/libnatpmp/msvc/libnatpmp.sln new file mode 100644 index 0000000..ac746d4 --- /dev/null +++ b/ext/libnatpmp/msvc/libnatpmp.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnatpmp", "libnatpmp.vcproj", "{D59B6527-F3DE-4D26-A08D-52F1EE989301}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "natpmpc-static", "natpmpc-static.vcproj", "{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}" + ProjectSection(ProjectDependencies) = postProject + {D59B6527-F3DE-4D26-A08D-52F1EE989301} = {D59B6527-F3DE-4D26-A08D-52F1EE989301} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.ActiveCfg = Debug|Win32 + {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.Build.0 = Debug|Win32 + {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.ActiveCfg = Release|Win32 + {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.Build.0 = Release|Win32 + {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.ActiveCfg = Debug|Win32 + {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.Build.0 = Debug|Win32 + {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.ActiveCfg = Release|Win32 + {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ext/libnatpmp/msvc/libnatpmp.vcproj b/ext/libnatpmp/msvc/libnatpmp.vcproj new file mode 100644 index 0000000..9bae5c1 --- /dev/null +++ b/ext/libnatpmp/msvc/libnatpmp.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/libnatpmp/msvc/natpmpc-static.vcproj b/ext/libnatpmp/msvc/natpmpc-static.vcproj new file mode 100644 index 0000000..c2052d9 --- /dev/null +++ b/ext/libnatpmp/msvc/natpmpc-static.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/libnatpmp/natpmp-jni.c b/ext/libnatpmp/natpmp-jni.c new file mode 100644 index 0000000..feec1ce --- /dev/null +++ b/ext/libnatpmp/natpmp-jni.c @@ -0,0 +1,157 @@ +#ifdef __CYGWIN__ +#include +#define __int64 uint64_t +#endif + +#ifdef WIN32 +#include +#include +#include +#endif + +#include +#include "natpmp.h" + +#include "fr_free_miniupnp_libnatpmp_NatPmp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_init (JNIEnv *env, jobject obj, jint forcegw, jint forcedgw) { + natpmp_t *p = malloc (sizeof(natpmp_t)); + if (p == NULL) return; + + initnatpmp(p, forcegw, (in_addr_t) forcedgw); + + jobject wrapped = (*env)->NewDirectByteBuffer(env, p, sizeof(natpmp_t)); + if (wrapped == NULL) return; + + jclass thisClass = (*env)->GetObjectClass(env,obj); + if (thisClass == NULL) return; + + jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); + if (fid == NULL) return; + (*env)->SetObjectField(env, obj, fid, wrapped); +} + +JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_free (JNIEnv *env, jobject obj) { + + jclass thisClass = (*env)->GetObjectClass(env,obj); + if (thisClass == NULL) return; + + jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); + + if (fid == NULL) return; + jobject wrapped = (*env)->GetObjectField(env, obj, fid); + if (wrapped == NULL) return; + + natpmp_t* natpmp = (natpmp_t*) (*env)->GetDirectBufferAddress(env, wrapped); + + closenatpmp(natpmp); + + if (natpmp == NULL) return; + free(natpmp); + + (*env)->SetObjectField(env, obj, fid, NULL); +} + +static natpmp_t* getNatPmp(JNIEnv* env, jobject obj) { + jclass thisClass = (*env)->GetObjectClass(env,obj); + if (thisClass == NULL) return NULL; + + jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); + + if (fid == NULL) return NULL; + jobject wrapped = (*env)->GetObjectField(env, obj, fid); + if (wrapped == NULL) return NULL; + + natpmp_t* natpmp = (natpmp_t*) (*env)->GetDirectBufferAddress(env, wrapped); + + return natpmp; +} + +JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_sendPublicAddressRequest(JNIEnv* env, jobject obj) { + natpmp_t* natpmp = getNatPmp(env, obj); + if (natpmp == NULL) return -1; + + return sendpublicaddressrequest(natpmp); +} + + +JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_startup(JNIEnv* env, jclass cls) { + (void)env; + (void)cls; +#ifdef WIN32 + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(2, 2); + WSAStartup(wVersionRequested, &wsaData); +#endif +} + + +JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_sendNewPortMappingRequest(JNIEnv* env, jobject obj, jint protocol, jint privateport, jint publicport, jint lifetime) { + natpmp_t* natpmp = getNatPmp(env, obj); + if (natpmp == NULL) return -1; + + return sendnewportmappingrequest(natpmp, protocol, privateport, publicport, lifetime); +} + +JNIEXPORT jlong JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_getNatPmpRequestTimeout(JNIEnv* env, jobject obj) { + natpmp_t* natpmp = getNatPmp(env, obj); + + struct timeval timeout; + + getnatpmprequesttimeout(natpmp, &timeout); + + return ((jlong) timeout.tv_sec) * 1000 + (timeout.tv_usec / 1000); + +} + +#define SET_FIELD(prefix, name, type, longtype) { \ + jfieldID fid = (*env)->GetFieldID(env, thisClass, #name, type); \ + if (fid == NULL) return -1; \ + (*env)->Set ## longtype ## Field(env, response, fid, resp. prefix name); \ +} + +JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_readNatPmpResponseOrRetry(JNIEnv* env, jobject obj, jobject response) { + + natpmp_t* natpmp = getNatPmp(env, obj); + natpmpresp_t resp; + int result = readnatpmpresponseorretry(natpmp, &resp); + + if (result != 0) { + return result; + } + + jclass thisClass = (*env)->GetObjectClass(env, response); + if (thisClass == NULL) return -1; + + SET_FIELD(,type, "S", Short); + SET_FIELD(,resultcode, "S", Short); + + jfieldID fid = (*env)->GetFieldID(env, thisClass, "epoch", "J"); + if (fid == NULL) return -1; + (*env)->SetLongField(env, response, fid, ((jlong)resp.epoch) * 1000); + + if (resp.type == 0) { + jfieldID fid = (*env)->GetFieldID(env, thisClass, "addr", "I"); + if (fid == NULL) return -1; + (*env)->SetIntField(env, response, fid, resp.pnu.publicaddress.addr.s_addr); + + + } else { + SET_FIELD(pnu.newportmapping., privateport, "I", Int); + SET_FIELD(pnu.newportmapping., mappedpublicport, "I", Int); + + jfieldID fid = (*env)->GetFieldID(env, thisClass, "lifetime", "J"); + if (fid == NULL) return -1; + (*env)->SetLongField(env, response, fid, ((jlong) resp.pnu.newportmapping.lifetime) * 1000 * 1000); + } + return result; +} + + +#ifdef __cplusplus +} +#endif diff --git a/ext/libnatpmp/natpmp.c b/ext/libnatpmp/natpmp.c new file mode 100644 index 0000000..9843c41 --- /dev/null +++ b/ext/libnatpmp/natpmp.c @@ -0,0 +1,383 @@ +/* $Id: natpmp.c,v 1.20 2015/05/27 12:43:15 nanard Exp $ */ +/* libnatpmp +Copyright (c) 2007-2015, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifdef __linux__ +#define _BSD_SOURCE 1 +#endif +#include +#include +#if !defined(_MSC_VER) +#include +#endif +#ifdef WIN32 +#include +#include +#include +#include +#ifndef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#endif +#ifndef ECONNREFUSED +#define ECONNREFUSED WSAECONNREFUSED +#endif +#include "wingettimeofday.h" +#define gettimeofday natpmp_gettimeofday +#else +#include +#include +#include +#include +#include +#define closesocket close +#endif +#include "natpmp.h" +#include "getgateway.h" +#include + +LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw) +{ +#ifdef WIN32 + u_long ioctlArg = 1; +#else + int flags; +#endif + struct sockaddr_in addr; + if(!p) + return NATPMP_ERR_INVALIDARGS; + memset(p, 0, sizeof(natpmp_t)); + p->s = socket(PF_INET, SOCK_DGRAM, 0); + if(p->s < 0) + return NATPMP_ERR_SOCKETERROR; +#ifdef WIN32 + if(ioctlsocket(p->s, FIONBIO, &ioctlArg) == SOCKET_ERROR) + return NATPMP_ERR_FCNTLERROR; +#else + if((flags = fcntl(p->s, F_GETFL, 0)) < 0) + return NATPMP_ERR_FCNTLERROR; + if(fcntl(p->s, F_SETFL, flags | O_NONBLOCK) < 0) + return NATPMP_ERR_FCNTLERROR; +#endif + + if(forcegw) { + p->gateway = forcedgw; + } else { + if(getdefaultgateway(&(p->gateway)) < 0) + return NATPMP_ERR_CANNOTGETGATEWAY; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(NATPMP_PORT); + addr.sin_addr.s_addr = p->gateway; + if(connect(p->s, (struct sockaddr *)&addr, sizeof(addr)) < 0) + return NATPMP_ERR_CONNECTERR; + return 0; +} + +LIBSPEC int closenatpmp(natpmp_t * p) +{ + if(!p) + return NATPMP_ERR_INVALIDARGS; + if(closesocket(p->s) < 0) + return NATPMP_ERR_CLOSEERR; + return 0; +} + +int sendpendingrequest(natpmp_t * p) +{ + int r; +/* struct sockaddr_in addr;*/ + if(!p) + return NATPMP_ERR_INVALIDARGS; +/* memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(NATPMP_PORT); + addr.sin_addr.s_addr = p->gateway; + r = (int)sendto(p->s, p->pending_request, p->pending_request_len, 0, + (struct sockaddr *)&addr, sizeof(addr));*/ + r = (int)send(p->s, (const char *)p->pending_request, p->pending_request_len, 0); + return (r<0) ? NATPMP_ERR_SENDERR : r; +} + +int sendnatpmprequest(natpmp_t * p) +{ + int n; + if(!p) + return NATPMP_ERR_INVALIDARGS; + /* TODO : check if no request is already pending */ + p->has_pending_request = 1; + p->try_number = 1; + n = sendpendingrequest(p); + gettimeofday(&p->retry_time, NULL); // check errors ! + p->retry_time.tv_usec += 250000; /* add 250ms */ + if(p->retry_time.tv_usec >= 1000000) { + p->retry_time.tv_usec -= 1000000; + p->retry_time.tv_sec++; + } + return n; +} + +LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout) +{ + struct timeval now; + if(!p || !timeout) + return NATPMP_ERR_INVALIDARGS; + if(!p->has_pending_request) + return NATPMP_ERR_NOPENDINGREQ; + if(gettimeofday(&now, NULL) < 0) + return NATPMP_ERR_GETTIMEOFDAYERR; + timeout->tv_sec = p->retry_time.tv_sec - now.tv_sec; + timeout->tv_usec = p->retry_time.tv_usec - now.tv_usec; + if(timeout->tv_usec < 0) { + timeout->tv_usec += 1000000; + timeout->tv_sec--; + } + return 0; +} + +LIBSPEC int sendpublicaddressrequest(natpmp_t * p) +{ + if(!p) + return NATPMP_ERR_INVALIDARGS; + //static const unsigned char request[] = { 0, 0 }; + p->pending_request[0] = 0; + p->pending_request[1] = 0; + p->pending_request_len = 2; + // TODO: return 0 instead of sizeof(request) ?? + return sendnatpmprequest(p); +} + +LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol, + uint16_t privateport, uint16_t publicport, + uint32_t lifetime) +{ + if(!p || (protocol!=NATPMP_PROTOCOL_TCP && protocol!=NATPMP_PROTOCOL_UDP)) + return NATPMP_ERR_INVALIDARGS; + p->pending_request[0] = 0; + p->pending_request[1] = protocol; + p->pending_request[2] = 0; + p->pending_request[3] = 0; + /* break strict-aliasing rules : + *((uint16_t *)(p->pending_request + 4)) = htons(privateport); */ + p->pending_request[4] = (privateport >> 8) & 0xff; + p->pending_request[5] = privateport & 0xff; + /* break stric-aliasing rules : + *((uint16_t *)(p->pending_request + 6)) = htons(publicport); */ + p->pending_request[6] = (publicport >> 8) & 0xff; + p->pending_request[7] = publicport & 0xff; + /* break stric-aliasing rules : + *((uint32_t *)(p->pending_request + 8)) = htonl(lifetime); */ + p->pending_request[8] = (lifetime >> 24) & 0xff; + p->pending_request[9] = (lifetime >> 16) & 0xff; + p->pending_request[10] = (lifetime >> 8) & 0xff; + p->pending_request[11] = lifetime & 0xff; + p->pending_request_len = 12; + return sendnatpmprequest(p); +} + +LIBSPEC int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response) +{ + unsigned char buf[16]; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + int n; + if(!p) + return NATPMP_ERR_INVALIDARGS; + n = recvfrom(p->s, (char *)buf, sizeof(buf), 0, + (struct sockaddr *)&addr, &addrlen); + if(n<0) +#ifdef WIN32 + switch(WSAGetLastError()) { +#else + switch(errno) { +#endif + /*case EAGAIN:*/ + case EWOULDBLOCK: + n = NATPMP_TRYAGAIN; + break; + case ECONNREFUSED: + n = NATPMP_ERR_NOGATEWAYSUPPORT; + break; + default: + n = NATPMP_ERR_RECVFROM; + } + /* check that addr is correct (= gateway) */ + else if(addr.sin_addr.s_addr != p->gateway) + n = NATPMP_ERR_WRONGPACKETSOURCE; + else { + response->resultcode = ntohs(*((uint16_t *)(buf + 2))); + response->epoch = ntohl(*((uint32_t *)(buf + 4))); + if(buf[0] != 0) + n = NATPMP_ERR_UNSUPPORTEDVERSION; + else if(buf[1] < 128 || buf[1] > 130) + n = NATPMP_ERR_UNSUPPORTEDOPCODE; + else if(response->resultcode != 0) { + switch(response->resultcode) { + case 1: + n = NATPMP_ERR_UNSUPPORTEDVERSION; + break; + case 2: + n = NATPMP_ERR_NOTAUTHORIZED; + break; + case 3: + n = NATPMP_ERR_NETWORKFAILURE; + break; + case 4: + n = NATPMP_ERR_OUTOFRESOURCES; + break; + case 5: + n = NATPMP_ERR_UNSUPPORTEDOPCODE; + break; + default: + n = NATPMP_ERR_UNDEFINEDERROR; + } + } else { + response->type = buf[1] & 0x7f; + if(buf[1] == 128) + //response->publicaddress.addr = *((uint32_t *)(buf + 8)); + response->pnu.publicaddress.addr.s_addr = *((uint32_t *)(buf + 8)); + else { + response->pnu.newportmapping.privateport = ntohs(*((uint16_t *)(buf + 8))); + response->pnu.newportmapping.mappedpublicport = ntohs(*((uint16_t *)(buf + 10))); + response->pnu.newportmapping.lifetime = ntohl(*((uint32_t *)(buf + 12))); + } + n = 0; + } + } + return n; +} + +int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response) +{ + int n; + if(!p || !response) + return NATPMP_ERR_INVALIDARGS; + if(!p->has_pending_request) + return NATPMP_ERR_NOPENDINGREQ; + n = readnatpmpresponse(p, response); + if(n<0) { + if(n==NATPMP_TRYAGAIN) { + struct timeval now; + gettimeofday(&now, NULL); // check errors ! + if(timercmp(&now, &p->retry_time, >=)) { + int delay, r; + if(p->try_number >= 9) { + return NATPMP_ERR_NOGATEWAYSUPPORT; + } + /*printf("retry! %d\n", p->try_number);*/ + delay = 250 * (1<try_number); // ms + /*for(i=0; itry_number; i++) + delay += delay;*/ + p->retry_time.tv_sec += (delay / 1000); + p->retry_time.tv_usec += (delay % 1000) * 1000; + if(p->retry_time.tv_usec >= 1000000) { + p->retry_time.tv_usec -= 1000000; + p->retry_time.tv_sec++; + } + p->try_number++; + r = sendpendingrequest(p); + if(r<0) + return r; + } + } + } else { + p->has_pending_request = 0; + } + return n; +} + +#ifdef ENABLE_STRNATPMPERR +LIBSPEC const char * strnatpmperr(int r) +{ + const char * s; + switch(r) { + case NATPMP_ERR_INVALIDARGS: + s = "invalid arguments"; + break; + case NATPMP_ERR_SOCKETERROR: + s = "socket() failed"; + break; + case NATPMP_ERR_CANNOTGETGATEWAY: + s = "cannot get default gateway ip address"; + break; + case NATPMP_ERR_CLOSEERR: +#ifdef WIN32 + s = "closesocket() failed"; +#else + s = "close() failed"; +#endif + break; + case NATPMP_ERR_RECVFROM: + s = "recvfrom() failed"; + break; + case NATPMP_ERR_NOPENDINGREQ: + s = "no pending request"; + break; + case NATPMP_ERR_NOGATEWAYSUPPORT: + s = "the gateway does not support nat-pmp"; + break; + case NATPMP_ERR_CONNECTERR: + s = "connect() failed"; + break; + case NATPMP_ERR_WRONGPACKETSOURCE: + s = "packet not received from the default gateway"; + break; + case NATPMP_ERR_SENDERR: + s = "send() failed"; + break; + case NATPMP_ERR_FCNTLERROR: + s = "fcntl() failed"; + break; + case NATPMP_ERR_GETTIMEOFDAYERR: + s = "gettimeofday() failed"; + break; + case NATPMP_ERR_UNSUPPORTEDVERSION: + s = "unsupported nat-pmp version error from server"; + break; + case NATPMP_ERR_UNSUPPORTEDOPCODE: + s = "unsupported nat-pmp opcode error from server"; + break; + case NATPMP_ERR_UNDEFINEDERROR: + s = "undefined nat-pmp server error"; + break; + case NATPMP_ERR_NOTAUTHORIZED: + s = "not authorized"; + break; + case NATPMP_ERR_NETWORKFAILURE: + s = "network failure"; + break; + case NATPMP_ERR_OUTOFRESOURCES: + s = "nat-pmp server out of resources"; + break; + default: + s = "Unknown libnatpmp error"; + } + return s; +} +#endif + diff --git a/ext/libnatpmp/natpmp.def b/ext/libnatpmp/natpmp.def new file mode 100644 index 0000000..cd11003 --- /dev/null +++ b/ext/libnatpmp/natpmp.def @@ -0,0 +1,11 @@ +LIBRARY +; libnatpmp library + +EXPORTS + initnatpmp + closenatpmp + sendpublicaddressrequest + sendnewportmappingrequest + getnatpmprequesttimeout + readnatpmpresponseorretry + strnatpmperr diff --git a/ext/libnatpmp/natpmp.h b/ext/libnatpmp/natpmp.h new file mode 100644 index 0000000..7889d20 --- /dev/null +++ b/ext/libnatpmp/natpmp.h @@ -0,0 +1,219 @@ +/* $Id: natpmp.h,v 1.20 2014/04/22 09:15:40 nanard Exp $ */ +/* libnatpmp +Copyright (c) 2007-2014, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef __NATPMP_H__ +#define __NATPMP_H__ + +/* NAT-PMP Port as defined by the NAT-PMP draft */ +#define NATPMP_PORT (5351) + +#include +#if !defined(_MSC_VER) +#include +#endif /* !defined(_MSC_VER) */ + +#ifdef WIN32 +#include +#if !defined(_MSC_VER) || _MSC_VER >= 1600 +#include +#else /* !defined(_MSC_VER) || _MSC_VER >= 1600 */ +typedef unsigned long uint32_t; +typedef unsigned short uint16_t; +#endif /* !defined(_MSC_VER) || _MSC_VER >= 1600 */ +#define in_addr_t uint32_t +#include "declspec.h" +#else /* WIN32 */ +#define LIBSPEC +#include +#endif /* WIN32 */ + +/* causes problem when installing. Maybe should it be inlined ? */ +/* #include "declspec.h" */ + +typedef struct { + int s; /* socket */ + in_addr_t gateway; /* default gateway (IPv4) */ + int has_pending_request; + unsigned char pending_request[12]; + int pending_request_len; + int try_number; + struct timeval retry_time; +} natpmp_t; + +typedef struct { + uint16_t type; /* NATPMP_RESPTYPE_* */ + uint16_t resultcode; /* NAT-PMP response code */ + uint32_t epoch; /* Seconds since start of epoch */ + union { + struct { + //in_addr_t addr; + struct in_addr addr; + } publicaddress; + struct { + uint16_t privateport; + uint16_t mappedpublicport; + uint32_t lifetime; + } newportmapping; + } pnu; +} natpmpresp_t; + +/* possible values for type field of natpmpresp_t */ +#define NATPMP_RESPTYPE_PUBLICADDRESS (0) +#define NATPMP_RESPTYPE_UDPPORTMAPPING (1) +#define NATPMP_RESPTYPE_TCPPORTMAPPING (2) + +/* Values to pass to sendnewportmappingrequest() */ +#define NATPMP_PROTOCOL_UDP (1) +#define NATPMP_PROTOCOL_TCP (2) + +/* return values */ +/* NATPMP_ERR_INVALIDARGS : invalid arguments passed to the function */ +#define NATPMP_ERR_INVALIDARGS (-1) +/* NATPMP_ERR_SOCKETERROR : socket() failed. check errno for details */ +#define NATPMP_ERR_SOCKETERROR (-2) +/* NATPMP_ERR_CANNOTGETGATEWAY : can't get default gateway IP */ +#define NATPMP_ERR_CANNOTGETGATEWAY (-3) +/* NATPMP_ERR_CLOSEERR : close() failed. check errno for details */ +#define NATPMP_ERR_CLOSEERR (-4) +/* NATPMP_ERR_RECVFROM : recvfrom() failed. check errno for details */ +#define NATPMP_ERR_RECVFROM (-5) +/* NATPMP_ERR_NOPENDINGREQ : readnatpmpresponseorretry() called while + * no NAT-PMP request was pending */ +#define NATPMP_ERR_NOPENDINGREQ (-6) +/* NATPMP_ERR_NOGATEWAYSUPPORT : the gateway does not support NAT-PMP */ +#define NATPMP_ERR_NOGATEWAYSUPPORT (-7) +/* NATPMP_ERR_CONNECTERR : connect() failed. check errno for details */ +#define NATPMP_ERR_CONNECTERR (-8) +/* NATPMP_ERR_WRONGPACKETSOURCE : packet not received from the network gateway */ +#define NATPMP_ERR_WRONGPACKETSOURCE (-9) +/* NATPMP_ERR_SENDERR : send() failed. check errno for details */ +#define NATPMP_ERR_SENDERR (-10) +/* NATPMP_ERR_FCNTLERROR : fcntl() failed. check errno for details */ +#define NATPMP_ERR_FCNTLERROR (-11) +/* NATPMP_ERR_GETTIMEOFDAYERR : gettimeofday() failed. check errno for details */ +#define NATPMP_ERR_GETTIMEOFDAYERR (-12) + +/* */ +#define NATPMP_ERR_UNSUPPORTEDVERSION (-14) +#define NATPMP_ERR_UNSUPPORTEDOPCODE (-15) + +/* Errors from the server : */ +#define NATPMP_ERR_UNDEFINEDERROR (-49) +#define NATPMP_ERR_NOTAUTHORIZED (-51) +#define NATPMP_ERR_NETWORKFAILURE (-52) +#define NATPMP_ERR_OUTOFRESOURCES (-53) + +/* NATPMP_TRYAGAIN : no data available for the moment. try again later */ +#define NATPMP_TRYAGAIN (-100) + +#ifdef __cplusplus +extern "C" { +#endif + +/* initnatpmp() + * initialize a natpmp_t object + * With forcegw=1 the gateway is not detected automaticaly. + * Return values : + * 0 = OK + * NATPMP_ERR_INVALIDARGS + * NATPMP_ERR_SOCKETERROR + * NATPMP_ERR_FCNTLERROR + * NATPMP_ERR_CANNOTGETGATEWAY + * NATPMP_ERR_CONNECTERR */ +LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw); + +/* closenatpmp() + * close resources associated with a natpmp_t object + * Return values : + * 0 = OK + * NATPMP_ERR_INVALIDARGS + * NATPMP_ERR_CLOSEERR */ +LIBSPEC int closenatpmp(natpmp_t * p); + +/* sendpublicaddressrequest() + * send a public address NAT-PMP request to the network gateway + * Return values : + * 2 = OK (size of the request) + * NATPMP_ERR_INVALIDARGS + * NATPMP_ERR_SENDERR */ +LIBSPEC int sendpublicaddressrequest(natpmp_t * p); + +/* sendnewportmappingrequest() + * send a new port mapping NAT-PMP request to the network gateway + * Arguments : + * protocol is either NATPMP_PROTOCOL_TCP or NATPMP_PROTOCOL_UDP, + * lifetime is in seconds. + * To remove a port mapping, set lifetime to zero. + * To remove all port mappings to the host, set lifetime and both ports + * to zero. + * Return values : + * 12 = OK (size of the request) + * NATPMP_ERR_INVALIDARGS + * NATPMP_ERR_SENDERR */ +LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol, + uint16_t privateport, uint16_t publicport, + uint32_t lifetime); + +/* getnatpmprequesttimeout() + * fills the timeval structure with the timeout duration of the + * currently pending NAT-PMP request. + * Return values : + * 0 = OK + * NATPMP_ERR_INVALIDARGS + * NATPMP_ERR_GETTIMEOFDAYERR + * NATPMP_ERR_NOPENDINGREQ */ +LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout); + +/* readnatpmpresponseorretry() + * fills the natpmpresp_t structure if possible + * Return values : + * 0 = OK + * NATPMP_TRYAGAIN + * NATPMP_ERR_INVALIDARGS + * NATPMP_ERR_NOPENDINGREQ + * NATPMP_ERR_NOGATEWAYSUPPORT + * NATPMP_ERR_RECVFROM + * NATPMP_ERR_WRONGPACKETSOURCE + * NATPMP_ERR_UNSUPPORTEDVERSION + * NATPMP_ERR_UNSUPPORTEDOPCODE + * NATPMP_ERR_NOTAUTHORIZED + * NATPMP_ERR_NETWORKFAILURE + * NATPMP_ERR_OUTOFRESOURCES + * NATPMP_ERR_UNSUPPORTEDOPCODE + * NATPMP_ERR_UNDEFINEDERROR */ +LIBSPEC int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response); + +#ifdef ENABLE_STRNATPMPERR +LIBSPEC const char * strnatpmperr(int t); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/libnatpmp/natpmpc.1 b/ext/libnatpmp/natpmpc.1 new file mode 100644 index 0000000..5f0003d --- /dev/null +++ b/ext/libnatpmp/natpmpc.1 @@ -0,0 +1,19 @@ +.TH natpmpc 1 + +.SH NAME +natpmpc \- NAT\-PMP library test client and mapping setter. + +.SH "SYNOPSIS" +Display the public IP address: +.br +\fBnatpmpc\fP + +Add a port mapping: +.br +\fBnatpmpc\fP \-a [lifetime] + +.SH DESCRIPTION + +In order to remove a mapping, set it with a lifetime of 0 seconds. +To remove all mappings for your machine, use 0 as private port and +lifetime. diff --git a/ext/libnatpmp/natpmpc.c b/ext/libnatpmp/natpmpc.c new file mode 100644 index 0000000..611bd2d --- /dev/null +++ b/ext/libnatpmp/natpmpc.c @@ -0,0 +1,244 @@ +/* $Id: natpmpc.c,v 1.13 2012/08/21 17:23:38 nanard Exp $ */ +/* libnatpmp +Copyright (c) 2007-2011, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include +#include +#if defined(_MSC_VER) +#if _MSC_VER >= 1400 +#define strcasecmp _stricmp +#else +#define strcasecmp stricmp +#endif +#else +#include +#endif +#ifdef WIN32 +#include +#else +#include +#include +#endif +#include "natpmp.h" + +void usage(FILE * out, const char * argv0) +{ + fprintf(out, "Usage :\n"); + fprintf(out, " %s [options]\n", argv0); + fprintf(out, "\tdisplay the public IP address.\n"); + fprintf(out, " %s -h\n", argv0); + fprintf(out, "\tdisplay this help screen.\n"); + fprintf(out, " %s [options] -a [lifetime]\n", argv0); + fprintf(out, "\tadd a port mapping.\n"); + fprintf(out, "\nOption available :\n"); + fprintf(out, " -g ipv4address\n"); + fprintf(out, "\tforce the gateway to be used as destination for NAT-PMP commands.\n"); + fprintf(out, "\n In order to remove a mapping, set it with a lifetime of 0 seconds.\n"); + fprintf(out, " To remove all mappings for your machine, use 0 as private port and lifetime.\n"); +} + +/* sample code for using libnatpmp */ +int main(int argc, char * * argv) +{ + natpmp_t natpmp; + natpmpresp_t response; + int r; + int sav_errno; + struct timeval timeout; + fd_set fds; + int i; + int protocol = 0; + uint16_t privateport = 0; + uint16_t publicport = 0; + uint32_t lifetime = 3600; + int command = 0; + int forcegw = 0; + in_addr_t gateway = 0; + struct in_addr gateway_in_use; + +#ifdef WIN32 + WSADATA wsaData; + int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if(nResult != NO_ERROR) + { + fprintf(stderr, "WSAStartup() failed.\n"); + return -1; + } +#endif + + /* argument parsing */ + for(i=1; i i + 1) { + if(1 != sscanf(argv[i+1], "%u", &lifetime)) { + fprintf(stderr, "%s is not a correct 32bits unsigned integer\n", argv[i]); + } else { + i++; + } + } + break; + default: + fprintf(stderr, "Unknown option %s\n", argv[i]); + usage(stderr, argv[0]); + return 1; + } + } else { + fprintf(stderr, "Unknown option %s\n", argv[i]); + usage(stderr, argv[0]); + return 1; + } + } + + /* initnatpmp() */ + r = initnatpmp(&natpmp, forcegw, gateway); + printf("initnatpmp() returned %d (%s)\n", r, r?"FAILED":"SUCCESS"); + if(r<0) + return 1; + + gateway_in_use.s_addr = natpmp.gateway; + printf("using gateway : %s\n", inet_ntoa(gateway_in_use)); + + /* sendpublicaddressrequest() */ + r = sendpublicaddressrequest(&natpmp); + printf("sendpublicaddressrequest returned %d (%s)\n", + r, r==2?"SUCCESS":"FAILED"); + if(r<0) + return 1; + + do { + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + r = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + if(r<0) { + fprintf(stderr, "select()"); + return 1; + } + r = readnatpmpresponseorretry(&natpmp, &response); + sav_errno = errno; + printf("readnatpmpresponseorretry returned %d (%s)\n", + r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED")); + if(r<0 && r!=NATPMP_TRYAGAIN) { +#ifdef ENABLE_STRNATPMPERR + fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n", + strnatpmperr(r)); +#endif + fprintf(stderr, " errno=%d '%s'\n", + sav_errno, strerror(sav_errno)); + } + } while(r==NATPMP_TRYAGAIN); + if(r<0) + return 1; + + /* TODO : check that response.type == 0 */ + printf("Public IP address : %s\n", inet_ntoa(response.pnu.publicaddress.addr)); + printf("epoch = %u\n", response.epoch); + + if(command == 'a') { + /* sendnewportmappingrequest() */ + r = sendnewportmappingrequest(&natpmp, protocol, + privateport, publicport, + lifetime); + printf("sendnewportmappingrequest returned %d (%s)\n", + r, r==12?"SUCCESS":"FAILED"); + if(r < 0) + return 1; + + do { + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&natpmp, &response); + printf("readnatpmpresponseorretry returned %d (%s)\n", + r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED")); + } while(r==NATPMP_TRYAGAIN); + if(r<0) { +#ifdef ENABLE_STRNATPMPERR + fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n", + strnatpmperr(r)); +#endif + return 1; + } + + printf("Mapped public port %hu protocol %s to local port %hu " + "liftime %u\n", + response.pnu.newportmapping.mappedpublicport, + response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" : + (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" : + "UNKNOWN"), + response.pnu.newportmapping.privateport, + response.pnu.newportmapping.lifetime); + printf("epoch = %u\n", response.epoch); + } + + r = closenatpmp(&natpmp); + printf("closenatpmp() returned %d (%s)\n", r, r==0?"SUCCESS":"FAILED"); + if(r<0) + return 1; + + return 0; +} + diff --git a/ext/libnatpmp/setup.py b/ext/libnatpmp/setup.py new file mode 100644 index 0000000..aa774ee --- /dev/null +++ b/ext/libnatpmp/setup.py @@ -0,0 +1,18 @@ +#! /usr/bin/python +# $Id: setup.py,v 1.3 2012/03/05 04:54:01 nanard Exp $ +# +# python script to build the libnatpmp module under unix +# +# replace libnatpmp.a by libnatpmp.so for shared library usage +from distutils.core import setup, Extension +from distutils import sysconfig +sysconfig.get_config_vars()["OPT"] = '' +sysconfig.get_config_vars()["CFLAGS"] = '' +setup(name="libnatpmp", version="1.0", + ext_modules=[ + Extension(name="libnatpmp", sources=["libnatpmpmodule.c"], + extra_objects=["libnatpmp.a"], + define_macros=[('ENABLE_STRNATPMPERR', None)] + )] + ) + diff --git a/ext/libnatpmp/setupmingw32.py b/ext/libnatpmp/setupmingw32.py new file mode 100644 index 0000000..d02fdfc --- /dev/null +++ b/ext/libnatpmp/setupmingw32.py @@ -0,0 +1,17 @@ +#! /usr/bin/python +# $Id: setupmingw32.py,v 1.3 2012/03/05 04:54:01 nanard Exp $ +# python script to build the miniupnpc module under windows +# +from distutils.core import setup, Extension +from distutils import sysconfig +sysconfig.get_config_vars()["OPT"] = '' +sysconfig.get_config_vars()["CFLAGS"] = '' +setup(name="libnatpmp", version="1.0", + ext_modules=[ + Extension(name="libnatpmp", sources=["libnatpmpmodule.c"], + libraries=["ws2_32"], + extra_objects=["libnatpmp.a"], + define_macros=[('ENABLE_STRNATPMPERR', None)] + )] + ) + diff --git a/ext/libnatpmp/testgetgateway.c b/ext/libnatpmp/testgetgateway.c new file mode 100644 index 0000000..24cbe7d --- /dev/null +++ b/ext/libnatpmp/testgetgateway.c @@ -0,0 +1,57 @@ +/* $Id: testgetgateway.c,v 1.7 2012/08/21 17:13:31 nanard Exp $ */ +/* libnatpmp +Copyright (c) 2007-2011, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#ifdef WIN32 +#include +#else +#include +#include +#endif +#include "getgateway.h" + +int main(int argc, char * * argv) +{ + (void)argc; + (void)argv; + struct in_addr gatewayaddr; + int r; +#ifdef WIN32 + uint32_t temp = 0; + r = getdefaultgateway(&temp); + gatewayaddr.S_un.S_addr = temp; +#else + r = getdefaultgateway(&(gatewayaddr.s_addr)); +#endif + if(r>=0) + printf("default gateway : %s\n", inet_ntoa(gatewayaddr)); + else + fprintf(stderr, "getdefaultgateway() failed\n"); + return 0; +} + diff --git a/ext/libnatpmp/wingettimeofday.c b/ext/libnatpmp/wingettimeofday.c new file mode 100644 index 0000000..cb730e1 --- /dev/null +++ b/ext/libnatpmp/wingettimeofday.c @@ -0,0 +1,60 @@ +/* $Id: wingettimeofday.c,v 1.6 2013/09/10 20:13:26 nanard Exp $ */ +/* libnatpmp +Copyright (c) 2007-2013, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifdef WIN32 +#if defined(_MSC_VER) +struct timeval { + long tv_sec; + long tv_usec; +}; +#else +#include +#endif + +typedef struct _FILETIME { + unsigned long dwLowDateTime; + unsigned long dwHighDateTime; +} FILETIME; + +void __stdcall GetSystemTimeAsFileTime(FILETIME*); + +int natpmp_gettimeofday(struct timeval* p, void* tz /* IGNORED */) { + union { + long long ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } _now; + + if(!p) + return -1; + GetSystemTimeAsFileTime( &(_now.ft) ); + p->tv_usec =(long)((_now.ns100 / 10LL) % 1000000LL ); + p->tv_sec = (long)((_now.ns100-(116444736000000000LL))/10000000LL); + return 0; +} +#endif + diff --git a/ext/libnatpmp/wingettimeofday.h b/ext/libnatpmp/wingettimeofday.h new file mode 100644 index 0000000..1d18d9f --- /dev/null +++ b/ext/libnatpmp/wingettimeofday.h @@ -0,0 +1,39 @@ +/* $Id: wingettimeofday.h,v 1.5 2013/09/11 07:22:25 nanard Exp $ */ +/* libnatpmp +Copyright (c) 2007-2013, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef __WINGETTIMEOFDAY_H__ +#define __WINGETTIMEOFDAY_H__ +#ifdef WIN32 +#if defined(_MSC_VER) +#include +#else +#include +#endif +int natpmp_gettimeofday(struct timeval* p, void* tz /* IGNORED */); +#endif +#endif diff --git a/ext/libpqxx-7.7.3/.circleci/config.yml b/ext/libpqxx-7.7.3/.circleci/config.yml new file mode 100644 index 0000000..038d7ad --- /dev/null +++ b/ext/libpqxx-7.7.3/.circleci/config.yml @@ -0,0 +1,60 @@ +# CircleCI config for automated test builds triggered from Github. +version: 2 +jobs: + build: + docker: + - image: debian:testing +# - image: postgres:latest + environment: + - PGHOST: "/tmp" + steps: + - checkout + - run: + name: Configure apt archives + command: apt update + - run: + name: Install + command: apt install -y lsb-release python3 cmake postgresql libpq-dev postgresql-server-dev-all build-essential autoconf dh-autoreconf autoconf-archive automake cppcheck + - run: + name: Identify + command: lsb_release -a && c++ --version + - run: + name: Prepare postgres + command: | + mkdir /tmp/db && + chown postgres /tmp/db && + su postgres -c '/usr/lib/postgresql/*/bin/initdb --pgdata /tmp/db --auth trust --nosync' + - run: + name: Run postgres + command: (su postgres -c '/usr/lib/postgresql/*/bin/postgres -D /tmp/db -k /tmp' &) && sleep 5 + - run: + name: Create postgres user + command: su postgres -c "createuser -w -d root" + - run: + name: Set up database + command: createdb root + - run: + name: Autogen + command: NOCONFIGURE=1 ./autogen.sh + - run: + name: Configure + command: | + ./configure \ + --disable-documentation \ + --enable-maintainer-mode \ + --enable-audit \ + --enable-shared --disable-static \ + CXXFLAGS=-O3 + - store_artifacts: + path: config.log + - run: + name: Make + command: make -j$(nproc) + - run: + name: Test + command: PGDATA=db/data make check + - run: + name: Analyse + command: ./tools/lint --full >lint.log + - store_artifacts: + path: lint.log diff --git a/ext/libpqxx-7.7.3/.clang-format b/ext/libpqxx-7.7.3/.clang-format new file mode 100644 index 0000000..97823d8 --- /dev/null +++ b/ext/libpqxx-7.7.3/.clang-format @@ -0,0 +1,71 @@ +Language: Cpp + +AlignAfterOpenBracket: AlwaysBreak +# AllowAllArgumentsOnNextLine: true +# AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Inline +# AllowShortIfStatementsOnASingleLine: WithoutElse +# AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +# AlwaysBreakTemplateDeclarations: No +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Custom +BraceWrapping: + # AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterExternBlock: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyNamespace: false + SplitEmptyRecord: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: AfterColon +# BreakInheritanceList: AfterColon +BreakStringLiterals: true +ColumnLimit: 79 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: true +FixNamespaceComments: true +IncludeBlocks: Preserve +IndentCaseLabels: false +IndentPPDirectives: AfterHash +IndentWidth: 2 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 2 +# NamespaceIndentation: All +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +# SpaceBeforeCpp11BracedList: false +# SpaceBeforeCtorInitializerColon: true +# SpaceBeforeInheritanceColon: true +# SpaceBeforeParents: ControlStatements +# SpaceBeforeRangedBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +UseTab: Never +--- diff --git a/ext/libpqxx-7.7.3/.cmake-format b/ext/libpqxx-7.7.3/.cmake-format new file mode 100644 index 0000000..af00ef9 --- /dev/null +++ b/ext/libpqxx-7.7.3/.cmake-format @@ -0,0 +1,184 @@ +format: + _help_max_prefix_chars: + - !!python/unicode 'If the statement spelling length (including space and' + - !!python/unicode 'parenthesis) is larger than the tab width by more than this' + - !!python/unicode 'amount, then force reject un-nested layouts.' + max_prefix_chars: 10 + _help_dangle_align: + - !!python/unicode 'If the trailing parenthesis must be ''dangled'' on its own' + - !!python/unicode 'line, then align it to this reference: `prefix`: the start' + - !!python/unicode 'of the statement, `prefix-indent`: the start of the' + - !!python/unicode 'statement, plus one indentation level, `child`: align to' + - !!python/unicode 'the column of the arguments' + dangle_align: !!python/unicode 'prefix' + _help_max_subgroups_hwrap: + - !!python/unicode 'If an argument group contains more than this many sub-groups' + - !!python/unicode '(parg or kwarg groups) then force it to a vertical layout.' + max_subgroups_hwrap: 2 + _help_min_prefix_chars: + - !!python/unicode 'If the statement spelling length (including space and' + - !!python/unicode 'parenthesis) is smaller than this amount, then force reject' + - !!python/unicode 'nested layouts.' + min_prefix_chars: 4 + _help_max_pargs_hwrap: + - !!python/unicode 'If a positional argument group contains more than this many' + - !!python/unicode 'arguments, then force it to a vertical layout.' + max_pargs_hwrap: 6 + _help_max_lines_hwrap: + - !!python/unicode 'If a candidate layout is wrapped horizontally but it exceeds' + - !!python/unicode 'this many lines, then reject the layout.' + max_lines_hwrap: 2 + _help_autosort: + - !!python/unicode 'If true, the parsers may infer whether or not an argument' + - !!python/unicode 'list is sortable (without annotation).' + autosort: false + _help_line_ending: + - !!python/unicode 'What style line endings to use in the output.' + line_ending: !!python/unicode 'unix' + _help_line_width: + - !!python/unicode 'How wide to allow formatted cmake files' + line_width: 80 + _help_dangle_parens: + - !!python/unicode 'If a statement is wrapped to more than one line, then dangle' + - !!python/unicode 'the closing parenthesis on its own line.' + dangle_parens: true + _help_tab_size: + - !!python/unicode 'How many spaces to tab for indent' + tab_size: 4 + _help_always_wrap: + - !!python/unicode 'A list of command names which should always be wrapped' + always_wrap: [] + _help_require_valid_layout: + - !!python/unicode 'By default, if cmake-format cannot successfully fit' + - !!python/unicode 'everything into the desired linewidth it will apply the' + - !!python/unicode 'last, most agressive attempt that it made. If this flag is' + - !!python/unicode 'True, however, cmake-format will print error, exit with non-' + - !!python/unicode 'zero status code, and write-out nothing' + require_valid_layout: true + _help_keyword_case: + - !!python/unicode 'Format keywords consistently as ''lower'' or ''upper'' case' + keyword_case: !!python/unicode 'unchanged' + _help_layout_passes: + - !!python/unicode 'A dictionary mapping layout nodes to a list of wrap' + - !!python/unicode 'decisions. See the documentation for more information.' + layout_passes: {} + _help_enable_sort: + - !!python/unicode 'If true, the argument lists which are known to be sortable' + - !!python/unicode 'will be sorted lexicographically' + enable_sort: true +_help_markup: !!python/unicode 'Options affecting comment reflow and formatting.' +markup: + _help_literal_comment_pattern: + - !!python/unicode 'If comment markup is enabled, don''t reflow any comment block' + - !!python/unicode 'which matches this (regex) pattern. Default is `None`' + - !!python/unicode '(disabled).' + literal_comment_pattern: null + _help_hashruler_min_length: + - !!python/unicode 'If a comment line starts with at least this many consecutive' + - !!python/unicode 'hash characters, then don''t lstrip() them off. This allows' + - !!python/unicode 'for lazy hash rulers where the first hash char is not' + - !!python/unicode 'separated by space' + hashruler_min_length: 10 + _help_fence_pattern: + - !!python/unicode 'Regular expression to match preformat fences in comments' + - !!python/unicode 'default=r''^\s*([`~]{3}[`~]*)(.*)$''' + fence_pattern: !!python/unicode '^\s*([`~]{3}[`~]*)(.*)$' + _help_canonicalize_hashrulers: + - !!python/unicode 'If true, then insert a space between the first hash char and' + - !!python/unicode 'remaining hash chars in a hash ruler, and normalize its' + - !!python/unicode 'length to fill the column' + canonicalize_hashrulers: true + _help_explicit_trailing_pattern: + - !!python/unicode 'If a comment line matches starts with this pattern then it' + - !!python/unicode 'is explicitly a trailing comment for the preceeding' + - !!python/unicode 'argument. Default is ''#<''' + explicit_trailing_pattern: !!python/unicode '#<' + _help_first_comment_is_literal: + - !!python/unicode 'If comment markup is enabled, don''t reflow the first comment' + - !!python/unicode 'block in each listfile. Use this to preserve formatting of' + - !!python/unicode 'your copyright/license statements.' + first_comment_is_literal: false + _help_enable_markup: + - !!python/unicode 'enable comment markup parsing and reflow' + enable_markup: true + _help_ruler_pattern: + - !!python/unicode 'Regular expression to match rulers in comments' + - !!python/unicode 'default=r''^\s*[^\w\s]{3}.*[^\w\s]{3}$''' + ruler_pattern: !!python/unicode '^\s*[^\w\s]{3}.*[^\w\s]{3}$' + _help_enum_char: + - !!python/unicode 'What character to use as punctuation after numerals in an' + - !!python/unicode 'enumerated list' + enum_char: . + _help_bullet_char: + - !!python/unicode 'What character to use for bulleted lists' + bullet_char: '*' +_help_lint: !!python/unicode 'Options affecting the linter' +lint: + _help_function_pattern: + - !!python/unicode 'regular expression pattern describing valid function names' + function_pattern: !!python/unicode '[0-9a-z_]+' + _help_disabled_codes: + - !!python/unicode 'a list of lint codes to disable' + disabled_codes: [] + _help_min_statement_spacing: + - !!python/unicode 'Require at least this many newlines between statements' + min_statement_spacing: 1 + _help_macro_pattern: + - !!python/unicode 'regular expression pattern describing valid macro names' + macro_pattern: !!python/unicode '[0-9A-Z_]+' + _help_public_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'publicdirectory variables' + public_var_pattern: !!python/unicode '[0-9A-Z][0-9A-Z_]+' + max_statements: 50 + _help_max_conditionals_custom_parser: + - !!python/unicode 'In the heuristic for C0201, how many conditionals to match' + - !!python/unicode 'within a loop in before considering the loop a parser.' + max_conditionals_custom_parser: 2 + _help_global_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'variables with global scope' + global_var_pattern: !!python/unicode '[0-9A-Z][0-9A-Z_]+' + _help_keyword_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'keywords used in functions or macros' + keyword_pattern: !!python/unicode '[0-9A-Z_]+' + max_arguments: 5 + _help_private_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'privatedirectory variables' + private_var_pattern: !!python/unicode '_[0-9a-z_]+' + max_localvars: 15 + max_branches: 12 + _help_local_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'variables with local scope' + local_var_pattern: !!python/unicode '[0-9a-z_]+' + _help_max_statement_spacing: + - !!python/unicode 'Require no more than this many newlines between statements' + max_statement_spacing: 1 + _help_internal_var_pattern: + - !!python/unicode 'regular expression pattern describing valid names for' + - !!python/unicode 'variables with global scope (but internal semantic)' + internal_var_pattern: !!python/unicode '_[0-9A-Z][0-9A-Z_]+' + max_returns: 6 +_help_misc: !!python/unicode 'Miscellaneous configurations options.' +misc: + _help_per_command: + - !!python/unicode 'A dictionary containing any per-command configuration' + - !!python/unicode 'overrides. Currently only `command_case` is supported.' + per_command: {} +_help_parse: !!python/unicode 'Options affecting listfile parsing' +parse: + _help_additional_commands: + - !!python/unicode 'Specify structure for custom cmake functions' + additional_commands: + !!python/unicode 'foo': + !!python/unicode 'flags': + - !!python/unicode 'BAR' + - !!python/unicode 'BAZ' + !!python/unicode 'kwargs': + !!python/unicode 'HEADERS': !!python/unicode '*' + !!python/unicode 'DEPENDS': !!python/unicode '*' + !!python/unicode 'SOURCES': !!python/unicode '*' +_help_encode: !!python/unicode 'Options effecting file encoding' diff --git a/ext/libpqxx-7.7.3/.github/workflows/stale.yml b/ext/libpqxx-7.7.3/.github/workflows/stale.yml new file mode 100644 index 0000000..0983a3e --- /dev/null +++ b/ext/libpqxx-7.7.3/.github/workflows/stale.yml @@ -0,0 +1,19 @@ +name: Mark stale issues and pull requests + +on: + schedule: + - cron: "30 1 * * *" + +jobs: + stale: + + runs-on: ubuntu-latest + + steps: + - uses: actions/stale@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'There has been no activity on this ticket. Consider closing it.' + stale-pr-message: 'There has been no activity on this pull request. Complete it or drop it.' + stale-issue-label: 'no-issue-activity' + stale-pr-label: 'no-pr-activity' diff --git a/ext/libpqxx-7.7.3/.gitignore b/ext/libpqxx-7.7.3/.gitignore new file mode 100644 index 0000000..d798c9d --- /dev/null +++ b/ext/libpqxx-7.7.3/.gitignore @@ -0,0 +1,49 @@ +autom4te.cache +build-*.out +ChangeLog +CMakeFiles/CMakeTmp +confdefs.h +config.log +config.status +conftest +conftest.cpp +conftest.err +doc/_build +doc/Doxyfile +doc/html/Reference/*.css +doc/html/Reference/*.html +doc/html/Reference/*.js +doc/html/Reference/*.png +doc/html/Reference/*.map +doc/html/Reference/*.md5 +doc/reference-stamp +include/pqxx/config-*-*.h +include/pqxx/config.h +include/pqxx/stamp-h1 +libpqxx.pc +libpqxx-*.tar.gz +libtool +pqxx-config +pqxxlo.txt +test/pqxxlo.txt +tools/pqxxthreadsafety +tools/rmlo +README +win32/common +**/Makefile +**/*.la +**/*.lo +**/*.o +**/*.out +**/.*.swp +**/.swp +**/*.tmp +**/.deps +**/.libs +**/*~ +**/lint.log +**/lint.trs +**/runner +**/runner.log +**/runner.trs +**/test-suite.log diff --git a/ext/libpqxx-7.7.3/.lgtm.yml b/ext/libpqxx-7.7.3/.lgtm.yml new file mode 100644 index 0000000..d53664e --- /dev/null +++ b/ext/libpqxx-7.7.3/.lgtm.yml @@ -0,0 +1,9 @@ +# Config file for lgtm.com static analysis. + +path_classifiers: + test: + - test + generated: + - aclocal.m4 + - configure + - ltmain.sh diff --git a/ext/libpqxx-7.7.3/.lift/ignoreFiles b/ext/libpqxx-7.7.3/.lift/ignoreFiles new file mode 100644 index 0000000..8c6c7a1 --- /dev/null +++ b/ext/libpqxx-7.7.3/.lift/ignoreFiles @@ -0,0 +1,3 @@ +# Make Sonatype Lift ignore these generated files. +configure +config/* diff --git a/ext/libpqxx-7.7.3/AUTHORS b/ext/libpqxx-7.7.3/AUTHORS new file mode 100644 index 0000000..6a922e9 --- /dev/null +++ b/ext/libpqxx-7.7.3/AUTHORS @@ -0,0 +1,4 @@ +Jeroen T. Vermeulen. Wrote the code. +Ray Dassen. Did most of the autoconf etc. stuff. + +Lots of others helped with various other contributions. diff --git a/ext/libpqxx-7.7.3/BUILDING-cmake.md b/ext/libpqxx-7.7.3/BUILDING-cmake.md new file mode 100644 index 0000000..48b1e79 --- /dev/null +++ b/ext/libpqxx-7.7.3/BUILDING-cmake.md @@ -0,0 +1,272 @@ +Building using CMake +==================== + +The build requires the full PostgreSQL development package. That package must +be installed before you can build libpqxx. + +The instructions will assume that you're working from a command-line shell. +If you prefer to work from an IDE, you'll have to know how your IDE likes to +do things, and you'll want to follow the shell instructions as a guide. + +I'm not too familiar with CMake, and this build relies heavily on contributions +from users. If you see something wrong here, please file a bug and explain, in +simple words, what needs changing and why. + + +Quick start +----------- + +If you just want to get it built and installed quickly, run `cmake` from the +root of the libpqxx source tree. This configures your build. + +Then compile libpqxx by running: + +```shell + cmake --build . +``` + +To install in the default location: + +```shell + cmake --install . +``` + + +Stages +------ + +I'll explain the main build steps in more detail below, but here's a quick +rundown: +1. Configure +2. Compile +3. Test +4. Install +5. Use + +The Test step is optional. + + +Configure +--------- + +Run `cmake` to configure your build. It figures out various parameters, such +as where libpq and its headers are, which C++ features your compiler supports, +and which options your compiler needs. CMake generates configuration for your +build tool: `Makefile`s for `make`, or a Solution (".sln") file for MSVC's +`msbuild`, and so on. + +At this stage you can also override those options yourself. e.g. to instruct +the compiler to look for libpq in a non-standard place, or to use a different +compiler, or pass different compiler flags. Don't try to specify those while +doing the actual compile; set them once when running `cmake`. + +Let's say `$BUILD` is the directory where you want to build libpqxx, and +`$SRC` is where its source code is. So for example, the readme file will be at +`$SRC/README.md`. + +In the simplest case, you just do: + +```shell + cd $BUILD + cmake $SRC +``` + +Add CMake options as needed. There's more about the options below. I'll also +explain the two directories. + + +### Cheat sheet + +Here are some popular `cmake` options for libpqxx: +* `-DSKIP_BUILD_TEST=on` skips compiling libpqxx's tests. +* `-DBUILD_SHARED_LIBS=on` to build a shared library. +* `-DBUILD_SHARED_LIBS=off` to build a static library. +* `-DBUILD_DOC=on` to build documentation. +* `-DINSTALL_TEST=on` to install test executor binary. + +On Windows, I recommend building libpqxx as a shared library and bundling it +with your application. On other platforms I would prefer a static library. + +Building the documentation requires some tools to be installed. It takes at +least Doxygen, but there's no list of requirements. The way to get this set up +is to just try it and see what it's missing. + + +### Generators + +You can also choose your own build tool by telling CMake to use a particular +"generator." For example, here's how to force use of `make`: + +```shell + cmake -G 'Unix Makefiles' +``` + +Or if you prefer to build using `ninja` instead: + +```shell + cmake -G Ninja +``` + +There are many more options. You may prefer yet a different build tool. + + +### Finding libpq + +The CMake step tries to figure out where libpq is, using Cmake's `find_package` +function. If that doesn't work, or if you want a libpq in a different location +from the one it finds, there are two ways to override it. + +The first is to set the individual include and link paths. + +To make the build look for the libpq headers in some directory `$DIR`, add +these options: +* `-DPostgreSQL_TYPE_INCLUDE_DIR=$DIR` +* `-DPostgreSQL_INCLUDE_DIR=$DIR` + +To make the build look for the libpq library binary in a directory `$DIR`, add +this option: +* `-DPostgreSQL_LIBRARY_DIR=$DIR` + +The second, easier way requires CMake 3.12 or better. Here, you specify a path +to a full PostgreSQL build tree. You do this (again for some directory `$DIR`) +by simply passing this cmake option: `-DPostgreSQL_ROOT=$DIR` + + +### Source and Build trees + +Where should you run `cmake`? + +Two directories matter when building libpqxx: the _source tree_ (where the +libpqxx source code is) and the _build tree_ (where you want your build +artefacts). Here I will call them `$SRC` and `$BUILD`, but you can call them +anything you like. + +They can be one and the same, if you like. It's convenient, but less clean, as +source code and build artefacts will exist in the same directory tree. If +you're going to delete the source tree after installing, of course it's fine to +make a mess in there. + + +Compile +------- + +To compile, run: + +```shell + cmake --build $BUILD +``` + +(Where `$BUILD` is again the directory where you wish to do the build.) + +This command will invoke your build tool. Other ways to do the same thing +would be... +* With Unix Makefiles: `make` +* With Ninja: `ninja` +* With Visual Studio: `msbuild libpqxx.sln` +* etc. + +Depending on your build tool, you may want to speed this up by adding an option +like `-j 16`, where `16` is an example of how many processes you might want to +run in parallel. The optimal number depends on your available CPUs and memory. +If you have enough memory, usually the number of CPUs will be a good starting +point for the right number. Don't use this option with Ninja though. It +figures things out for itself. + + +Test +---- + +Of course libpqxx comes with a test suite, to check that the library is +functioning correctly. + +You can run it, but there's one caveat: you need to give it a database where it +can log in, without a password or any other parameters, and try out various +things. + +And when I say you need to "give" it a database, I really mean "give." The +test suite will create and drop tables. Those will all have names prefixed +with "pqxx", so it's probably safe to use a database you already had, but if +any of the items in your database happen to have names starting with `pqxx`, +tough luck. They're fair game. + +Enter this in your shell to build and run the tests: + +```shell + test/runner +``` + + +### Configuring the test database + +But what if you do need a password to log into your test database? Or, what if +it's running on a different system so you need to pass that machine's address? +What if it's not running on the default port? + +You can set these parameters for the test suite, or for any other libpq-based +application, using the following environment variables. (They only set default +values, so they won't override parameters that the application sets in some +other way.) +* `PGHOST` — the IP address where we can contact the database's socket. Or + for a Unix domain socket, its absolute path on the filesystem. +* `PGPORT` — TCP port number on which we can connect to the database. +* `PGDATABASE` — the name of the database to which you wish to connect. +* `PGUSER` — user name under which you wish to log in on the database. +* `PGPASSWORD` — user name's password for accessing the database. + +See the full list at https://www.postgresql.org/docs/current/libpq-envars.html + +**Be careful with passwords,** by the way. Depending on your operating system +and configuration, an attacker with access to your machine could try to read +your password if you set it on the command line: +* Your shell may keep a log of the commands you have entered. +* Environment variables may be visible to other users on the system. + +If at all possible, rely on postgres "peer authentication." Once set up, it is +both more secure and more convenient than passwords. + + +Install +------- + +Once you've built libpqxx, CMake can also help you install the library and +headers on your system. The default installation location will vary from one +operating system to another, but you can set it explicitly. + +Let's say you've got your finished build in `$BUILD`, and you want to install +it to your system's default install location. The command for this is: + +```shell + cmake --install $BUILD +``` + +But you may want to install to some other location. Let's call it `$DEST`. +`$DEST` might be something like `/usr/local` on a Unix-like system, or +something like `D:\Software` on a Windows system. + +To install to `$DEST`, run: + +```shell + cmake --install $BUILD --prefix $DEST +``` + + +Use +--- + +Other projects can include libpqxx in their CMake builds. + +`@abrownsword` uses this configuration: + +```cmake + set(libpqxxdir "libpqxx-${LIBVERSION}") # LIBVERSION set above + set(SKIP_BUILD_TEST on) + set(BUILD_SHARED_LIBS OFF) + + # Used this instead of FindLibrary. + # Setting PostgresSQL_INCLUDE_DIRS externally. + set(PostgreSQL_FOUND true) + set(PostgresSQL_INCLUDE_DIR ${PostgresSQL_INCLUDE_DIRS}) + set(PostgresSQL_TYPE_INCLUDE_DIR ${PostgresSQL_INCLUDE_DIRS}) + + add_subdirectory(${libpqxxdir}) +``` diff --git a/ext/libpqxx-7.7.3/BUILDING-configure.md b/ext/libpqxx-7.7.3/BUILDING-configure.md new file mode 100644 index 0000000..7c63f5b --- /dev/null +++ b/ext/libpqxx-7.7.3/BUILDING-configure.md @@ -0,0 +1,275 @@ +Building using `configure` +========================== + +The build requires `libpq`, the C client library for PostgreSQL. This library +must be installed before you can build libpqxx. You'll need the headers as +well as the library binary. + +The instructions will assume that you're working from a command-line shell. +If you prefer to work from an IDE, you'll have to know how your IDE likes to +do things, and you'll want to follow the shell instructions as a guide. + + +Quick start +----------- + +If you just want to get it built and installed quickly, try: + +```shell + ./configure + make + sudo make install +``` + +Want more detail? Read on. + + +Stages +------ + +I'll explain the main build steps in more detail below, but here's a quick +overview: +1. Configure +2. Compile +3. Test +4. Install + +The Test step is optional. + + +Configure +--------- + +The `configure` script configures your build. It figures out various +parameters, such as where libpq and its headers are, which C++ features your +compiler supports, and which options your compiler needs. It generates +Makefiles, which in turn tell the `make` utility how to perform tasks such as +compiling libpqxx, running tests, cleaning up after itself, and installing +libpqxx. + +The `configure` step is also where you can set these options, e.g. to instruct +the compiler to look for libpq in a non-standard place, or to use a different +compiler, or pass different compiler flags. Don't try to specify those while +doing the actual compile; set them once when running `configure`. + +Let's say `$BUILD` is the directory where you want to build libpqxx, and +`$SRC` is where its source code is. So for example, the readme file will be at +`$SRC/README.md`. + +In the simplest case, you just do: + +```shell + cd $BUILD + $SRC/configure +``` + +Add `configure` options as needed. There's more about the options below, or in +the output of `configure --help`. I'll also explain the two directories. + + +### Cheat sheet + +Here are some popular `configure` options: +* `--disable-documentation` skips building of the documentation. +* `CXXFLAGS=-O0` disables optimisation. Slower code, but faster build. +* `CXXFLAGS=-O3` asks for _more_ optimisation. Faster code, slower build. +* `CXX=clang++` compiles with `clang++` as the compiler. +* `--enable-maintainer-mode` makes the compiler more pedantic about the code. +* `--enable-audit` enables expensive run-time checks for debugging. +* `--with-postgres-lib=$DIR` looks for libpq in `$DIR`. +* `--with-postgres-include=$DIR` looks for the libpq headers in `$DIR`. +* `--prefix=$PATH` prepares to install libpqxx in `$PATH`. +* `--enable-shared` enables compilation of libpqxx as a shared library. +* `--disable-shared` disbles compilation of libpqxx as a shared library. +* `--enable-static` enables compilation of libpqxx as a static library. +* `--disable-static` disables compilation of libpqxx as a static library. +* `--help` shows you a lot more of the options. + +So for example, to get a very quick build but produce very inefficient code: + +```shell + ./configure --disable-documentation CXXFLAGS=-O0 +``` + + +Or if you want to pull out all the stops to find problems in the code: + +```shell + ./configure --enable-maintainer-mode --enable-audit CXXFLAGS=-O3 +``` + +(Requesting `-O3` optimisation will make some compilers perform extra analysis +which may, as a side effect, cause them to notice and warn about certain kinds +of mistakes in the code, such as occasionally-unused variables.) + + +### Finding libpq + +One of `configure`'s most important jobs in the libpqxx build is to find the +headers and library for libpq. It has three ways of finding those: +1. Asking a popular tool called `pkg-config`, if installed. +2. Asking postgres' deprecated `pg_config` tool, if installed. +3. Through explicit command-line options to `configure`. + +The explicit command-line options are `--with-postgres-lib` (for the libpq +library binary) and `--with-postgres-include` (for the libpq headers). + +If you want to use a version of libpq that's not installed in a standard +location, e.g. if you're cross-compiling to produce a binary for a different +CPU architecture than your native system's, use the explicit options. + + +### Where does the `configure` script come from? + +I didn't write the `configure` script. It was generated by GNU `autoconf` and +related GNU tools. There's a script to re-generate it, called `autogen.sh`. + +The contents of `configure` are based on a higher-level script called +`configure.ac`. This is where I script checks for specific features in libpq +or the compiler. The `configure` script adds a lot of built-in items that I +don't need to worry about, such as figuring out exactly how your build tools +work. + +Don't try to debug `configure` yourself if you can help it. It's very hard to +read, partly because it's automatically generated, but also because it is +engineered to work with an extremely broad range of shells, compilers, tools, +and operating systems. If you're going to do a "deep dive," try looking at +`configure.ac` instead. + + +### Source and Build trees + +Where should you run `configure`? + +Two directories matter when building libpqxx: the _source tree_ (where the +libpqxx source code is) and the _build tree_ (where you want your build +artefacts). Here I will call them `$SRC` and `$BUILD`, but you can call them +anything you like. + +They can be one and the same, if you like. It's convenient, but less clean, as +source code and build artefacts will exist in the same directory tree. If +you're going to delete the source tree after installing, of course it's fine to +make a mess in there. + + +Compile +------- + +To start the compile, run the `make` tool. It will go through all the steps to +produce a libpqxx library binary. + +Beware though, it only runs _one_ compiler process at a time. That could take +a while. Use the `-j` option to make it run concurrent processes, e.g.: + +```shell + make -j8 +``` + +Very roughly speaking, it's probably fastest if you run one process per CPU +core in your system. If you have the `nproc` utility installed: + +```shell + make -j$(nproc) +``` + +If you want a very fast build and don't mind missing out on efficient code or +documentation, tweak the Configure step above by adding `configure` options +like `CXXFLAGS=-O0` and `--disable-documentation`. + + +Test +---- + +Of course libpqxx comes with a test suite, to check that the library is +functioning correctly. + +You can run it, but there's one caveat: you need to give it a database where it +can log in, without a password or any other parameters, and try out various +things. + +And when I say you need to "give" it a database, I really mean "give." The +test suite will create and drop tables. Those will all have names prefixed +with "pqxx", so it's probably safe to use a database you already had, but if +any of the items in your database happen to have names starting with `pqxx`, +tough luck. They're fair game. + +Enter this in your shell to build and run the tests: + +```shell + make check +``` + +As with compiling, use the `-j` option to make better use of your CPUs. For +example: + +```shell + make check -j$(nproc) +``` + + +### Configuring the test database + +But what if you do need a password to log into your test database? Or, what if +it's running on a different system so you need to pass that machine's address? +What if it's not running on the default port? + +You can set these parameters for the test suite, or for any other libpq-based +application, using the following environment variables. (They only set default +values, so they won't override parameters that the application sets in some +other way.) +* `PGHOST` — the IP address where we can contact the database's socket. Or + for a Unix domain socket, its absolute path on the filesystem. +* `PGPORT` — +* `PGDATABASE` — the name of the database to which you wish to connect. +* `PGUSER` — user name under which you wish to log in on the database. +* `PGPASSWORD` — user name's password for accessing the database. + +See the full list at https://www.postgresql.org/docs/current/libpq-envars.html + +**Be careful with passwords,** by the way. Depending on your operating system +and configuration, an attacker with access to your machine could try to read +your password if you set it on the command line: +* Your shell may keep a log of the commands you have entered. +* Environment variables may be visible to other users on the system. + +If at all possible, rely on postgres "peer authentication." Once set up, it is +both more secure and more convenient than passwords. + + +Install +------- + +Installing libpqxx will install the library and headers in a location chosen at +the time you can the `configure` script. On some systems it defaults to the +`/usr/local/` tree, but it may be different in your environment. Or, use the +`configure` script's `--prefix` option to set an install location. + +(If you want to see exactly what happens, you can run any `make` command line +with the `-n` option, which means: don't actually do this, but print all the +commands you would execute if you did. It's a lot of output though.) + +To install, ensure that you have sufficient privileges to write the files to +their install locations, and run: + +```shell + make install +``` + +Save your build tree somewhere, so that you will be able to undo installation +in the future: + +```shell + make uninstall +``` + +When using the library, make sure the libpqxx headers are in your compiler's +include path. (You will no longer need the libpq headers at that time.) + +Also, building an application which uses libpqxx, make sure the libpqxx library +binary is in your compiler's library search path. And if the library binary is +a shared library, you'll also need it in your loader's search path when running +your application. + +This last part goes for libpq as well: when using libpq, make sure you have +the libpq library binary in your compiler's library search path, and if it's a +shared library, also have it in your loader's search path when running. diff --git a/ext/libpqxx-7.7.3/CMakeLists.txt b/ext/libpqxx-7.7.3/CMakeLists.txt new file mode 100644 index 0000000..55b3c4d --- /dev/null +++ b/ext/libpqxx-7.7.3/CMakeLists.txt @@ -0,0 +1,66 @@ +cmake_minimum_required(VERSION 3.8) + +file(READ VERSION VER_FILE_CONTENT) +string(STRIP ${VER_FILE_CONTENT} VER_FILE_CONTENT) + +project( + libpqxx + VERSION ${VER_FILE_CONTENT} + LANGUAGES CXX +) + +if(NOT "${CMAKE_CXX_STANDARD}") + set(CMAKE_CXX_STANDARD 17) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +option(BUILD_DOC "Build documentation" OFF) + +if(NOT SKIP_BUILD_TEST) + option(BUILD_TEST "Build all test cases" ON) +endif() + +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) +include(config) + +add_subdirectory(src) +add_subdirectory(include) +if(BUILD_DOC) + add_subdirectory(doc) +endif() +if(BUILD_TEST) + add_subdirectory(test) +endif() + +# installation +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config-version.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) +install(FILES cmake/libpqxx-config.cmake + "${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config-version.cmake" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libpqxx +) +install( + EXPORT libpqxx-targets + NAMESPACE libpqxx:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libpqxx +) +# Build tree export +export( + EXPORT libpqxx-targets + NAMESPACE libpqxx:: + FILE ${CMAKE_CURRENT_BINARY_DIR}/libpqxx-targets.cmake +) +configure_file( + cmake/libpqxx-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/libpqxx-config.cmake + COPYONLY +) +# Package generation +set(CPACK_GENERATOR TGZ) +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +include(CPack) diff --git a/ext/libpqxx-7.7.3/COPYING b/ext/libpqxx-7.7.3/COPYING new file mode 100644 index 0000000..8a566aa --- /dev/null +++ b/ext/libpqxx-7.7.3/COPYING @@ -0,0 +1,27 @@ +Copyright (c) 2000-2022 Jeroen T. Vermeulen. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the author, nor the names of other contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/ext/libpqxx-7.7.3/Makefile.am b/ext/libpqxx-7.7.3/Makefile.am new file mode 100644 index 0000000..cd93a57 --- /dev/null +++ b/ext/libpqxx-7.7.3/Makefile.am @@ -0,0 +1,23 @@ +SUBDIRS = include src test tools config doc +EXTRA_DIST = autogen.sh configitems README.md VERSION requirements.json + +MAINTAINERCLEANFILES = \ + Makefile.in aclocal.m4 config.h.in config.log configure stamp-h.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libpqxx.pc + +TESTS = tools/lint + + +# Generate ChangeLog from git history. It goes all the way back through +# the project's git, bzr, svn, and cvs days. +dist-hook: ChangeLog + +ChangeLog: configure.ac + git log --stat --name-only --date=short --abbrev-commit >$@ + + +# We use README.md, but automake expects plain README. +README: README.md + ln -s $< $@ diff --git a/ext/libpqxx-7.7.3/Makefile.in b/ext/libpqxx-7.7.3/Makefile.in new file mode 100644 index 0000000..f6798aa --- /dev/null +++ b/ext/libpqxx-7.7.3/Makefile.in @@ -0,0 +1,1253 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h +CONFIG_CLEAN_FILES = libpqxx.pc compile_flags +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope check recheck distdir distdir-am dist dist-all \ + distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +RECHECK_LOGS = $(TEST_LOGS) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/compile_flags.in \ + $(srcdir)/libpqxx.pc.in $(top_srcdir)/config/compile \ + $(top_srcdir)/config/config.guess \ + $(top_srcdir)/config/config.sub \ + $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \ + $(top_srcdir)/config/missing \ + $(top_srcdir)/config/mkinstalldirs \ + $(top_srcdir)/config/test-driver AUTHORS COPYING ChangeLog \ + INSTALL NEWS README README.md +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +SUBDIRS = include src test tools config doc +EXTRA_DIST = autogen.sh configitems README.md VERSION requirements.json +MAINTAINERCLEANFILES = \ + Makefile.in aclocal.m4 config.h.in config.log configure stamp-h.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libpqxx.pc +TESTS = tools/lint +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .log .test .test$(EXEEXT) .trs +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +libpqxx.pc: $(top_builddir)/config.status $(srcdir)/libpqxx.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +compile_flags: $(top_builddir)/config.status $(srcdir)/compile_flags.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +tools/lint.log: tools/lint + @p='tools/lint'; \ + b='tools/lint'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-recursive +all-am: Makefile $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgconfigDATA + +.MAKE: $(am__recursive_targets) check-am install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-TESTS check-am clean clean-cscope \ + clean-generic clean-libtool cscope cscopelist-am ctags \ + ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \ + dist-lzip dist-shar dist-tarZ dist-xz dist-zip dist-zstd \ + distcheck distclean distclean-generic distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am recheck tags tags-am uninstall uninstall-am \ + uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +# Generate ChangeLog from git history. It goes all the way back through +# the project's git, bzr, svn, and cvs days. +dist-hook: ChangeLog + +ChangeLog: configure.ac + git log --stat --name-only --date=short --abbrev-commit >$@ + +# We use README.md, but automake expects plain README. +README: README.md + ln -s $< $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/NEWS b/ext/libpqxx-7.7.3/NEWS new file mode 100644 index 0000000..102716c --- /dev/null +++ b/ext/libpqxx-7.7.3/NEWS @@ -0,0 +1,1040 @@ +7.7.3 + - Fix up more damage done by auto-formatting. + - New `result::for_each()`: simple iteration and conversion of rows. (#528) + - Add some missing headers in ``. (#551) + - More strictness in `header-pre.hxx`/`header-post.hxx` checking. + - Disallow nesting of `ignore-deprecated` blocks. + - Deprecate `exec` functions' `desc` parameter. + - Fix `placeholders` documentation. (#557) + - Strip `const` and references from `value_type`. (#558) + - Get tests running on appveyor. (#560) + - Fix broken nonblocking connection on Windows. (#560) +7.7.2 + - Fix up damage done by auto-formatting. +7.7.1 + - When you build libpqxx, configure the compiler's C++ version yourself! + - Finally fix a long-standing silly warning in autogen. + - Fix `digit_to_number` not being found on some comilers. (#518, #519) + - In audit mode, define `_FORTIFY_SOURCE` to enable some extra checks. + - Make more functions `constexpr`. Nothing particularly useful though. + - Make more functions `noexcept`. + - Move constructor & assignment for `result`. + - Support LGTM.com and Facebook "infer" static analysis. + - Deprecated `set_variable`/`get_variable` on `transaction_base`. + - (Design unearthed warts in SQL variables, which were then fixed.) + - Set/get session variables on `connection`: `set_session_var`/`get_var`. + - Set/get local variables: execute SQL statements. + - When using `select()`, include `` if available. +7.7.0 + - Fix `stream_to` for differing table/client encodings. (#473) + - Use `[[likely]]` & `[[unlikely]]` only in C++20, to silence warnings. + - Fix clang "not a const expression" error in Windows. (#472) + - Fix warnings about `[[likely]]` in `if constexpr`. (#475) + - Clearer error for ambiguous string conversion of `char` type. (#481) + - Pseudo-statement in `prepare()` error was for the wrong statement. (#488) + - New class, `connecting` for nonblocking connection to the database. (#487) + - New class, `range` for SQL range types. (#490) + - Replace `std::isdigit` with a safer alternative. + - Support string conversions for `std::chrono::year_month_day`. (#492) + - Helper for implementing string traits: `generic_to_buf`. + - Support `result::at(row_num, col_num)`. + - Support `result[row_num, col_num]` if the compiler allows it. + - Work around broken `std::filesystem::path` in MinGW. (#498) + - Fix leak when getting client encoding fails. (#500) + - Use `std::cmp_greater` etc. when available. Saves some ugly casts. + - Move `result_iterator.hxx` into `pqxx/include/internal/`. + - Move `compiler-public.hxx` into `pqxx/include/internal/`. + - Add script for updating copyright strings. + - Make `tools/lint` figure out source directory by itself. + - Pass the actual C++ version to `tools/lint`, not the baseline one. + - Re-enable pyflakes testing in `tools/lint`. + - Make more functions `[[nodiscard]]`. + - Qualified some member functions as lvalue or rvalue. + - Don't run clang-tidy by default. Compatibility issues with gcc options. + - Describe version requirements in a JSON file, `requirements.json`. + - Doxygen documentation now uses the (Doxygen-extended) Markdown format. + - Build docs in `doc/html/`, no longer in `doc/html/Reference/`. + - Disable some `std::filesystem` features on Windows. + - Shut up stupid Visual Studio warnings. + - On gcc, mark rarely-used functions as "cold," to be optimised for size. + - Glyph scanning for GB18030 encoding was utterly broken. (#517) +7.6.0 + - Removed bad string conversion to `std::basic_string_view`. (#463) + - Add C++20 concepts: `binary`, `char_string`, `char_strings`. + - Generalise binary strings to any contiguous range of `std::byte`. + - Mark `zview` as a view and as a borrowed range. + - Save a copy step on string fields in `stream_to`. + - New helper: `pqxx::value_type`. + - New helper: `pqxx::binary_cast`. (#450) + - Some escaping functions now have "into my buffer" variants. + - More generic escaping functions, supporting more types of binary. + - In C++20, accept generic columns list for `stream_to`. (#447) + - Renamed `` to ``. + - Deprecated `dynamic_params` in favour of `params`. + - `pqxx::params::append_multi()` now calls `reserve()` if possible. + - `pqxx::params::size()` is now `noexcept` (but sadly, `ssize()` is not). + - Helper for generating parameter placeholders `$1`, `$2`, etc. (#443) + - Now requires support for C++14 `[[deprecated]]` attribute. + - Deprecated `unesc_raw()` with `unesc_bin()` variants. + - Once `unesc_raw()` is gone, we'll support only the hex escape format. + - Work around broken `thread_local` in MinGW gcc < 11.1. + - `pqxx::blob` now supports `std::filesystem::path`. + - Fixed check against header/lib version mismatch: `check_pqxx_version_7_6` + - Deprecated result slicing. Expect `row::slice()` to disappear. + - More complete documentation, of cursors in particular. +7.5.2 + - **Actual serious bug.** `blob::read(std::vector<...>)` was broken. +7.5.1 + - Fixed some Visual Studio warnings. + - Missed a bit in working around MinGW's broken ``. + - Deprecated more obsolete representations of binary data. Use `std::byte`. + - New script `tools/deprecations` lists files that use deprecated code. + - Added automake-generated `config/compile` to revision control. +7.5.0 + - Now requires `std::variant` support! No longer works with gcc7. + - When implementing a string conversion, consider specialising `param_format`. + - Stop "aborting" nontransaction on closing. (#419) + - Silence an overzealous Visual C++ warning. (#418) + - Starting support for C++20 `std::span`. + - New `blob::read()` using `std::span`. (#429) + - New `params` class lets you build parameter lists incrementally. (#387) + - Pass `std::vector` params in binary format. + - Dropped legacy tests 31 and 49 to work around clang C++20 bug. + - Fixed `stream_to` test failure in non-English locales. (#440) + - Clarify `transaction_base::stream` documentation. (#423) + - Avoid `` on MinGW; it's broken there. (#336, #398, #424, #441) +7.4.1 + - Missing includes; broke macOS clang build. (#416) +7.4.0 + - Work around Visual Studio 2017 bug with `[[deprecated]]`. (#405, #406) + - Work around eternal Windows bug with `max` macro yet again. (#101) + - Prepare for C++20 `std::ssize()`. + - Dropped test12, which didn't add much and tried to read null strings. + - Support string conversion for `std::monostate`. (#409) + - Consistent "named constructors" for `stream_to` and `stream_from`. + - New `table_path` type. + - New `connection` methods `quote_table` and `quote_columns`. + - Lots of deprecated stream constructors. + - `pqxx::row::swap()` now finally has the `deprecated` attribute. + - Finally deprecated a bunch of `field`, `row`, and `result` constructors. + - Exposed `transaction_focus` marker class. +7.3.1 + - New, simpler API for large objects: `blob` ("binary large object"). + - `largeobject` and friends are now deprecated. + - Fix visibility issue on gcc/clang, especially on macOS. (#395) + - Use "pure" & "visibility" attributes if they work, regardless of compiler. + - More deprecated items now have the `[[deprecated]]` attribute. + - Document the concept of transaction focus. + - Error messages more often report query description, if given. + - Suppress spurious deprecation messages on Visual Studio. (#402) + - Correct error when prepared/param statement clashes with tx focus. (#401) + - `from_stream` with `from_query` now has a convenient factory function. + - Removed some obsolete scripts from the `tools/` directory. +7.3.0 + - `stream_to` now quotes and escapes its table name. + - Removed `transaction_base::classname()`. Did anyone ever use it? + - Internal reorg of the `transaction` and `transactionfocus` hierarchies. + - Removed the only case of virtual inheritance, related to `namedclass`. + - Internal `concat()` for faster, simpler string concatentation. + - Fix compile omission in string conversions for `nullptr_t`. + - `pqxx::size_buffer()` can now size multiple values at once. + - `multi_to_string()` to convert multiple values into one `std::string`. + - Implicit `zview` constructor from `char const *`. (#389) + - Many `std::string&` parameters are now `zview` or `std::string_view`. + - Now checking statement parameter lengths for overflow. + - `#include ` in connection.cxx. (#394) +7.2.1 + - Fix infinite loop in converting `char *` to string. (#377) + - Deprecated `namedclass`. + - Convert an entire row using `row::as()`. + - Internal rework of `field::to()` and `field::as()` functions. + - Some more warning options in maintainer mode. + - Removed the old, DocBook-based tutorial. + - Fixed wrong `query` and SQLSTATE params to some exceptions. (#378) +7.2.0 + - You can now implicitly convert a `const std::string &` to `zview`. + - Replaced some overloads for C strings and C++ strings with `zview`. + - Deprecating `binarystring`. Use `std::basic_string` instead! + - Array parser did not recognise escaping in unquoted values. + - gcc10 test build fix: a result iterator is not the same thing as a `row`. + - Doc fix: field size does _not_ include terminating zero. (#356) + - Fix error message in `demangle_type_name`: printed result, not raw name. + - Fix compile warning in `demangle_type_name` on GNU systems. + - Document that string conversions assume non-null values. + - Start playing with C++20 _concepts._ + - Sketch out concepts-based `PQconnectdbParams` support. (#343) + - Add missing link to "datatypes" documentation. (#346) + - Supports `to_string`, `stream_to`, etc. for `binarystring`. (#312) + - Fixed infinite recursion when using `std::optional` in `stream_to`. (#364) + - Home-rolled hex-escaping. Saves an allocation. + - Catch floating-point negative overflow in `check_cast`, not underflow. + - Bit more work on CMake build doc. (#318) + - Typo in `datatypes.md`: `nullness`, not `nullness_traits`. (#353) + - Fixed test names map in `tests/runner.cxx`. (#354) + - Integral `from_string` now accept leading whitespace, as in composite types. + - Experimental support basics for composite types. (#355) + - Use `stream_from` without knowing the number of fields. (#357) + - Global `size_buffer` function. + - `quote()` now works for always-null types without conversions defined. + - `std::nullopt` now converts to an SQL null. + - Skip quoting and escaping array/composite fields of "safe" types. + - New type trait: `is_unquoted_safe`. + - Forbid invalid specialisations of `query_value`. + - Fixed `mktemp` invocation that broke on FreeBSD. + - Avoid unneeded encode/decode step on more binary data. + - If `__cxa_demangle` fails, fall back on raw type name. (#361) +7.1.2 + - Document build in `BUILDING-configure.md` / `BUILDING-cmake.md`. + - Work around silly clang warning in `test_errorhandler.cxx`. + - Fix install error with some internal headers. (#322) + - Fix "No object selected" error message in large objects. (#324) + - If error has no SQLSTATE, throw `broken_connection`. (#280) + - Fix argument order in `encrypt_password`. (#333, #334) + - Fix underestimate of buffer size for `to_string` for floats. (#328) +7.1.1 + - Compile fix for Visual Studio. + - Warning fix for clang. + - Also install `transaction_focus.hxx`. (#320) +7.1.0 + - Query tuples straight into `std::tuple` using `transaction::stream()`! + - And, `stream_from` now supports more or less arbitrary queries. + - Instead of a tuple of fields, you can pass `stream_to` a container as well. + - `string_traits::size_buffer()` must now be `noexcept`. + - New `nullness` member: `always_null`. + - There is now `to_buf` support for string literals. + - Streaming data is now more efficient. + - The table name in `stream_from` is now escaped. + - You can now "convert" strings to `std::string_view`. Mind your lifetimes! + - A `std::variant` will now convert to string, if its member types do. + - If a `stream_from` row fails to convert, you can no longer retry it. + - `from_string(field const &)` now handles null values properly. + - Obsolete Windows build docs are gone. + - Added `row::to(std::tuple<...>)`. + - Unified the test suites. We no longer need `test/unit/unit_runner`. + - New helper: `strip_t<...>` to remove a type's constness and reference. + - Replace custom templating with CMake glob in `src/CMakeLists.txt`. + - Replace custom templating with CMake glob in `doc/CMakeLists.txt`. + - Replace custom templating with CMake glob in `test/unit/CMakeLists.txt`. +7.0.8 + - Inline `type_name` in `PQXX_DECLARE_ENUM_CONVERSION`. +7.0.7 + - Fix broken `--with-postgres-lib` option in `configure` script (#311) + - Should now build even if neither `pkg-config` nor `pg_config` is available. + - CMake accepts `PostgreSQL_ROOT`, if it's a sufficiently recent version. +7.0.6 + - Prefer `pg_config` over `pkg-config` for include path (#291). + - Try to plod on if we don't know the PostgreSQL include path. + - Fix error message when starting overlapping transactions and such (#303). + - Fix potential crashes when converting invalid strings to floats (#307, #308). +7.0.5 + - Compile fix for g++ 10: include `` (#292). + - Cleaned up error-checking of PG results. (#280). + - The `esc()` methods now also take `std::string_view` (#295). +7.0.4 + - Fix possible crash in `connection::connection_string` (#290). + - Fix filtering of default values in `connection::connection_string` (#288). + - Deprecate `row::swap` and public inheritance of iterators from `row`. + - More copy/move/default constructors/assignments on result iterators. + - More copy/move/default constructors/assignments on row iterators. +7.0.3 + - Fixed misreporting of broken connection as `sql_error` (#280). + - Replaced non-ASCII test texts with escape codes (#282, #283). + - `ilostream` could truncate at `0xff` byte at buffer boundary (#284, #286). +7.0.2 + - New query function: `query_value`, queries and converts a single value. + - A `stream_from` stream can now be iterated. + - More callable types qualify as transactors, thanks to `std::invoke`. +7.0.1 + - Windows build fixes. + - Documentation for writing your own string conversions. + - `transaction_rollback` and children are now `sql_error`, not just `failure`. +7.0.0 + - Bumped minimum required C++ version to C++17. + - Everything has changed. If you're porting from older versions, be careful! + - There is now only one connection class: `connection`. + - Removed tablereader/tablewriter, replaced by stream_from/stream_to. + - Removed obsolete transactor framework, replaced by post-C++11 one. + - Removed old ways of invoking parameterised and prepared statements. + - Session variables are no longer cached. + - If you do weird stuff with setting/getting variables, it may break. + - Reading a variable written from raw SQL, procedures, etc, will now work. + - Prepared statements are now registered immediately. + - If you do weird stuff with preparing/unpreparing statements, it may break. + - Changed exceptions and errors for many error situations. + - Mishandling prepared statements will now break the connection. + - Many string references and const char pointers are now `std::string_view`. + - New `zview` class wraps `string_view` for string with terminating zero. + - The `stream_base` abstract base class is gone. + - Transactions no longer have an `isolation_tag` nested type. + - The `isolation_traits` type is gone. + - There's no more `pqxx_exception`. Complicated things too much. + - `pqxx::string_traits<>::name()` has been replaced with `pqxx::type_name`. + - `to_string()` can now handle `std::vector` (to produce an SQL array). + - All `from_string()` that took a C string now take a `std::string_view`. + - There are now separate `string_traits` and `null_traits` templates. + - Enums outside classes are now scoped enums. + - `error_verbosity` is no longer nested in connection. + - `connection::get_verbosity` is gone. + - Some enums have changed names: `accesspolicy` to `access_policy`, and so on. + - `dynamic_params` now accepts an accessor. + - Fixed "const" support in arguments to parameterised/prepared statements. + - Connection objects can now be moved. + - `connections::options()` has been replaced by `connection_string()`. + - Replaced pqxx-fulltest with `test_all.py`. + - Some `size_type` have changed to different types, to match current libpq. + - Internal overflows are more consistently caught and reported. + - Deprecated items have been removed. + - Large objects now require backend version 9.3 or better. + - Seeking inside large objects now supports 64-bit sizes. + - Visual Studio project files and sample headers are gone. Use CMake. + - MinGW Makefiles are gone. Use `configure` or CMake. + - Need PostgreSQL 10 to use robusttransaction. + - `robusttransaction` no longer uses a log table. Feel free to drop it. +6.4.4 + - Use pkg-config if pg-config is not available. + - In CMake build, prefer CMake's config headers over any found in source tree. +6.4.3 + - Updated copyright strings. + - Added missing "stream" headers to autotools-based install. + - Added stream headers to pqxx/pqxx header. +6.4.2 + - Fix mistake for Windows in 6.4.1: use PQfreemem, not std::free. + - Easily enable runtime checks in configure: "--enable-audit". + - Enable optimisation in CircleCI build. +6.4.1 + - Fixed more memory leaks. +6.4.0 + - Half fix, half work around nasty notice processor life time bug. + - Fix selective running of tests: "test/unit/runner test_infinities". + - Added some missing `std::` qualifications. +6.3.3 + - Throw more appropriate error when unable to read client encoding. + - CMake build fixes. +6.3.2 + - Conversion errors no longer throw pqxx::failure; always conversion_error! + - Use C++17's built-in numeric string conversions, if available. + - Query numeric precision in a more sensible, standard way. + - Avoid "dead code" warning. + - Replace obsolete autoconf macros. + - Remove all "using namespace std". + - CMake build fixes. +6.3.1 + - Windows compile fix (CALLBACK is a macro there). + - Work around Visual Studio 2017 not supporting ISO 646. +6.3.0 + - New "table stream" classes by Joseph Durel: stream_from/stream_to. + - Support weird characters in more identifiers: cursors, notifcations, etc. + - Connection policies are deprecated. It'll all be one class in 7.0! + - Connection deactivation/reactivation is deprecated. + - Some items that were documented as deprecated are now also declared as such. + - Fix Windows bug where WSAPoll was never used. Thanks dpolunin. + - Fix Windows CMake build to link to socket libraries. Thanks dpolunin. + - Various other changes to the CMake build. + - Fix failure when doing multiple string conversions with Visual C++. + - Fix nested project builds in CMake. Thanks Andrew Brownsword. + - In Visual Studio, build for host architecture, not "x64". + - Fix string conversion link error in Visual Studio. Thanks Ivan Poiakov. + - Fix string conversion to bool for "1". Thanks Amaracs. + - Fix in escaping of strings in arrays. Thanks smirql. + - Faster copying of results of large queries. Thanks Vsevolod Strukchinsky. + - Starting to handle encodings properly! Thanks to Joseph Durel. + - No longer using std::iterator (deprecated in C++17). +6.2.5 + - Removed deprecated pqxx-config. + - Build fix on Visual C++ when not defining NOMINMAX. + - Reduce setup code for string conversions, hopefully improving speed. + - Allow nul bytes in tablereader. + - Support defining string conversions for enum types. + - Fixed const/pure attributes warning in gcc 8. + - Updated build documentation to mention CMake option. + - Fixed a floating-point string conversion failure with Visual Studio 2017. +6.2.4 + - Fix builds in paths containing non-ASCII characters. + - New macro: PQXX_HIDE_EXP_OPTIONAL (to work around a client build error). +6.2.3 + - Build fixes. +6.2.2 + - Variable number of arguments to prepared or parameterised statement (#75). + - Windows build fix (#76). +6.2.1 + - Compile fixes. +6.2.0 + - At last! A check against version mismatch between library and headers. + - Small compile fixes. +6.1.1 + - Small compile fixes. + - A particular error string would always come out empty. +6.1.0 + - Dependencies among headers have changed. You may need extra includes. + - Library headers now include "*.hxx" directly, not the user-level headers. + - Supports parsing of SQL arrays, when using "ASCII-like" encodings. +6.0.0 + - C++11 is now required. Your compiler must have shared_ptr, noexcept, etc. + - Removed configure.ac.in; we now use configure.ac directly. + - Removed pqxx::items. Use the new C++11 initialiser syntax. + - Removed maketemporary. We weren't using it. + - Can now be built outside the source tree. + - New, simpler, lambda-friendly transactor framework. + - New, simpler, prepared statements and parameterised statements. + - Result rows can be passed around independently. + - New exec0(): perform query, expect zero rows of data. + - New exec1(): perform query, expect (and return) a single row of data. + - New exec_n(): perform query, expect exactly n rows of data. + - No longer defines Visual Studio's NOMINMAX in headers. + - Much faster configure script. + - Most configuration items are gone. + - Retired all existing capability flags. + - Uses WSAPoll() on Windows. + - Documentation on readthedocs.org, thanks Tim Sheerman-Chase. +5.1.0 + - Releases after this will require C++11! + - Internal simplification to pqxx::result. + - A row object now keeps its result object alive. + - New exec() variants: "expect & return 1 row," "expect no rows," "expect n." + - ChangeLog is gone. It was a drag on maintenance. +5.0.1 + - Exposed sqlstate in sql_error exception class. +5.0 + - The PGSTD namespace alias is gone. Use the std namespace directly. + - pqxx::tuple is now pqxx::row, to avoid clashes with std::tuple. + - Deprecated escape_binary functions dropped. + - Deprecated notify_listener class dropped. + - Support for many old compilers dropped. + - Support for "long long" and "long double" types is always enabled. + - No longer uses obsolete std::tr1 namespace; use plain std instead. + - Now requires libpq 9.1 or better. + - Requires server version 9.1 or better. + - Support for REPEATABLE READ isolation level added. + - Makefile fixes for Visual Studio 2013. + - Supports C++11 and C++14. + - No longer has obsolete debian & RPM packaging built in. + - Fixed failure to abort uncommitted subtransactions on destruction. + - Fixed failure to detect some integer overflows during conversion. + - Build tooling uses /usr/bin/env python instead of /usr/bin/python. + - New configure options: --with-postgres-include and --with-postgres-lib. + - In g++ or compatible compilers, non-exported items are no longer accessible. + - Many build fixes for various platforms and compilers. +4.0 + - API change: noticers are gone! Use errorhandlers to capture error output. + - API change: tablereaders and tablewriters are gone; they weren't safe. + - API change: prepared statements are now weakly-typed, and much simpler. + - API change: fields and tuples are now stand-alone classes in ::pqxx. + - API change: thread-safety field have_strerror_r is now have_safe_strerror. + - API change: notify_listener has been replaced with notification_receiver. + - notification_receiver takes a payload parameter. + - Easier Visual C++ setup. + - Absolutely requires a libpq version with PQescapeStringConn. + - Absolutely requires libpq 8.0 or better. + - Changes for C++0x. + - Supports clang++. + - Visual C++ makefiles now support new-style unit tests. + - Sample headers for more recent Visual Studio versions. + - Fixes binary-data escaping problems with postgres 9.0. + - Fixes problems with binary-string handling and escaping. + - Fixes compatibility problems between 9.x libpq and 7.x backend. + - quote_name to escape SQL identifiers for use in queries. + - syntax_error reports error's approximate location in the query. + - On Windows, now uses ws2_32 instead of wsock32. + - Various Windows build fixes. + - Updated for gcc 4.6.0. + - configure script supports --enable-documentation/--disable-documentation. + - Streamlined test/release toolchain. +3.1 + - Shared libraries are now versioned by ABI: 3.1 instead of 3.1.0 etc. + - Threading behaviour is now documented, and can be queried. + - Version information available at compile time. + - Supports parameterized statements. + - Result tuples now support slicing. + - Configure with --with-tr1=boost to use BOOST shared_ptr. + - String conversion now has its own header file. + - Supports read-only transactions. + - Fixed breakage with Solaris "make". + - Uses shared_ptr if available. + - binarystring::str() is no longer cached; no longer returns reference. + - Fixed problems in Visual C++ Makefile for test suite. + - Fixed problems with RPM packaging. + - Fixed build problem on RedHat/CentOS 5. + - Lets you check whether a prepared statement has been defined. + - "Varargs" prepared statements. + - Unnamed prepared statements now supported. + - Results have iterator as well as const_iterator. + - Rewrite of robusttransaction logic; may actually do its job now. + - Connections support async query cancel from signal handler or thread. + - More documentation for performance features. +3.0 + - Website is now at http://pqxx.org/ (no redirects) + - Completely replaced cursor classes + - More helpful error messages on failed connections + - More detailed hierarchy of constraint-violation exception classes + - trigger is now called notify_listener, trigger header is now notify-listen + - New mixin base class pqxx_exception distinguishes libpqxx exception types + - Quoting is back! transaction_base::quote() & connection_base::quote() + - Several build & documentation problems with Visual C++ fixed + - Compile fixes for gcc 4.2, 4.3 + - Compile fixes for Sun Studio Express 5.9 + - Uses strlcpy() where available, instead of strncpy() + - Keeps better track of applicable text encodings + - Fixed bug with prepared statement parameters in separate C++ statements + - robusttransaction now works for multiple users + - Pipeline lets you cancel ongoing queries, e.g. because they run for too long + - Fixed broken escaping of binary values in tablewriter + - Floating-point types now represented with full precision + - Proper unit tests for new functionality + - New traits-based system for adding data types + - Floating-point infinities now supported + - Flushing/completing a pipeline now frees up the transaction for other use + - Completely reworked test suite, builds and runs much faster + - tablewriter supports writing of raw lines +2.6.9 + - Removed old 1.x API (that means all identifiers with capital letters!) + - Tested with all current libpq versions and oldest/newest supported backends + - No longer have old OnCommit()/OnAbort()/OnDoubt() callbacks in transactor! + - Fixes failure when closing cursors with upper-case letters in their names + - Fixes bug when adding triggers to connections that aren't open yet + - Fixes bug when removing triggers + - Fixes small memory leak when preparing statements + - Fixes many problems with older backends + - Fixes bug in result::swap(): protocol versions were not swapped + - Some errors went undetected when using certain libpq versions + - Fixes prepared statements on new libpq versions talking to old backends + - Can estimate server version if libpq does not know how to obtain it + - Greatly reduced memory usage while escaping strings + - With Visual C++, creates lib/ directory if not already present + - Useful error messages when preparing statements + - Allows prepared statements to be registered explicitly + - Support for "long long" types; enable with PQXX_ALLOW_LONG_LONG macro + - Compilation errors for older libpq versions fixed + - Some new small utility classes for disabling notice processing etc. + - Result sets remember the queries that yielded them + - New test script, pqxx-fulltest, tests against all current postgres versions + - Connections can simulate failure + - Adds password encryption function +2.6.8 + - Fixes bug: binary parameters to prepared statements truncated at nul bytes + - New, more specific exception types to distinguish errors from server + - Resolved serious problems with generated reference documentation + - Automatically detect Windows socket library with MinGW + - Windows "make" fixed to run from main directory, not win32 + - Fixes "mktemp" problems on some BSD-based platforms + - pqxx-config is deprecated; use pkg-config instead + - On GNU/Linux, uses poll() instead of select() to avoid file descriptor limit + - Will provide server and protocol version information where available + - New cursor class, absolute_cursor +2.6.7 + - New escape functions for binary data: transaction_base::esc_raw() + - Improved detection of socket libraries, especially for MinGW + - Works around bug in some versions of GNU grep 2.5.1 + - Fixes problem with configuration headers + - Fixes PQprepare() detection + - Fixes incomplete Visual C++ Makefile + - Fixes compile error in workaround for older libpq versions + - Removes "rpath" link option +2.6.6 + - New, encoding-safe string-escaping functions + - Upper-case letters now allowed in prepared-statement names + - Fixes crash in test005 + - More Visual C++ improvements + - Removed collaboration diagrams from reference docs + - New templating system for generating Windows Makefiles etc. +2.6.5 + - Visual C++ users: copy win32/common-sample to win32/common before editing it + - Should fix problems finding socket library on MinGW + - Even more work on Visual C++ problems + - Updated documentation for Visual C++ users + - Fixed bug in prepared statements (mostly visible on Visual C++) + - Nested transactions work harder to detect backend support +2.6.4 + - Massively improved compatibility with Windows and Visual C++ + - Fixed late initialization of "direct" connection state + - Fixed problem with initialization of connection capabilities + - Fixed configuration bug for libpq in nonstandard locations + - Sample configuration header for libpq found in PostgreSQL 8.1 +2.6.3 + - Radical rework of prepared statements; INCOMPATIBLE INTERFACE CHANGE! + - Dropped support for g++ 2.95 + - Emulate prepared statements support on old libpq or old backend + - Bug fix: missing tutorial (release script now tests for this) + - Automatically links in socket library on Windows or Solaris, if needed + - Bug fix: check for std namespace didn't work + - Fixes for Cygwin/MSYS/MinGW +2.6.2 + - Bug fix: connection state was not set up properly in some common cases + - Bug fix: headers were installed in "include" instead of "include/pqxx" + - Bug fix: sqlesc(string) broke with multibyte or multiple encodings + - namedclass is now used as a virtual base; affects all subclass constructors + - Initial implementation of subtransactions + - Detect more connection capabilities + - Standard library namespace can be set from configure script's command line + - Completely reworked connection hierarchy, with separate policy objects + - Clients can now define their own connection policies + - Paved the way for client-defined thread synchronization + - Now lives at http://thaiopensource.org/development/libpqxx/ +2.6.1 + - Hugely improved recognition of different strerror_r() versions + - Resolved link problems with gcc 4.0 and shared library +2.6.0 + - New macro PQXX_SHARED defines whether to use/build libpqxx as shared library + - Robusttransaction compatible with PostgreSQL 8.1 + - Infrastructure for querying connection/backend capabilities at runtime + - Greatly improved cursor support + - Connection reactivation can be inhibited explicitly + - Tries even harder to make sense of conflicting strerror_r() definitions + - Detects connection failures that libpq glosses over + - Reference documentation grouped into more coherent sections + - Assumes strerror() is threadsafe on systems that have no strerror_r() + - Now allows connection's socket number to be queried + - New internal_error class for libpqxx-internal errors + - With Visual C++, doesn't redefine NOMINMAX if it is defined already + - Several compatibility improvements for Visual C++ + - Fixes and workarounds for HP-UX and HP aCC compiler + - Phased old cursor interface out of test suite; tests ported to new interface + - Added documentation on thread safety + - New thread safety model + - Large objects have functions to tell current position + - Minor updates to tutorial (somebody pay me and I'll do more :) + - No longer needs libpq-fs.h header + - Meaningful error messages for ambiguous string conversions fixed +2.5.6 + - Support null parameters to prepared statements (use C-style char pointers) +2.5.5 + - Diagnoses connection failure during result transfer + - Fixes invalid -R link option in pqxx-config +2.5.4 + - Fix workaround code for older libpq versions without PQunescapeBytea() + - Work around grep bug in Fedora Core 4 that broke configure in UTF-8 locales + - In Visual C++, assume libpqxx is a DLL when linking to std library as DLL + - Missing documentation in distribution archive is back again + - Export fewer symbols from library binary with gcc 4.0 + - Releases now automatically tested against gcc 4.0 + - Meaningful link errors for additional ambiguous string conversions + - DLL symbol exports now automatically tested before each release +2.5.3 + - Greatly improved builds on MinGW with MSYS + - All known problems with MinGW fixed + - Fix bugs in stream classes that caused failures and crashes with STLport + - Detects and uses STLport automatically +2.5.2 + - Fix memory leaks + - Fix problems with NaN (not-a-number values) on some compilers +2.5.1 + - Fix configure script; broke when very recent libpqxx was already installed + - Fix cursor breakage when "long" is more than 32 bits + - Fix cases where new-style abort/doubt handlers are used + - Fix for division-by-zero error in Visual C++ (changed sample headers) + - Improved checking for strerror_r in configure script + - Fix for problem MinGW has with configure script + - Fix spurious failure of Oid check in configure script +2.5.0 + - Fix race condition in removing triggers + - Fix binary string conversion with older libpq + - Fix some error strings that may previously have come out wrong + - No longer includes any libpq headers while compiling client code + - Improved thread safety: avoid strerror() where possible + - Prepared statements + - Translate more error conditions to std::bad_alloc exception + - Clearer and more specific explanations for configuration failures + - Improved documentation + - Looks for standard library in global namespace as well as std + - Accepts standard C library in std namespace + - Release script automatically tests with a range of compilers, not just one + - Compatible with g++ 2.95 again; this time it's tested automatically +2.4.4 + - Fix problems building shared library in Visual C++ + - Fix autobuild in Debian, which was broken by mistake in BSD grep workaround + - Fix conversion of string to floating-point type NaN + - Remove stray CVS directories from distribution archive + - Workaround for Visual C++ problem when issuing messages from destructors + - Yet more workarounds for Visual C++ bugs + - Fix situation where connection state might not be restored after failure + - Fix configuration problem on SunOS + - Network speedup in connection setup with pending variables and/or triggers +2.4.3 + - Yet more workarounds for bugs in Visual C++ .NET 2003 + - Fixes for SunC++ 5.5 + - On Visual C++, now defines NOMINMAX, fixing large object support + - Workaround for BSD grep + - Improvements for builds from CVS + - Sample config headers for Sun ONE Studio 8 +2.4.2 + - Fix minor problems with Apple's version of g++ 3.3 + - Fix problem with MingW on Windows + - Workarounds and fixes for Visual C++.NET 2003 + - Renewed compatibility with g++ 2.95 + - More sample configuration headers + - Updated reference documentation + - Removed assert code +2.4.1 + - Several bugs in icursor_iterator fixed; incompatible interface changes + - Tightens throw specifications on begin(), end(), size(), capacity() + - Containers define reference and pointer types + - Implements swap() in all container types + - Implements == and != in all container types + - Stabilizes new (but still limited) cursor interface + - icursor_iterator thinks purely in stride granularity + - Introduces />= comparisons for icursor_iterators + - Allows "adopted SQL cursors" in new cursor interface + - Reference-counting in binarystrings, so they can be copied (and efficiently) + - Fixes reference-to-temporary problem with std::reverse_iterator in results + - Result/tuple reverse_iterators no longer require std::reverse_iterator + - Includes some sample config headers (in config/sample-headers) + - Replaces iffy autoconf checks (avoid failures with maintainer mode's -Werror) + - Fixes incompatibility with some implementations of Unix "cut" program (again) +2.4.0 + - Fixes incompatibility with some implementations of Unix "cut" program + - Fixes "ptrdiff_t redefinition" problem in some environments + - More container-like tuples, so fields can be iterated + - All size_type types are now unsigned + - More conservative robusttransaction--thanks Tom Lane + - Stream-like extraction operator for result field conversion + - Warnings about deprecated headers now suppressed while compiling library + - Iterator constructors and copy assignments now have empty throw specs +2.3.0 + - Generates MinGW Makefile automatically + - Documents MinGW build + - Workaround for missing prepared-statement support + - Potential bug fixed in closing of connections + - Fixed incompatibility between new cursor streams and older backends + - Removed pqxxbench +2.2.9 + - Bugfix in removing trigger + - Added "failed connection" to regression test + - Some changes to throw specifications + - Putting libpq in its own namespace is optional +2.2.8 + - Moved libpq into pqxx::internal::pq namespace + - New config system separates compiler-related items from libpq-related ones + - Auto-generates Visual C++ Makefile, should always remain up-to-date now +2.2.7 + - Bugfix: from_string() didn't handle LONG_MIN--thanks Yannick Boivin +2.2.6 + - Complete "pipeline" rewrite, for better exception safety + - New garbage collection scheme for "result;" constructors now exception-free +2.2.5 + - First new cursor classes! + - Fixed strange failure in tablewriter during large insertions + - Updated tutorial +2.2.4 + - New utility class template, items<> for easy container initialization + - New utility function template, separated_list() + - Error handling bugfix in tablewriter + - Fixed tablereader handling of lines ending in empty fields + - tablereader lines no longer end in newline with old libpq versions +2.2.3 + - Trigger names no longer need to be proper identifiers + - Compile fixes for g++ 3.4.0 and other modern compilers + - Tablestreams may specify column lists + - Deprecated Quote() in favour of sqlesc(); improved quoting + - Fixed generation of libpqxx.spec +2.2.2 + - Bugfix in fieldstream w.r.t. reading strings on some systems + - Renamed config.h to internalconfig.h to avoid confusion + - New connection functions allow client to sleep until notification arrives + - Notification functions return number of notifications received + - Even fewer client-visible macros exported by libconfig.h +2.2.1 + - New, 2.x-style string conversions without locale problem + - Documentation improvements + - Implemented result::swap() +2.2.0 + - Installs to /usr/local by default, NOT to /usr/local/pqxx like before! + - Uses Postgres-provided script to find Postgres (thanks Peter Eisentraut) + - Which means no more configure arguments required on Irix (thanks Arjen Baart) + - Fixes long-standing bug in result class! + - New pipeline class for throughput optimization + - New field stream class: read result field as C++ stream + - Separate namespace pqxx::internal for definitions not relevant to the user + - More Windows compilation fixes + - SUN Workshop 6 compile fixes and workarounds (thanks Jon Meinecke) + - Implemented reverse_iterator for result class + - Checks for functional std::reverse_iterator template + - Preliminary Makefile for MinGW compiler (thanks Pasquale Fersini) + - Changed the way unique<> works + - Checks for functional std::count_if() + - Bugs fixed & test programs added +2.1.3 + - Makefile fixes for Visual C++, thanks Paresh Patel + - Library ABI versioning implemented, thanks Roger Leigh + - Uses old SQL isolation level syntax for compatibility, thanks koun@sina.com + - tablestreams can explicitly complete() before destructor + - Bugfix in robusttransaction: forgot to set isolation level + - Fixed off-by-ones in tablewriter escape code + - tablestreams now use \n-style escape sequences + - tablestreams support octal numbers + - Freely definable "null" strings in tablestreams, as originally intended + - Improved Debian packaging, thanks Roger Leigh + - tablestreams use libpq's new-style COPY functions, if available + - Extended automation of build/release procedure + - tablewriter writes in nonblocking mode to help hide communication latency + - Can get backend variables as well as set them + - More configuration macro cleanups + - Workaround for missing clear() in standard string + - Merry Christmas! +2.1.2 + - Compile fix for gcc libstdc++ 2.9, thanks Jaroslaw Staniek + - Moved deprecated functions below current ones + - Cleanups for Debian packaging (thanks Roger Leigh, new Debian maintainer!) + - Updated authors listings + - Bumped ABI version number for the first time (now 2:0:1) +2.1.1 + - More workarounds for gcc 2.95 + - Automated tools keep test makefiles up to date +2.1.0 + - Asynchronous connections + - Fixed configure --includedir option (thanks Ray Dassen!) + - Compile fixes for SUN Workshop 6, and one for gcc on FreeBSD 4.8 +2.0.0 + - New stable release! + - Includes all changes since 1.5 release. + - Workarounds for Microsoft Visual C++ 7 problems. Thanks Costin Musteata! + - No longer need to define PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION + - Integrated Windows configuration into regular configuration + - Only uses #warning if preprocessor supports it + - Works on libpq versions without PQ[un]escapeBytea() +1.9.9 + - Minor documentation changes +1.9.8 + - Workaround for compile problem with postgres 7.3 + - Convenience typedef for transaction<>: "work" +1.9.7 + - binarystring rewritten and moved to its own file + - binarystring::size() does not include terminating null byte! + - Implemented escaping of binary strings + - Fix in workaround for missing numeric_limits on some compilers + - String conversion supported for unsigned char * + - More helpful link errors for unsupported string conversions + - Complete test coverage +1.9.6 + - Fixes in "field table" support + - Improved coexistence with client program's config.h, if any + - Prefixed autoconf macros used in headers with "PQXX_" +1.9.5 + - Header file contents moved to .hxx files for editor filetype recognition + - Fixes wrong timestamp for include/pqxx/result in 1.9.4 distribution +1.9.4 + - Fixes Visual C++ build problem when compiling as library +1.9.3 + - Quick release for various minor changes +1.9.2 + - Renamed most public member functions to all-lower-case names + - (previously is now called +1.9.1 + - tablestream destructor crashed if table didn't exist (thanks Sean [Rogers?]) + - Renamed all header files to remove ".h" suffix + - Tables created by regression test now prefixed with "pqxx" for safety + - Large objects now considered stable + - Migrated tutorial from SGML to DocBook XML (thanks Wichert Akkerman) + - Added tests 57-59 + - Fixed compile error in largeobject + - Updated Windows makefiles +1.9.0 + - EVERYTHING HAS CHANGED. Read the list or run into trouble! + - CURSOR HAS INCOMPATIBLE CHANGES AND MAY BE REPLACED COMPLETELY + - CACHEDRESULT HAS INCOMPATIBLE CHANGES (won't compile without changes) + - REVISE YOUR TRANSACTORS; now templatized on transaction type + - Finally got license file in order + - Incompatible change in setting transactor quality of service + - Cursors require serializable isolation level (checked at link time) + - Renamed Connection_base to connection_base, Connection to connection, + LazyConnection to lazyconnection + - Renamed LargeObject to largeobject, LargeObjectAccess to largeobjectaccess + - Renamed Noticer to noticer + - Renamed Trigger to trigger + - Renamed Result to result, Tuple to tuple, Field to field + - Renamed Unique<> to unique<> + - Renamed CachedResult to cachedresult + - Transformed Transaction Taxonomy (TTT): + - Renamed Transaction_base to transaction_base + - Renamed Transaction to transaction + - Renamed Transactor to transactor<> (now a template) + - Implemented transaction isolation levels as compile-time static properties + - transaction and robusttransaction now templatized on their isolation levels + - cachedresult requires serializable isolation level (checked at link time) + - Now need to include pqxx/transactor.h yourself if you need transactors + - Large objects require real backend transaction at compile time + - New type oid and constant oid_none for row identifiers resp. null oid + - Added some forgotten PQXX_LIBEXPORTs + - Tweaked documentation in many places +1.8.1 + - By popular request: more convenient way to read field values + - Documented locale sensitivity of ToString(), FromString(), Field::to() +1.8.0 + - Compiles on gcc 2.95 again (heavy streambuf workarounds in largeobject.h) + - ConnectionItf renamed to Connection_base, TransactionItf to Transaction_base + - connectionitf.h is now connection_base.h, transactionitf.h connection_base.h +1.7.8 + - BinaryString class for unescaping bytea strings + - PQAlloc template keeps track of libpq-allocated objects + - Removed some consts in Unique<>, ConnectionItf, sorry! + - Can now set session variables on connections, transactions +1.7.7 + - ./configure also looks for postgres in /usr/local/pgsql + - test007 now uses SQL_ASCII as its test encoding + - integrated Greg Hookey's Debian packaging +1.7.6 + - added postgres library (libpq) to dynamic link path +1.7.5 + - added test052 - test055 + - added Result::Tuple::ColumnNumber() + - also test setting of client encodings + - removed superfluous versions of to_file() from large object classes +1.7.4 + - new exception class, sql_error, remembers query text + - moved exception classes to new file include/pqxx/except.h + - test cases report texts of any failed queries + - added tools/rmlo.cxx +1.7.3 + - default constructors for connection classes + - revamped seeking operations on large objects + - better error messages in large objects + - added test050, test051 +1.7.2 + - more workarounds for Sun CC 5.1, thanks Jeroen van Erp! + - preliminary support for "named" queries + - can now Quote() string constants + - included Doxyfile in distribution archive + - helps avoid Windows memory allocation problem in DLLs + - allows setting of client character set encoding +1.7.1 + - regenerated documentation +1.7.0 + - removed all deprecated features + - connection string documentation in README + - separate Connection, LazyConnection classes + - made test001 more concise + - added test049 +1.6.4 + - configure script now respects different std namespace +1.6.3 + - olostream, lostream now flush themselves before closing + - fixed compilation problems when using ToString<>() on a plain char * + - compilation fixes for Sun compiler (thanks Jeroen van Erp!) + - added .pc file for pkgconfig (thanks Ray Dassen!) +1.6.2 + - Debian packaging added to distribution archive + - new ilostream, olostream, lostream classes +1.6.1 + - large object's cunlink() replaced by remove() + - default constructor for LargeObject +1.6.0 + - new large objects interface + - added test048 +1.5.0 + - allow result fields to be written to streams + - removed confusing CachedResult::clear() + - minor documentation updates + - added test046, test047 + - added convenience header +1.4.5 + - fixed crash CachedResult that was less shallow than I thought + - fixed quoting problem with adopted SQL cursors +1.4.4 + - (forgot to save cursor.cxx with new constructor in 1.4.4, sorry) +1.4.3 + - all tests now have three-digit numbers + - Cursor can adopt SQL cursor returned by a function +1.4.2 + - bugfix in CachedResult when accessing empty Results + - minor documentation improvements +1.4.1 + - documents new homepage: http://pqxx.tk/ + - Connection constructor accepts null connect string + - Exec() now also takes queries as C++ strings +1.4.0 + - Connection::IsOpen() renamed to is_open() + - NoticeProcessor replaced by Noticer (with C++ linkage) +1.3.7: + - detects nasty rare problem case with Cursors in unknown positions +1.3.6: + - fixed detection of missing PQescapeString(). Thanks David Wright! +v1.3.5: + - documented Windows build procedure + - fixed problem with upper-case letters in cursor names. Thanks key88! +2003-01-19 16:00, v1.3.4: + - support long double type + - clarified some error messages +2003-01-08 18:45, v1.3.3: + - fix missing include in test13 +2003-01-07 02:30, v1.3.2: + - configure looks for postgres includes/library in more places, thanks Ray! +2003-01-02 23:00, v1.3.1: + - bugfix in Cursor positioning +2003-01-02 20:30, v1.3.0: + - absolute positioning for Cursor + - better documentation on cursors + - reduced, but improved test suite output +2002-12-23 17:30, v1.2.8: + - Cursor::Move() returns number of rows skipped + - new typedef Cursor::size_type +2002-12-14 23:30, v1.2.7: + - test suite now distinguishes expected errors from unexpected ones +2002-12-09 20:00, v1.2.6: + - fixed some Cursor test cases for change in postgres 7.3 + - added important warning to Cursor +2002-12-09 02:00, v1.2.5: + - added important warning to CachedResult +2002-12-08 14:14, v1.2.4: + - fixed compile error on some systems in include/pqxx/util.h +2002-12-04 12:00, v1.2.3: + - workaround for broken on some systems + - fixed Quote() bug +2002-12-03 01:30, v1.2.2: + - fixed serious CachedResult bug + - added test41 +2002-12-02 17:00, v1.2.1: + - hopefully fixed cursor bug with PostgreSQL 7.3 +2002-12-01 22:00, v1.2.0: + - new CachedResult class +2002-11-07 13:15, v1.1.4: + - workaround for missing InvalidOid definition +2002-10-23 16:00, v1.1.3: + - Cursor & TableStream hierarchy now work on any transaction type + - get no. of affected rows & oid of inserted row from Result + - increased test coverage +2002-10-21 01:30, v1.1.2: + - updated build procedure + - Debian packaging improvements +2002-09-25 03:00, v1.1.1: + - supports activating/deactivating of connections + - various Connection getters now activate deferred connection first +2002-09-23 01:00, v1.1.0: + - supports lazy connections (added 19 test cases just for these) + - greatly reduced performance overhead for RobustTransaction + - removed id field from RobustTransaction's transaction log tables +2002-09-14 20:00, v1.0.1: + - now lives on GBorg + - various packaging updates +2002-06-12 17:30, v0.5.1: + - no longer have to destroy one transaction before creating the next +2002-06-07 17:15, v0.5.0: + - "make install" now finally installs headers! + - distribution now includes SGML (DocBook) version of tutorial +2002-06-04 15:00, v0.4.4: + - may now have multiple triggers with same name on single connection +2002-06-02 23:00, v0.4.3: + - fixed TableReader problem with \t and \n +2002-06-01 21:00, v0.4.2: + - hopefully fixes compile problem with broken std::iterator + - configure no longer requires --with-postgres-include=/usr/include/postgresql +2002-05-29 22:00, v0.4.1: + - can now also handle bool, unsigned char, short field types +2002-05-27 22:30, v0.4.0: + - RENAMED Transactor::TRANSACTIONTYPE to argument_type for STL conformance + - RENAMED Result::Field::name() to Name() + - documentation improvements + - minor optimizations +2002-05-18 00:00, v0.3.1: + - removed broken postgres_fe.h dependency (hopefully permanent fix) +2002-05-12 22:45, v0.3.0: + - also looks for postgres_fe.h in postgres' internal/ directory (tmp fix) +2002-05-05 01:30, v0.2.3: + - extensive build instructions in README + - make check now controlled through PG environment variables +2002-05-04 19:30, v0.2.2: + - more STL conformance + - fixed regression test + - test6 now copies "orgevents" to "events" by default +2002-04-28 23:45 Version bumped to 0.2 +2002-04-28 23:45 Self-generated distribution archive +2002-04-27 14:20 Replaced automake symlinks with actual files +2002-04-07 02:30 Released with configure script +2002-03-29 01:15 Not yet released. Still integrating autogen stuff... diff --git a/ext/libpqxx-7.7.3/README.md b/ext/libpqxx-7.7.3/README.md new file mode 100644 index 0000000..3a1c17d --- /dev/null +++ b/ext/libpqxx-7.7.3/README.md @@ -0,0 +1,199 @@ +libpqxx +======= + +Welcome to libpqxx, the C++ API to the PostgreSQL database management system. + +Home page: http://pqxx.org/development/libpqxx/ + +Find libpqxx on Github: https://github.com/jtv/libpqxx + +Documentation on Read The Docs: https://libpqxx.readthedocs.io + +Compiling this package requires PostgreSQL to be installed -- or at least the C +headers and library for client development. The library builds on top of +PostgreSQL's standard C API, libpq, though your code won't notice. + +If you're getting the code straight from the Git repo, the head of the `master` +branch represents the current _development version._ Releases are tags on +commits in `master`. For example, to get version 7.1.1: + + git checkout 7.1.1 + + +Upgrade notes +------------- + +**The 7.x versions require at least C++17.** Make sure your compiler is up to +date. For libpqxx 8.x you will need at least C++20. + +Also, **7.0 makes some breaking changes in rarely used APIs:** +* There is just a single `connection` class. It connects immediately. +* Custom `connection` classes are no longer supported. +* It's no longer possible to reactivate a connection once it's been closed. +* The API for defining string conversions has changed. + +If you're defining your own type conversions, **7.1 requires one additional +field in your `nullness` traits.** + + +Building libpqxx +---------------- + +There are two different ways of building libpqxx from the command line: +1. Using CMake, on any system which supports it. +2. On Unix-like systems, using a `configure` script. + +"Unix-like" systems include GNU/Linux, Apple macOS and the BSD family, AIX, +HP-UX, Irix, Solaris, etc. Even on Microsoft Windows, a Unix-like environment +such as WSL, Cygwin, or MinGW should work. + +You'll find detailed build and install instructions in `BUILDING-configure.md` +and `BUILDING-cmake.md`, respectively. + +And if you're working with Microsoft Visual Studio, have a look at Gordon +Elliott's +[ + Easy-PQXX Build for Windows Visual Studio +](https://github.com/GordonLElliott/Easy-PQXX-Build-for-Windows-Visual-Studio) +project. + + +Documentation +------------- + +Building the library, if you have the right tools installed, generates HTML +documentation in the `doc/` directory. It is based on the headers in +`include/pqxx/` and text in `include/pqxx/doc/`. This documentation is also +available online at [readthedocs](https://libpqxx.readthedocs.io). + + +Programming with libpqxx +------------------------ + +Your first program will involve the libpqxx classes `connection` (see the +`pqxx/connection.hxx` header), and `work` (a convenience alias for +`transaction<>` which conforms to the interface defined in +`pqxx/transaction_base.hxx`). + +These `*.hxx` headers are not the ones you include in your program. Instead, +include the versions without filename suffix (e.g. `pqxx/connection`). Those +will include the actual .hxx files for you. This was done so that includes are +in standard C++ style (as in `` etc.), but an editor will still +recognize them as files containing C++ code. + +Continuing the list of classes, you will most likely also need the result class +(`pqxx/result.hxx`). In a nutshell, you create a `connection` based on a +Postgres connection string (see below), create a `work` in the context of that +connection, and run one or more queries on the work which return `result` +objects. The results are containers of rows of data, each of which you can +treat as an array of strings: one for each field in the row. It's that simple. + +Here is a simple example program to get you going, with full error handling: + +```c++ + #include + #include + + int main() + { + try + { + // Connect to the database. + pqxx::connection C; + std::cout << "Connected to " << C.dbname() << '\n'; + + // Start a transaction. + pqxx::work W{C}; + + // Perform a query and retrieve all results. + pqxx::result R{W.exec("SELECT name FROM employee")}; + + // Iterate over results. + std::cout << "Found " << R.size() << "employees:\n"; + for (auto row: R) + std::cout << row[0].c_str() << '\n'; + + // Perform a query and check that it returns no result. + std::cout << "Doubling all employees' salaries...\n"; + W.exec0("UPDATE employee SET salary = salary*2"); + + // Commit the transaction. + std::cout << "Making changes definite: "; + W.commit(); + std::cout << "OK.\n"; + } + catch (std::exception const &e) + { + std::cerr << e.what() << '\n'; + return 1; + } + return 0; + } +``` + + +Connection strings +------------------ + +Postgres connection strings state which database server you wish to connect to, +under which username, using which password, and so on. Their format is defined +in the documentation for libpq, the C client interface for PostgreSQL. +Alternatively, these values may be defined by setting certain environment +variables as documented in e.g. the manual for psql, the command line interface +to PostgreSQL. Again the definitions are the same for libpqxx-based programs. + +The connection strings and variables are not fully and definitively documented +here; this document will tell you just enough to get going. Check the +PostgreSQL documentation for authoritative information. + +The connection string consists of attribute=value pairs separated by spaces, +e.g. "user=john password=1x2y3z4". The valid attributes include: +* `host` — + Name of server to connect to, or the full file path (beginning with a + slash) to a Unix-domain socket on the local machine. Defaults to + "/tmp". Equivalent to (but overrides) environment variable PGHOST. +* `hostaddr` — + IP address of a server to connect to; mutually exclusive with "host". +* `port` — + Port number at the server host to connect to, or socket file name + extension for Unix-domain connections. Equivalent to (but overrides) + environment variable PGPORT. +* `dbname` — + Name of the database to connect to. A single server may host multiple + databases. Defaults to the same name as the current user's name. + Equivalent to (but overrides) environment variable PGDATABASE. +* `user` — + User name to connect under. This defaults to the name of the current + user, although PostgreSQL users are not necessarily the same thing as + system users. +* `requiressl` — + If set to 1, demands an encrypted SSL connection (and fails if no SSL + connection can be created). + +Settings in the connection strings override the environment variables, which in +turn override the default, on a variable-by-variable basis. You only need to +define those variables that require non-default values. + + +Linking with libpqxx +-------------------- + +To link your final program, make sure you link to both the C-level libpq library +and the actual C++ library, libpqxx. With most Unix-style compilers, you'd do +this using the options + + -lpqxx -lpq + +while linking. Both libraries must be in your link path, so the linker knows +where to find them. Any dynamic libraries you use must also be in a place +where the loader can find them when loading your program at runtime. + +Some users have reported problems using the above syntax, however, particularly +when multiple versions of libpqxx are partially or incorrectly installed on the +system. If you get massive link errors, try removing the "-lpqxx" argument from +the command line and replacing it with the name of the libpqxx library binary +instead. That's typically libpqxx.a, but you'll have to add the path to its +location as well, e.g. /usr/local/pqxx/lib/libpqxx.a. This will ensure that the +linker will use that exact version of the library rather than one found +elsewhere on the system, and eliminate worries about the exact right version of +the library being installed with your program.. diff --git a/ext/libpqxx-7.7.3/VERSION b/ext/libpqxx-7.7.3/VERSION new file mode 100644 index 0000000..d92ba80 --- /dev/null +++ b/ext/libpqxx-7.7.3/VERSION @@ -0,0 +1 @@ +7.7.3 diff --git a/ext/libpqxx-7.7.3/aclocal.m4 b/ext/libpqxx-7.7.3/aclocal.m4 new file mode 100644 index 0000000..2c938cf --- /dev/null +++ b/ext/libpqxx-7.7.3/aclocal.m4 @@ -0,0 +1,1187 @@ +# generated automatically by aclocal 1.16.4 -*- Autoconf -*- + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.16' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.16.4], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.16.4])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? + done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi +AC_SUBST([CTAGS]) +if test -z "$ETAGS"; then + ETAGS=etags +fi +AC_SUBST([ETAGS]) +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi +AC_SUBST([CSCOPE]) + +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. +AC_DEFUN([AM_MAKE_INCLUDE], +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2021 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([config/m4/libtool.m4]) +m4_include([config/m4/ltoptions.m4]) +m4_include([config/m4/ltsugar.m4]) +m4_include([config/m4/ltversion.m4]) +m4_include([config/m4/lt~obsolete.m4]) diff --git a/ext/libpqxx-7.7.3/appveyor.yml b/ext/libpqxx-7.7.3/appveyor.yml new file mode 100644 index 0000000..110bd75 --- /dev/null +++ b/ext/libpqxx-7.7.3/appveyor.yml @@ -0,0 +1,30 @@ +# Configuration for test runs in Appveyor. +version: 1.0.{build} +image: Visual Studio 2022 +services: postgresql13 +# Run CMake to build libpqxx.sln. +before_build: +- cmd: >- + call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" + + cmake -DBUILD_SHARED_LIBS=1 -DCMAKE_CXX_STANDARD=23 +configuration: Release +build: + parallel: true + project: libpqxx.sln +test_script: +- ps: >- + $env:Path += ";.\src\Release;C:\Program Files\PostgreSQL\13\bin" + + $env:PGUSER = "postgres" + + $env:PGPASSWORD = "Password12!" + + .\test\Release\runner.exe +notifications: +- provider: Email + subject: 'libpqxx: AppVeyor build failure' + message: The libpqxx AppVeyor build has failed. + on_build_success: false + on_build_failure: true + on_build_status_changed: false diff --git a/ext/libpqxx-7.7.3/autogen.sh b/ext/libpqxx-7.7.3/autogen.sh new file mode 100755 index 0000000..a09cb5a --- /dev/null +++ b/ext/libpqxx-7.7.3/autogen.sh @@ -0,0 +1,44 @@ +#! /bin/sh +# Run this to generate the configure script etc. + +set -eu + +PQXXVERSION=$(./tools/extract_version) +PQXX_ABI=$(./tools/extract_version --abi) +PQXX_MAJOR=$(./tools/extract_version --major) +PQXX_MINOR=$(./tools/extract_version --minor) +echo "libpqxx version $PQXXVERSION" +echo "libpqxx ABI version $PQXX_ABI" + +substitute() { + sed -e "s/@PQXXVERSION@/$PQXXVERSION/g" \ + -e "s/@PQXX_MAJOR@/$PQXX_MAJOR/g" \ + -e "s/@PQXX_MINOR@/$PQXX_MINOR/g" \ + -e "s/@PQXX_ABI@/$PQXX_ABI/g" \ + "$1" +} + + +# Use templating system to generate various Makefiles. +expand_templates() { + for template in "$@" + do + ./tools/template2mak.py "$template" "${template%.template}" + done +} + + +# We have two kinds of templates. One uses our custom templating tool. And +# a few others simply have some substitutions done. +expand_templates $(find -name \*.template) +substitute include/pqxx/version.hxx.template >include/pqxx/version.hxx +substitute include/pqxx/doc/mainpage.md.template >include/pqxx/doc/mainpage.md + + +autoheader +libtoolize --force --automake --copy +aclocal -I . -I config/m4 +automake --add-missing --copy +autoconf + +echo "Done." diff --git a/ext/libpqxx-7.7.3/cmake/config.cmake b/ext/libpqxx-7.7.3/cmake/config.cmake new file mode 100644 index 0000000..816ee44 --- /dev/null +++ b/ext/libpqxx-7.7.3/cmake/config.cmake @@ -0,0 +1,157 @@ +function(detect_code_compiled code macro msg) + message(STATUS "Detecting ${msg}") + check_cxx_source_compiles("${code}" "${macro}" FAIL_REGEX "warning") + if(${macro}) + message(STATUS "Detecting ${msg} - supported") + else() + message(STATUS "Detecting ${msg} - not supported") + endif() +endfunction(detect_code_compiled) + +include(CheckIncludeFileCXX) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CMakeDetermineCompileFeatures) +include(CheckCXXSourceCompiles) +include(CMakeFindDependencyMacro) + +if(NOT PostgreSQL_FOUND) + if(POLICY CMP0074) + cmake_policy(PUSH) + # CMP0074 is `OLD` by `cmake_minimum_required(VERSION 3.7)`, + # sets `NEW` to enable support CMake variable `PostgreSQL_ROOT`. + cmake_policy(SET CMP0074 NEW) + endif() + + find_package(PostgreSQL REQUIRED) + + if(POLICY CMP0074) + cmake_policy(POP) + endif() +endif() + +check_function_exists("poll" PQXX_HAVE_POLL) + +set(CMAKE_REQUIRED_LIBRARIES pq) +check_symbol_exists( + PQencryptPasswordConn + "${PostgreSQL_INCLUDE_DIR}/libpq-fe.h" + PQXX_HAVE_PQENCRYPTPASSWORDCONN) +check_symbol_exists( + PQenterPipelineMode + "${PostgreSQL_INCLUDE_DIR}/libpq-fe.h" + PQXX_HAVE_PQ_PIPELINE) + +cmake_determine_compile_features(CXX) +cmake_policy(SET CMP0057 NEW) + +# check_cxx_source_compiles requires CMAKE_REQUIRED_DEFINITIONS to specify +# compiling arguments. +# Wordaround: Push CMAKE_REQUIRED_DEFINITIONS +if(CMAKE_REQUIRED_DEFINITIONS) + set(def "${CMAKE_REQUIRED_DEFINITIONS}") +endif() +set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION}) +set(CMAKE_REQUIRED_QUIET ON) + +try_compile( + PQXX_HAVE_GCC_PURE + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/gcc_pure.cxx) +try_compile( + PQXX_HAVE_GCC_VISIBILITY + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/gcc_visibility.cxx) +try_compile( + PQXX_HAVE_LIKELY + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/likely.cxx) +try_compile( + PQXX_HAVE_CXA_DEMANGLE + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/cxa_demangle.cxx) +try_compile( + PQXX_HAVE_CONCEPTS + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/concepts.cxx) +try_compile( + PQXX_HAVE_SPAN + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/span.cxx) +try_compile( + PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/multidim-subscript.cxx) +try_compile( + PQXX_HAVE_CHARCONV_FLOAT + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/charconv_float.cxx) +try_compile( + PQXX_HAVE_CHARCONV_INT + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/charconv_int.cxx) +try_compile( + PQXX_HAVE_PATH + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/fs.cxx) +try_compile( + PQXX_HAVE_THREAD_LOCAL + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/thread_local.cxx) +try_compile( + PQXX_HAVE_SLEEP_FOR + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/sleep_for.cxx) +try_compile( + PQXX_HAVE_STRERROR_R + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/strerror_r.cxx) +try_compile( + PQXX_HAVE_STRERROR_S + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/strerror_s.cxx) +try_compile( + PQXX_HAVE_YEAR_MONTH_DAY + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/year_month_day.cxx) +try_compile( + PQXX_HAVE_CMP + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/cmp.cxx) + +try_compile( + need_fslib + ${PROJECT_BINARY_DIR} + SOURCES ${PROJECT_SOURCE_DIR}/config-tests/need_fslib.cxx) +if(!need_fslib) + # TODO: This may work for gcc 8, but some clang versions may need -lc++fs. + link_libraries(stdc++fs) +endif() + +# check_cxx_source_compiles requires CMAKE_REQUIRED_DEFINITIONS to specify +# compiling arguments. +# Workaround: Pop CMAKE_REQUIRED_DEFINITIONS +if(def) + set(CMAKE_REQUIRED_DEFINITIONS ${def}) + unset(def CACHE) +else() + unset(CMAKE_REQUIRED_DEFINITIONS CACHE) +endif() +set(CMAKE_REQUIRED_QUIET OFF) + +set(AC_CONFIG_H_IN "${PROJECT_SOURCE_DIR}/include/pqxx/config.h.in") +set(CM_CONFIG_H_IN "${PROJECT_BINARY_DIR}/include/pqxx/config_cmake.h.in") +set(CM_CONFIG_PUB "${PROJECT_BINARY_DIR}/include/pqxx/config-public-compiler.h") +set(CM_CONFIG_INT "${PROJECT_BINARY_DIR}/include/pqxx/config-internal-compiler.h") +set(CM_CONFIG_PQ "${PROJECT_BINARY_DIR}/include/pqxx/config-internal-libpq.h") +message(STATUS "Generating config.h") +file(WRITE "${CM_CONFIG_H_IN}" "") +file(STRINGS "${AC_CONFIG_H_IN}" lines) +foreach(line ${lines}) + string(REGEX REPLACE "^#undef" "#cmakedefine" l "${line}") + file(APPEND "${CM_CONFIG_H_IN}" "${l}\n") +endforeach() +configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_INT}" @ONLY) +configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_PUB}" @ONLY) +configure_file("${CM_CONFIG_H_IN}" "${CM_CONFIG_PQ}" @ONLY) +message(STATUS "Generating config.h - done") diff --git a/ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake b/ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake new file mode 100644 index 0000000..cb25a05 --- /dev/null +++ b/ext/libpqxx-7.7.3/cmake/libpqxx-config.cmake @@ -0,0 +1,4 @@ +include(CMakeFindDependencyMacro) +find_dependency(PostgreSQL) + +include("${CMAKE_CURRENT_LIST_DIR}/libpqxx-targets.cmake") diff --git a/ext/libpqxx-7.7.3/compile_flags.in b/ext/libpqxx-7.7.3/compile_flags.in new file mode 100644 index 0000000..1304e8a --- /dev/null +++ b/ext/libpqxx-7.7.3/compile_flags.in @@ -0,0 +1 @@ +@CPPFLAGS@ @CXXFLAGS@ diff --git a/ext/libpqxx-7.7.3/config-tests/README.md b/ext/libpqxx-7.7.3/config-tests/README.md new file mode 100644 index 0000000..b3865d0 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/README.md @@ -0,0 +1,22 @@ +Configuration tests +=================== + +Libpqxx comes with support for different build systems: the GNU autotools, +CMake, Visual Studio's "nmake", and raw GNU "make" on Windows. + +For several of these build systems, we need to test things like "does this +compiler environment support `std::to_chars` for floating-point types?" + +We test these things by trying to compile a particular snippet of code, and +seeing whether that succeeds. + +To avoid duplicating those snippets for multiple build systems, we put them +here. Both the autotools configuration and the CMake configuration can refer to +them that way. + +It took a bit of nasty magic to read a C++ source file into m4 and treat it as +a string literal, without macro expansion. There is every chance that I missed +something, so be prepared for tests failing for unexpected reasons! Some C++ +syntax may end up having an unforeseen meaning in m4, and screw up the handling +of the code snippet. Re-configure, and read your logs carefully after editing +these snippets. diff --git a/ext/libpqxx-7.7.3/config-tests/charconv_float.cxx b/ext/libpqxx-7.7.3/config-tests/charconv_float.cxx new file mode 100644 index 0000000..bc5d973 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/charconv_float.cxx @@ -0,0 +1,16 @@ +// Test for std::to_string/std::from_string for floating-point types. +#include +#include + +int main() +{ + char z[100]; + auto rt = std::to_chars(std::begin(z), std::end(z), 3.14159L); + if (rt.ec != std::errc{}) + return 1; + long double n; + auto rf = std::from_chars(std::cbegin(z), std::cend(z), n); + if (rf.ec != std::errc{}) + return 2; + return (n > 3 and n < 4) ? 0 : 1; +} diff --git a/ext/libpqxx-7.7.3/config-tests/charconv_int.cxx b/ext/libpqxx-7.7.3/config-tests/charconv_int.cxx new file mode 100644 index 0000000..076ee0d --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/charconv_int.cxx @@ -0,0 +1,16 @@ +// Test for std::to_string/std::from_string for integral types. +#include +#include + +int main() +{ + char z[100]; + auto rt = std::to_chars(std::begin(z), std::end(z), 9ULL); + if (rt.ec != std::errc{}) + return 1; + unsigned long long n; + auto rf = std::from_chars(std::cbegin(z), std::cend(z), n); + if (rf.ec != std::errc{}) + return 2; + return (n == 9ULL) ? 0 : 1; +} diff --git a/ext/libpqxx-7.7.3/config-tests/cmp.cxx b/ext/libpqxx-7.7.3/config-tests/cmp.cxx new file mode 100644 index 0000000..7f5abaa --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/cmp.cxx @@ -0,0 +1,8 @@ +// Test for C++20 std::cmp_greater etc. support. +#include + + +int main() +{ + return std::cmp_greater(-1, 2u) && std::cmp_less_equal(3, 0); +} diff --git a/ext/libpqxx-7.7.3/config-tests/concepts.cxx b/ext/libpqxx-7.7.3/config-tests/concepts.cxx new file mode 100644 index 0000000..5589b4e --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/concepts.cxx @@ -0,0 +1,21 @@ +// Test for concepts support. Not just the language feature; also headers. +#include +#include +#include + + +template +concept Foo = std::ranges::input_range; + + +template auto foo(F const &r) +{ + return std::distance(std::begin(r), std::end(r)); +} + + +int main() +{ + std::vector const v{1, 2, 3}; + std::cout << foo(v) << '\n'; +} diff --git a/ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx b/ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx new file mode 100644 index 0000000..4d4ee7e --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/cxa_demangle.cxx @@ -0,0 +1,19 @@ +// Test for cross-vendor C++ ABI's __cxa_demangle function. +#include +#include +#include +#include + +#include + +int main() +{ + int status = 0; + char *name = + abi::__cxa_demangle(typeid(10).name(), nullptr, nullptr, &status); + if (status != 0) + throw std::runtime_error("Demangle failed!"); + int result = std::strcmp(name, "int"); + std::free(name); + return result; +} diff --git a/ext/libpqxx-7.7.3/config-tests/fs.cxx b/ext/libpqxx-7.7.3/config-tests/fs.cxx new file mode 100644 index 0000000..d93d37f --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/fs.cxx @@ -0,0 +1,9 @@ +// Check for working std::filesystem support. +#include + + +int main() +{ + // Apparently some versions of MinGW lack this comparison operator. + return std::filesystem::path{} != std::filesystem::path{}; +} diff --git a/ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx b/ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx new file mode 100644 index 0000000..4edd267 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/gcc_pure.cxx @@ -0,0 +1,10 @@ +// Test for gcc-style "pure" attribute. +int __attribute__((pure)) f() +{ + return 0; +} + +int main() +{ + return f(); +} diff --git a/ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx b/ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx new file mode 100644 index 0000000..23d0111 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/gcc_visibility.cxx @@ -0,0 +1,12 @@ +// Test for gcc-style "visibility" attribute. +struct __attribute__((visibility("hidden"))) D +{ + D() {} + int f() { return 0; } +}; + +int main() +{ + D d; + return d.f(); +} diff --git a/ext/libpqxx-7.7.3/config-tests/likely.cxx b/ext/libpqxx-7.7.3/config-tests/likely.cxx new file mode 100644 index 0000000..9d0eca8 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/likely.cxx @@ -0,0 +1,15 @@ +// Test for C++20 [[likely]] and [[unlikely]] attributes. + +int main(int argc, char **) +{ +#if __cplusplus < 202002L + deliberately_fail(because, older, C++, standard); +#endif + + int x = 0; + if (argc == 1) [[likely]] + x = 0; + else + x = 1; + return x; +} diff --git a/ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx b/ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx new file mode 100644 index 0000000..f75d1aa --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/multidim-subscript.cxx @@ -0,0 +1,14 @@ +// Test for multidimensional subscript operator support. +// Proposed for C++23: P2128R6. +struct table +{ + int width = 100; + + int operator[](int x, int y) const { return x + width * y; } +}; + + +int main() +{ + return table{}[0, 0]; +} diff --git a/ext/libpqxx-7.7.3/config-tests/need_fslib.cxx b/ext/libpqxx-7.7.3/config-tests/need_fslib.cxx new file mode 100644 index 0000000..041c46b --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/need_fslib.cxx @@ -0,0 +1,21 @@ +// Check whether we need to link to the stdc++fs library. +// +// We assume that the presence of the header means that we have +// support for the basics of std::filesystem. This check will succeed if +// either there is no header, or there is one and it works without +// any special options. If the link fails, we assume that -lstdc++fs will fix +// it for us. + +#include + +#if __has_include() +# include +#endif + + +int main() +{ +#if __has_include() + std::cout << std::filesystem::path{"foo.bar"}.c_str() << '\n'; +#endif +} diff --git a/ext/libpqxx-7.7.3/config-tests/poll.cxx b/ext/libpqxx-7.7.3/config-tests/poll.cxx new file mode 100644 index 0000000..d67cef5 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/poll.cxx @@ -0,0 +1,7 @@ +// Test for poll(). +#include + +int main() +{ + return poll(nullptr, 0, 0); +} diff --git a/ext/libpqxx-7.7.3/config-tests/sleep_for.cxx b/ext/libpqxx-7.7.3/config-tests/sleep_for.cxx new file mode 100644 index 0000000..f081fe0 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/sleep_for.cxx @@ -0,0 +1,28 @@ +// Test for std::this_thread::sleep_for(). +/* For some reason MinGW's header seems to be broken. + * + * But it gets worse. It looks as if we can include without problems + * in this configuration test. Why does it break when MinGW users try to build + * the library, but succeed when we try it here? + * + * To try and get close to the situation in the library code itself, we try + * including some standard headers that we don't strictly need here. + */ + +#if __has_include() +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +int main() +{ + std::this_thread::sleep_for(std::chrono::microseconds{10u}); +} diff --git a/ext/libpqxx-7.7.3/config-tests/span.cxx b/ext/libpqxx-7.7.3/config-tests/span.cxx new file mode 100644 index 0000000..8c13b97 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/span.cxx @@ -0,0 +1,8 @@ +// Test for std::span. +#include + +int main(int argc, char **argv) +{ + std::span args{argv, static_cast(argc)}; + return static_cast(std::size(args) - 1u); +} diff --git a/ext/libpqxx-7.7.3/config-tests/strerror_r.cxx b/ext/libpqxx-7.7.3/config-tests/strerror_r.cxx new file mode 100644 index 0000000..604d3b8 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/strerror_r.cxx @@ -0,0 +1,14 @@ +// Check for strerror_r. +// It can be either the POSIX version (which returns int) or the GNU version +// (which returns char *). + +#include +#include + +int main() +{ + char buffer[200]; + auto res{strerror_r(1, buffer, 200)}; + // Sidestep type differences. We don't really care what the value is. + return not not res; +} diff --git a/ext/libpqxx-7.7.3/config-tests/strerror_s.cxx b/ext/libpqxx-7.7.3/config-tests/strerror_s.cxx new file mode 100644 index 0000000..f6f99a7 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/strerror_s.cxx @@ -0,0 +1,11 @@ +// Test for strerror_s, as defined in Windows and C11. +// Presumably this'll be part of the C++ standard some day. + +#include + +int main() +{ + using namespace std; + char buf[200]; + return strerror_s(buf, 200, 1); +} diff --git a/ext/libpqxx-7.7.3/config-tests/thread_local.cxx b/ext/libpqxx-7.7.3/config-tests/thread_local.cxx new file mode 100644 index 0000000..b5a98b7 --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/thread_local.cxx @@ -0,0 +1,15 @@ +// Test for std::to_string/std::from_string for floating-point types. +#include +#include + +int main(int argc, char **) +{ +#if defined(__MINGW32__) && defined(__GNUC__) +# if __GNUC__ < 11 || ((__GNUC__ == 11) && (__GNU_MINOR__ == 0)) +# error "On MinGW before gcc 11.1, thread_local breaks at run time." +# endif +#endif + thread_local std::stringstream s; + s << argc; + std::cout << s.str(); +} diff --git a/ext/libpqxx-7.7.3/config-tests/year_month_day.cxx b/ext/libpqxx-7.7.3/config-tests/year_month_day.cxx new file mode 100644 index 0000000..dbe543b --- /dev/null +++ b/ext/libpqxx-7.7.3/config-tests/year_month_day.cxx @@ -0,0 +1,7 @@ +// Test for std::chrono::year_month_day etc. +#include + +int main() +{ + return int(std::chrono::year{1}); +} diff --git a/ext/libpqxx-7.7.3/config/Makefile.am b/ext/libpqxx-7.7.3/config/Makefile.am new file mode 100644 index 0000000..f34b310 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST=m4/Makefile.am sample-headers +MAINTAINERCLEANFILES=Makefile.in config.guess config.sub install-sh \ + ltmain.sh missing mkinstalldirs + +dist-hook: + find "${distdir}" -type d -name CVS -print0 | xargs -0 rm -rf + find "${distdir}" -type d -name .svn -print0 | xargs -0 rm -rf + diff --git a/ext/libpqxx-7.7.3/config/Makefile.in b/ext/libpqxx-7.7.3/config/Makefile.in new file mode 100644 index 0000000..bf7aa00 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/Makefile.in @@ -0,0 +1,470 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = config +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in compile config.guess \ + config.sub install-sh ltmain.sh missing mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +EXTRA_DIST = m4/Makefile.am sample-headers +MAINTAINERCLEANFILES = Makefile.in config.guess config.sub install-sh \ + ltmain.sh missing mkinstalldirs + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu config/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu config/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am dist-hook distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +dist-hook: + find "${distdir}" -type d -name CVS -print0 | xargs -0 rm -rf + find "${distdir}" -type d -name .svn -print0 | xargs -0 rm -rf + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/config/compile b/ext/libpqxx-7.7.3/config/compile new file mode 100755 index 0000000..df363c8 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/compile @@ -0,0 +1,348 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/* | msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/config/config.guess b/ext/libpqxx-7.7.3/config/config.guess new file mode 100755 index 0000000..2e9ad7f --- /dev/null +++ b/ext/libpqxx-7.7.3/config/config.guess @@ -0,0 +1,1462 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2016 Free Software Foundation, Inc. + +timestamp='2016-10-02' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2016 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "${UNAME_MACHINE_ARCH}" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = hppa2.0w ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + *:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + k1om:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + mips64el:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +cat >&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/ext/libpqxx-7.7.3/config/config.sub b/ext/libpqxx-7.7.3/config/config.sub new file mode 100755 index 0000000..dd2ca93 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/config.sub @@ -0,0 +1,1825 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2016 Free Software Foundation, Inc. + +timestamp='2016-11-04' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2016 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -ios) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/ext/libpqxx-7.7.3/config/depcomp b/ext/libpqxx-7.7.3/config/depcomp new file mode 100755 index 0000000..715e343 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/config/install-sh b/ext/libpqxx-7.7.3/config/install-sh new file mode 100755 index 0000000..6781b98 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/config/ltmain.sh b/ext/libpqxx-7.7.3/config/ltmain.sh new file mode 100755 index 0000000..21e5e07 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/ltmain.sh @@ -0,0 +1,11251 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.6 Debian-2.4.6-15" +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2015-10-07.11; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + _G_rc_run_hooks=false + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + if eval $_G_hook '"$@"'; then + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + _G_rc_run_hooks=: + fi + done + + $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, you may remove/edit +# any options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. In this case you also must return $EXIT_SUCCESS to let the +# hook's caller know that it should pay attention to +# '_result'. Returning $EXIT_FAILURE signalizes that +# arguments are left untouched by the hook and therefore caller will ignore the +# result variable. +# +# Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# # No change in '$@' (ignored completely by this hook). There is +# # no need to do the equivalent (but slower) action: +# # func_quote_for_eval ${1+"$@"} +# # my_options_prep_result=$func_quote_for_eval_result +# false +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# args_changed=false +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: +# args_changed=: +# ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# args_changed=: +# ;; +# *) # Make sure the first unrecognised option "$_G_opt" +# # is added back to "$@", we could need that later +# # if $args_changed is true. +# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; +# esac +# done +# +# if $args_changed; then +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# fi +# +# $args_changed +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# false +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll also need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options_finish [ARG]... +# ---------------------------- +# Finishing the option parse loop (call 'func_options' hooks ATM). +func_options_finish () +{ + $debug_cmd + + _G_func_options_finish_exit=false + if func_run_hooks func_options ${1+"$@"}; then + func_options_finish_result=$func_run_hooks_result + _G_func_options_finish_exit=: + fi + + $_G_func_options_finish_exit +} + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + _G_rc_options=false + + for my_func in options_prep parse_options validate_options options_finish + do + if eval func_$my_func '${1+"$@"}'; then + eval _G_res_var='$'"func_${my_func}_result" + eval set dummy "$_G_res_var" ; shift + _G_rc_options=: + fi + done + + # Save modified positional parameters for caller. As a top-level + # options-parser function we always need to set the 'func_options_result' + # variable (regardless the $_G_rc_options value). + if $_G_rc_options; then + func_options_result=$_G_res_var + else + func_quote_for_eval ${1+"$@"} + func_options_result=$func_quote_for_eval_result + fi + + $_G_rc_options +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propagate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + _G_rc_options_prep=false + if func_run_hooks func_options_prep ${1+"$@"}; then + _G_rc_options_prep=: + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result + fi + + $_G_rc_options_prep +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + _G_rc_parse_options=false + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + if func_run_hooks func_parse_options ${1+"$@"}; then + eval set dummy "$func_run_hooks_result"; shift + _G_rc_parse_options=: + fi + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_match_parse_options=: + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + if test $# = 0 && func_missing_arg $_G_opt; then + _G_rc_parse_options=: + break + fi + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) _G_rc_parse_options=: ; break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift + _G_match_parse_options=false + break + ;; + esac + + $_G_match_parse_options && _G_rc_parse_options=: + done + + + if $_G_rc_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_parse_options +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + _G_rc_validate_options=false + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + if func_run_hooks func_validate_options ${1+"$@"}; then + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result + _G_rc_validate_options=: + fi + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + $_G_rc_validate_options +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname $scriptversion Debian-2.4.6-15 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + _G_rc_lt_options_prep=: + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + *) + _G_rc_lt_options_prep=false + ;; + esac + + if $_G_rc_lt_options_prep; then + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_options_prep +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + _G_rc_lt_parse_options=false + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_match_lt_parse_options=: + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"} ; shift + _G_match_lt_parse_options=false + break + ;; + esac + $_G_match_lt_parse_options && _G_rc_lt_parse_options=: + done + + if $_G_rc_lt_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_parse_options +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files + # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer + # -fuse-ld=* Linker select flags for GCC + # -static-* direct GCC to link specific libraries statically + # -fcilkplus Cilk Plus language extension features for C/C++ + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/ext/libpqxx-7.7.3/config/m4/Makefile.am b/ext/libpqxx-7.7.3/config/m4/Makefile.am new file mode 100644 index 0000000..c5dd157 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/Makefile.am @@ -0,0 +1,3 @@ +MAINTAINERCLEANFILES=Makefile.in config.guess config.sub install-sh \ + ltmain.sh missing mkinstalldirs + diff --git a/ext/libpqxx-7.7.3/config/m4/libtool.m4 b/ext/libpqxx-7.7.3/config/m4/libtool.m4 new file mode 100644 index 0000000..c4c0294 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/libtool.m4 @@ -0,0 +1,8394 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[912]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*|11.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cr} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/ext/libpqxx-7.7.3/config/m4/ltoptions.m4 b/ext/libpqxx-7.7.3/config/m4/ltoptions.m4 new file mode 100644 index 0000000..94b0829 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/ext/libpqxx-7.7.3/config/m4/ltsugar.m4 b/ext/libpqxx-7.7.3/config/m4/ltsugar.m4 new file mode 100644 index 0000000..48bc934 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/ext/libpqxx-7.7.3/config/m4/ltversion.m4 b/ext/libpqxx-7.7.3/config/m4/ltversion.m4 new file mode 100644 index 0000000..fa04b52 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 b/ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c6b26f8 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/m4/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/ext/libpqxx-7.7.3/config/missing b/ext/libpqxx-7.7.3/config/missing new file mode 100755 index 0000000..1fe1611 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/config/mkinstalldirs b/ext/libpqxx-7.7.3/config/mkinstalldirs new file mode 100755 index 0000000..6b3b5fc --- /dev/null +++ b/ext/libpqxx-7.7.3/config/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/ext/libpqxx-7.7.3/config/test-driver b/ext/libpqxx-7.7.3/config/test-driver new file mode 100755 index 0000000..8e575b0 --- /dev/null +++ b/ext/libpqxx-7.7.3/config/test-driver @@ -0,0 +1,148 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2013-07-13.22; # UTC + +# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/ext/libpqxx-7.7.3/configitems b/ext/libpqxx-7.7.3/configitems new file mode 100644 index 0000000..e6f3925 --- /dev/null +++ b/ext/libpqxx-7.7.3/configitems @@ -0,0 +1,26 @@ +PACKAGE internal autotools +PACKAGE_BUGREPORT internal autotools +PACKAGE_NAME internal autotools +PACKAGE_STRING internal autotools +PACKAGE_TARNAME internal autotools +PACKAGE_VERSION internal autotools +PQXX_HAVE_CHARCONV_INT internal compiler +PQXX_HAVE_CHARCONV_FLOAT internal compiler +PQXX_HAVE_CMP public compiler +PQXX_HAVE_CONCEPTS public compiler +PQXX_HAVE_CXA_DEMANGLE internal compiler +PQXX_HAVE_GCC_PURE public compiler +PQXX_HAVE_GCC_VISIBILITY public compiler +PQXX_HAVE_LIKELY public compiler +PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT public compiler +PQXX_HAVE_PATH public compiler +PQXX_HAVE_POLL internal compiler +PQXX_HAVE_PQENCRYPTPASSWORDCONN internal libpq +PQXX_HAVE_PQ_PIPELINE internal libpq +PQXX_HAVE_SLEEP_FOR internal compiler +PQXX_HAVE_SPAN public compiler +PQXX_HAVE_STRERROR_R internal compiler +PQXX_HAVE_STRERROR_S internal compiler +PQXX_HAVE_THREAD_LOCAL internal compiler +PQXX_HAVE_YEAR_MONTH_DAY public compiler +VERSION internal autotools diff --git a/ext/libpqxx-7.7.3/configure b/ext/libpqxx-7.7.3/configure new file mode 100755 index 0000000..4c58f19 --- /dev/null +++ b/ext/libpqxx-7.7.3/configure @@ -0,0 +1,20443 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for libpqxx 7.7.3. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and Jeroen T. +$0: Vermeulen about your system, including any error +$0: possibly output before this message. Then install a +$0: modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='libpqxx' +PACKAGE_TARNAME='libpqxx' +PACKAGE_VERSION='7.7.3' +PACKAGE_STRING='libpqxx 7.7.3' +PACKAGE_BUGREPORT='Jeroen T. Vermeulen' +PACKAGE_URL='' + +ac_unique_file="src/connection.cxx" +ac_default_prefix=/usr/local +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +with_postgres_lib +POSTGRES_INCLUDE +PG_CONFIG +PKG_CONFIG +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +BUILD_REFERENCE_FALSE +BUILD_REFERENCE_TRUE +HAVE_DOT +DOXYGEN +MKDIR +CXXCPP +CPP +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +PQXX_ABI +PQXXVERSION +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +CSCOPE +ETAGS +CTAGS +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL +am__quote' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_documentation +enable_maintainer_mode +enable_audit +enable_suggest +with_postgres_include +with_postgres_lib +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +LT_SYS_LIBRARY_PATH +CPP +CXXCPP +DOXYGEN +HAVE_DOT' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures libpqxx 7.7.3 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/libpqxx] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of libpqxx 7.7.3:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-documentation Generate documentation + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-postgres-include=DIR + Use PostgreSQL includes from DIR. Defaults to + querying pg_config or pkg-config, whichever is + available. + --with-postgres-lib=DIR Use PostgreSQL libraries from DIR. Defaults to + querying pg_config. + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CC C compiler command + CFLAGS C compiler flags + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + CPP C preprocessor + CXXCPP C++ preprocessor + DOXYGEN Path to doxygen needed to build reference documentation + HAVE_DOT Variable used by doxygen to declare availibility of dot + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +libpqxx configure 7.7.3 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ---------------------------------- ## +## Report this to Jeroen T. Vermeulen ## +## ---------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libpqxx $as_me 7.7.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + +ac_aux_dir= +for ac_dir in config "$srcdir"/config; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + +am__api_version='1.16' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='libpqxx' + VERSION='7.7.3' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi + +if test -z "$ETAGS"; then + ETAGS=etags +fi + +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + +PQXX_ABI=7.7 +PQXXVERSION=$PACKAGE_VERSION + + + +ac_config_headers="$ac_config_headers include/pqxx/config.h" + + +# Default prefix for installs. + + + +# Read test programme from config-test. + + + +# Checks for programs. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=no +fi + + + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cr} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cr libconftest.a conftest.o" >&5 + $AR cr libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[912]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*|11.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "mkdir", so it can be a program name with args. +set dummy mkdir; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MKDIR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MKDIR in + [\\/]* | ?:[\\/]*) + ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MKDIR=$ac_cv_path_MKDIR +if test -n "$MKDIR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 +$as_echo "$MKDIR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# Documentation. +# Check whether --enable-documentation was given. +if test "${enable_documentation+set}" = set; then : + enableval=$enable_documentation; +else + enable_documentation=auto +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}doxygen", so it can be a program name with args. +set dummy ${ac_tool_prefix}doxygen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DOXYGEN+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $DOXYGEN in + [\\/]* | ?:[\\/]*) + ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +DOXYGEN=$ac_cv_path_DOXYGEN +if test -n "$DOXYGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 +$as_echo "$DOXYGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_DOXYGEN"; then + ac_pt_DOXYGEN=$DOXYGEN + # Extract the first word of "doxygen", so it can be a program name with args. +set dummy doxygen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_DOXYGEN+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_DOXYGEN in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_DOXYGEN="$ac_pt_DOXYGEN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_DOXYGEN=$ac_cv_path_ac_pt_DOXYGEN +if test -n "$ac_pt_DOXYGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DOXYGEN" >&5 +$as_echo "$ac_pt_DOXYGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_DOXYGEN" = x; then + DOXYGEN="nodoxygen" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DOXYGEN=$ac_pt_DOXYGEN + fi +else + DOXYGEN="$ac_cv_path_DOXYGEN" +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dot", so it can be a program name with args. +set dummy ${ac_tool_prefix}dot; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_DOT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_DOT"; then + ac_cv_prog_HAVE_DOT="$HAVE_DOT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in NO +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAVE_DOT="${ac_tool_prefix}dot" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +HAVE_DOT=$ac_cv_prog_HAVE_DOT +if test -n "$HAVE_DOT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DOT" >&5 +$as_echo "$HAVE_DOT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_HAVE_DOT"; then + ac_ct_HAVE_DOT=$HAVE_DOT + # Extract the first word of "dot", so it can be a program name with args. +set dummy dot; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_HAVE_DOT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_HAVE_DOT"; then + ac_cv_prog_ac_ct_HAVE_DOT="$ac_ct_HAVE_DOT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in NO +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_HAVE_DOT="dot" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_HAVE_DOT=$ac_cv_prog_ac_ct_HAVE_DOT +if test -n "$ac_ct_HAVE_DOT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_HAVE_DOT" >&5 +$as_echo "$ac_ct_HAVE_DOT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_HAVE_DOT" = x; then + HAVE_DOT="YES" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + HAVE_DOT=$ac_ct_HAVE_DOT + fi +else + HAVE_DOT="$ac_cv_prog_HAVE_DOT" +fi + +if test "$enable_documentation" = "yes" && test "$DOXYGEN" = "nodoxygen"; then : + as_fn_error $? "could not find tools necessary to build documentation" "$LINENO" 5 +fi + if test "$enable_documentation" != "no" -a "$DOXYGEN" != "nodoxygen"; then + BUILD_REFERENCE_TRUE= + BUILD_REFERENCE_FALSE='#' +else + BUILD_REFERENCE_TRUE='#' + BUILD_REFERENCE_FALSE= +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +# See if we want stricter compiler warnings. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking maintainer mode" >&5 +$as_echo_n "checking maintainer mode... " >&6; } +# Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_maintainer_mode}" >&5 +$as_echo "${enable_maintainer_mode}" >&6; } + +# See if we want runtime debug checking. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking audit" >&5 +$as_echo_n "checking audit... " >&6; } +# Check whether --enable-audit was given. +if test "${enable_audit+set}" = set; then : + enableval=$enable_audit; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_audit}" >&5 +$as_echo "${enable_audit}" >&6; } + +# See if we want "suggestions," such as "this class could be final." +# (The suggestions are often useful, but can also easily be wrong.) +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking suggest" >&5 +$as_echo_n "checking suggest... " >&6; } +# Check whether --enable-suggest was given. +if test "${enable_suggest+set}" = set; then : + enableval=$enable_suggest; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_suggest}" >&5 +$as_echo "${enable_suggest}" >&6; } + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; +fi + +if test "${shared}" = "yes" ; then : + CPPFLAGS="$CPPFLAGS -DPQXX_SHARED" +fi + + +# Add options to compiler command line, if compiler accepts them. +add_compiler_opts_if_ok() { + for option in $* + do + ACO_SAVE_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $option" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts $option" >&5 +$as_echo_n "checking whether $CXX accepts $option... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + has_option=yes +else + has_option=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_option" >&5 +$as_echo "$has_option" >&6; } + if test "$has_option" = "no" ; then : + CXXFLAGS="$ACO_SAVE_CXXFLAGS" +fi + done +} + + +# Add options to compiler command line, unconditionally. +add_compiler_opts() { + CXXFLAGS="$CXXFLAGS $*" +} + + +# It's tempting to use Autoconf Archive's AX_CXX_COMPILE_STDCXX_17 for this, +# but it's 2022 and the C++20 equivalent isn't quite ready for use. +# Seems simpler and more reliable for the user to arrange for the desired +# language versions by setting the appropriate option for their compiler. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sufficient C++ language/library level" >&5 +$as_echo_n "checking for sufficient C++ language/library level... " >&6; } +sufficient_cxx=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #if __cplusplus < 201611L + #error "Need C++17 or better." + #endif + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + sufficient_cxx=yes +else + sufficient_cxx=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sufficient_cxx" >&5 +$as_echo "$sufficient_cxx" >&6; } +if test "$sufficient_cxx" != "yes" +then + as_fn_error $? "This libpqxx version needs at least C++17." "$LINENO" 5 +fi + + +# Let's try to get the compiler to be helpful. +# +# (Omit options -Weffc++ and -Wabi because they currently yield too many +# warnings in gcc's standard headers; omit -Wunreachable-code because it isn't +# always right) +if test "$GCC" = "yes" +then + # In maintainer mode, enable all the warning options we can. + if test "$enable_maintainer_mode" = "yes" + then + # "Eternal" (FLW) g++ options. These have been around for + # ages, and both g++ and clang++ support them. Don't bother + # checking for support; just add them to the compiler options. + add_compiler_opts \ + -fstrict-enums \ + -Werror \ + -Wall \ + -pedantic \ + -Wcast-align \ + -Wcast-qual \ + -Wconversion \ + -Wctor-dtor-privacy \ + -Wendif-labels \ + -Wextra \ + -Wfloat-equal \ + -Wformat=2 \ + -Wformat-security \ + -Wmissing-include-dirs \ + -Wno-div-by-zero \ + -Wnon-virtual-dtor \ + -Wold-style-cast \ + -Woverlength-strings \ + -Woverloaded-virtual \ + -Wpointer-arith \ + -Wredundant-decls \ + -Wshadow \ + -Wsign-promo \ + -Wundef \ + -Wunused \ + -Wwrite-strings + + # "Iffy" g++ options. Some reasonably current g++-like + # compilers may not support these. + add_compiler_opts_if_ok \ + -fnothrow-opt \ + -Wattribute-alias=2 \ + -Wextra-semi \ + -Wlogical-op \ + -Wmismatched-tags \ + -Wnoexcept \ + -Wredundant-tags \ + -Wrestrict \ + -Wstringop-overflow \ + -Wzero-as-null-pointer-constant \ + -Warray-bounds=2 \ + -Wduplicated-branches \ + -Wduplicated-cond \ + -Wsuggest-attribute=noreturn \ + -Wsuggest-override \ + -Wtrampolines + fi + + # In "audit," enable all runtime checks we can. + if test "$enable_audit" = "yes" + then + add_compiler_opts_if_ok \ + -D_FORTIFY_SOURCE=2 \ + -fsanitize=address \ + -fsanitize-address-use-after-scope \ + -fsanitize=alignment \ + -fsanitize=bool \ + -fsanitize=bounds \ + -fsanitize=bounds-strict \ + -fsanitize=builtin \ + -fsanitize=enum \ + -fsanitize=float-cast-overflow \ + -fsanitize=float-divide-by-zero \ + -fsanitize=integer-divide-by-zero \ + -fsanitize=leak \ + -fsanitize=nonnull-attribute \ + -fsanitize=null \ + -fsanitize=object-size \ + -fsanitize=pointer-compare \ + -fsanitize=pointer-overflow \ + -fsanitize=pointer-subtract \ + -fsanitize=return \ + -fsanitize=returns-nonnull-attribute \ + -fsanitize=shift \ + -fsanitize=shift-base \ + -fsanitize=shift-exponent \ + -fsanitize=signed-integer-overflow \ + -fsanitize=undefined \ + -fsanitize=unreachable \ + -fsanitize=vla-bound \ + -fsanitize=vptr \ + -fstack-protector-all + fi + + # In "suggest" mode, enable a bunch of code suggestions. + if test "$enable_suggest" = "yes" + then + add_compiler_opts_if_ok \ + -Wsuggest-attribute=cold \ + -Wsuggest-attribute=const \ + -Wsuggest-attribute=malloc \ + -Wsuggest-attribute=pure \ + -Wsuggest-final-types \ + -Wsuggest-final-methods + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking g++ visibility attribute" >&5 +$as_echo_n "checking g++ visibility attribute... " >&6; } +gcc_visibility=yes +SAVE_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS -Werror" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for gcc-style "visibility" attribute. + +struct __attribute__((visibility("hidden"))) D + +{ + + D() {} + + int f() { return 0; } + +}; + + + +int main() + +{ + + D d; + + return d.f(); + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_GCC_VISIBILITY 1" >>confdefs.h + +else + gcc_visibility=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_visibility" >&5 +$as_echo "$gcc_visibility" >&6; } +CXXFLAGS="$SAVE_CXXFLAGS" +if test "$gcc_visibility" = "yes" +then + # Make internal definitions accessible only to the library itself. + # Only definitions marked PQXX_LIBEXPORT will be accessible. + add_compiler_opts -fvisibility=hidden + add_compiler_opts -fvisibility-inlines-hidden +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking g++ pure attribute" >&5 +$as_echo_n "checking g++ pure attribute... " >&6; } +gcc_pure=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for gcc-style "pure" attribute. + +int __attribute__((pure)) f() + +{ + + return 0; + +} + + + +int main() + +{ + + return f(); + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_GCC_PURE 1" >>confdefs.h + +else + gcc_pure=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_pure" >&5 +$as_echo "$gcc_pure" >&6; } + +fi # End of gcc-specific part. + + +# Check for __cxa_demangle. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking __cxa_demangle" >&5 +$as_echo_n "checking __cxa_demangle... " >&6; } +cxa_demangle=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for cross-vendor C++ ABI's __cxa_demangle function. + +#include + +#include + +#include + +#include + + + +#include + + + +int main() + +{ + + int status = 0; + + char *name = + + abi::__cxa_demangle(typeid(10).name(), nullptr, nullptr, &status); + + if (status != 0) + + throw std::runtime_error("Demangle failed!"); + + int result = std::strcmp(name, "int"); + + std::free(name); + + return result; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CXA_DEMANGLE 1" >>confdefs.h + +else + cxa_demangle=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cxa_demangle" >&5 +$as_echo "$cxa_demangle" >&6; } + + +# Check for sufficient Concepts support, introduced with C++20. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking concepts" >&5 +$as_echo_n "checking concepts... " >&6; } +concepts=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for concepts support. Not just the language feature; also headers. + +#include + +#include + +#include + + + + + +template + +concept Foo = std::ranges::input_range; + + + + + +template auto foo(F const &r) + +{ + + return std::distance(std::begin(r), std::end(r)); + +} + + + + + +int main() + +{ + + std::vector const v{1, 2, 3}; + + std::cout << foo(v) << '\n'; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CONCEPTS 1" >>confdefs.h + +else + concepts=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $concepts" >&5 +$as_echo "$concepts" >&6; } + + +# Check for C++20 std::span. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking std::span" >&5 +$as_echo_n "checking std::span... " >&6; } +span=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::span. + +#include + + + +int main(int argc, char **argv) + +{ + + std::span args{argv, static_cast(argc)}; + + return static_cast(std::size(args) - 1u); + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_SPAN 1" >>confdefs.h + +else + span=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $span" >&5 +$as_echo "$span" >&6; } + + +# Check for multidimensional subscript operator support. Proposed for C++23. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for multidimensional subscript operator support" >&5 +$as_echo_n "checking for multidimensional subscript operator support... " >&6; } +multidim_subscript=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for multidimensional subscript operator support. + +// Proposed for C++23: P2128R6. + +struct table + +{ + + int width = 100; + + + + int operator[](int x, int y) const { return x + width * y; } + +}; + + + + + +int main() + +{ + + return table{}[0, 0]; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT 1" >>confdefs.h + +else + multidim_subscript=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $multidim_subscript" >&5 +$as_echo "$multidim_subscript" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strerror_r()" >&5 +$as_echo_n "checking for strerror_r()... " >&6; } +strerror_r=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Check for strerror_r. + +// It can be either the POSIX version (which returns int) or the GNU version + +// (which returns char *). + + + +#include + +#include + + + +int main() + +{ + + char buffer[200]; + + auto res{strerror_r(1, buffer, 200)}; + + // Sidestep type differences. We don't really care what the value is. + + return not not res; + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_STRERROR_R 1" >>confdefs.h + +else + strerror_r=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $strerror_r" >&5 +$as_echo "$strerror_r" >&6; } + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strerror_s()" >&5 +$as_echo_n "checking for strerror_s()... " >&6; } +strerror_s=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for strerror_s, as defined in Windows and C11. + +// Presumably this'll be part of the C++ standard some day. + + + +#include + + + +int main() + +{ + + using namespace std; + + char buf[200]; + + return strerror_s(buf, 200, 1); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_STRERROR_S 1" >>confdefs.h + +else + strerror_s=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $strerror_s" >&5 +$as_echo "$strerror_s" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::chrono::year_month_day etc" >&5 +$as_echo_n "checking for std::chrono::year_month_day etc... " >&6; } +year_month_day=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::chrono::year_month_day etc. + +#include + + + +int main() + +{ + + return int(std::chrono::year{1}); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_YEAR_MONTH_DAY 1" >>confdefs.h + +else + year_month_day=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $year_month_day" >&5 +$as_echo "$year_month_day" >&6; } + + +# Check for [[likely]] and [[unlikely]] attributes. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking attributes \"likely\" and \"unlikely\"." >&5 +$as_echo_n "checking attributes \"likely\" and \"unlikely\".... " >&6; } +likely=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for C++20 [[likely]] and [[unlikely]] attributes. + + + +int main(int argc, char **) + +{ + +#if __cplusplus < 202002L + + deliberately_fail(because, older, C++, standard); + +#endif + + + + int x = 0; + + if (argc == 1) [[likely]] + + x = 0; + + else + + x = 1; + + return x; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_LIKELY 1" >>confdefs.h + +else + likely=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $likely" >&5 +$as_echo "$likely" >&6; } + + +# It's mid-2019, and gcc's charconv supports integers but not yet floats. +# So for now, we test for int and float conversion... separately. +# +# It's worse for older clang versions, which compile the integer conversions +# but then fail at link time because of a missing symbol "__muloti4" with the +# "long long" version. I couldn't resolve that symbol by adding -lm either. +# So don't just compile these tests; link them as well. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++17 charconv integer conversion" >&5 +$as_echo_n "checking for C++17 charconv integer conversion... " >&6; } +have_charconv_int=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::to_string/std::from_string for integral types. + +#include + +#include + + + +int main() + +{ + + char z[100]; + + auto rt = std::to_chars(std::begin(z), std::end(z), 9ULL); + + if (rt.ec != std::errc{}) + + return 1; + + unsigned long long n; + + auto rf = std::from_chars(std::cbegin(z), std::cend(z), n); + + if (rf.ec != std::errc{}) + + return 2; + + return (n == 9ULL) ? 0 : 1; + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CHARCONV_INT 1" >>confdefs.h + +else + have_charconv_int=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_charconv_int" >&5 +$as_echo "$have_charconv_int" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++17 charconv floating-point conversion" >&5 +$as_echo_n "checking for C++17 charconv floating-point conversion... " >&6; } +have_charconv_float=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::to_string/std::from_string for floating-point types. + +#include + +#include + + + +int main() + +{ + + char z[100]; + + auto rt = std::to_chars(std::begin(z), std::end(z), 3.14159L); + + if (rt.ec != std::errc{}) + + return 1; + + long double n; + + auto rf = std::from_chars(std::cbegin(z), std::cend(z), n); + + if (rf.ec != std::errc{}) + + return 2; + + return (n > 3 and n < 4) ? 0 : 1; + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CHARCONV_FLOAT 1" >>confdefs.h + +else + have_charconv_float=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_charconv_float" >&5 +$as_echo "$have_charconv_float" >&6; } + +# As per #262, clang with libcxxrt does not support thread_local on non-POD +# objects. Luckily we can live without those, it's just less efficient. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for full thread_local support" >&5 +$as_echo_n "checking for full thread_local support... " >&6; } +have_thread_local=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::to_string/std::from_string for floating-point types. + +#include + +#include + + + +int main(int argc, char **) + +{ + +#if defined(__MINGW32__) && defined(__GNUC__) + +# if __GNUC__ < 11 || ((__GNUC__ == 11) && (__GNU_MINOR__ == 0)) + +# error "On MinGW before gcc 11.1, thread_local breaks at run time." + +# endif + +#endif + + thread_local std::stringstream s; + + s << argc; + + std::cout << s.str(); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_THREAD_LOCAL 1" >>confdefs.h + +else + have_thread_local=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_thread_local" >&5 +$as_echo "$have_thread_local" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::this_thread::sleep_for" >&5 +$as_echo_n "checking for std::this_thread::sleep_for... " >&6; } +have_sleep_for=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for std::this_thread::sleep_for(). + +/* For some reason MinGW's header seems to be broken. + + * + + * But it gets worse. It looks as if we can include without problems + + * in this configuration test. Why does it break when MinGW users try to build + + * the library, but succeed when we try it here? + + * + + * To try and get close to the situation in the library code itself, we try + + * including some standard headers that we don't strictly need here. + + */ + + + +#if __has_include() + +# include + +#endif + + + +#include + +#include + +#include + +#include + +#include + + + +#include + +#include + + + +int main() + +{ + + std::this_thread::sleep_for(std::chrono::microseconds{10u}); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_SLEEP_FOR 1" >>confdefs.h + +else + have_sleep_for=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sleep_for" >&5 +$as_echo "$have_sleep_for" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::cmp_greater, std::cmp_less_equal, etc" >&5 +$as_echo_n "checking for std::cmp_greater, std::cmp_less_equal, etc... " >&6; } +have_cmp=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for C++20 std::cmp_greater etc. support. + +#include + + + + + +int main() + +{ + + return std::cmp_greater(-1, 2u) && std::cmp_less_equal(3, 0); + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_CMP 1" >>confdefs.h + +else + have_cmp=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_cmp" >&5 +$as_echo "$have_cmp" >&6; } + + +# Doing my own check for poll(). There's one built into autoconf-archive, but +# it produces warnings in C++ (about unnecessarily using "struct", and using 0 +# as a null pointer constant). In maintainer mode, those warnings turn into +# errors. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for poll()" >&5 +$as_echo_n "checking for poll()... " >&6; } +ax_cv_have_poll=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Test for poll(). + +#include + + + +int main() + +{ + + return poll(nullptr, 0, 0); + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_POLL 1" >>confdefs.h + +else + ax_cv_have_poll=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_poll" >&5 +$as_echo "$ax_cv_have_poll" >&6; } + +if test "$ax_cv_have_poll" != "yes" +then +# No poll(); we'll fall back to select(). + +# Some systems keep select() in a separate library which is not linked by +# default. See if we need one of those. +socklibok=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing select" >&5 +$as_echo_n "checking for library containing select... " >&6; } +if ${ac_cv_search_select+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char select (); +int +main () +{ +return select (); + ; + return 0; +} +_ACEOF +for ac_lib in '' socket nsl ws2_32 wsock32 winsock; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_search_select=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_select+:} false; then : + break +fi +done +if ${ac_cv_search_select+:} false; then : + +else + ac_cv_search_select=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_select" >&5 +$as_echo "$ac_cv_search_select" >&6; } +ac_res=$ac_cv_search_select +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + socklibok=yes +fi + + +# Microsoft proprietary libraries do not work with code that is generated with +# autoconf's SEARCH_LIBS macro, so we need to check manually and just use the +# first socket library available. +# We only do this if select() is not available by other means, to avoid picking +# up an unnecessary Windows compatibility library on a non-Windows system. +for l in ws2_32 wsock32 winsock +do + if test "${socklibok}" != "yes" + then + as_ac_Lib=`$as_echo "ac_cv_lib_$l''_main" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -l$l" >&5 +$as_echo_n "checking for main in -l$l... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$l $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + LIBS="$LIBS -l$l";socklibok=yes +fi + + fi +done + +if test "${socklibok}" != "yes" +then + as_fn_error $? " +Could not figure out how to link a simple sockets-based program. Please read +the config.log file for more clues as to why this failed. +" "$LINENO" 5 +fi + +fi # No poll() + + +# Find PostgreSQL includes and libraries +# Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +for ac_prog in pg_config +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PG_CONFIG=$ac_cv_path_PG_CONFIG +if test -n "$PG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PG_CONFIG" >&5 +$as_echo "$PG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PG_CONFIG" && break +done + + + +# Check whether --with-postgres-include was given. +if test "${with_postgres_include+set}" = set; then : + withval=$with_postgres_include; if test "x$with_postgres_include" = "xyes"; then : + with_postgres_include="" +fi +fi + + +if test -n "$with_postgres_include" +then + POSTGRES_INCLUDE="-I$with_postgres_include" +else + if test -x "$PKG_CONFIG" || test -x "$PG_CONFIG" + then + # We should prefer pkg-config over pg_config, but there seems to be a + # problem in pkg-config 1.6.3. Until that's been resolved (#291), go + # with pg_config if we can. + if test -x "$PG_CONFIG" + then + # From pg_config we can either get the C compiler options used to + # compile postgres, which isn't quite what we want; or we can get + # the headers directory, without the full option. That's something + # we can work with. The compiler must support the "-I" option for + # that, but both scripts assume that anyway. + POSTGRES_INCLUDE="-I$($PG_CONFIG --includedir)" + else + # From pkg-config we can get the compiler options to extend the + # include path. We use that. + POSTGRES_INCLUDE=$($PKG_CONFIG libpq --cflags-only-I) + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: finding PostgreSQL headers using $POSTGRES_INCLUDE" >&5 +$as_echo "$as_me: finding PostgreSQL headers using $POSTGRES_INCLUDE" >&6;} + else + POSTGRES_INCLUDE="" + + # We have nothing to tell us where the libpq headers are. That's fine + # if the compiler can find it, but if not, fail here. + +ac_fn_cxx_check_header_mongrel "$LINENO" "libpq-fe.h" "ac_cv_header_libpq_fe_h" "$ac_includes_default" +if test "x$ac_cv_header_libpq_fe_h" = xyes; then : + +else + as_fn_error $? " +Can't find the main PostgreSQL client header, libpq-fe.h. Make sure that it +is installed, and either use the --with-postgres-include option or install +pkg-config. +" "$LINENO" 5 +fi + + + fi +fi + + +# Add the compiler option so we can compile configure tests which rely on the +# libpq headers. +CPPFLAGS="$CPPFLAGS $POSTGRES_INCLUDE" + + + +# Check whether --with-postgres-lib was given. +if test "${with_postgres_lib+set}" = set; then : + withval=$with_postgres_lib; if test "x$with_postgres_lib" = "xyes"; then : + with_postgres_lib="" +fi +fi + + +# If no --with-postgres-lib was given, and we have pkg-config, use that. +if test -z "$with_postgres_lib" -a -x "$PKG_CONFIG"; then : + with_postgres_lib=$($PKG_CONFIG libpq --libs-only-L | sed 's/^-L//') +fi + +# pg_config is deprecated, but for some users it may still provide the only +# right answer. For instance, `pkg-config` may not know where `libpq` is +# installed. +if test -z "$with_postgres_lib" -a -x "$PG_CONFIG"; then : + with_postgres_lib=$($PG_CONFIG --libdir) +fi + +if test -n "$with_postgres_lib"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: using PostgreSQL libraries at $with_postgres_lib" >&5 +$as_echo "$as_me: using PostgreSQL libraries at $with_postgres_lib" >&6;} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: using PostgreSQL libraries in default location" >&5 +$as_echo "$as_me: using PostgreSQL libraries in default location" >&6;} +fi + + + + +ac_fn_cxx_check_header_mongrel "$LINENO" "libpq-fe.h" "ac_cv_header_libpq_fe_h" "$ac_includes_default" +if test "x$ac_cv_header_libpq_fe_h" = xyes; then : + +else + as_fn_error $? " +Can't find the main PostgreSQL client header, libpq-fe.h. Are you sure the +libpq headers are installed correctly, and that we've got the right path? +" "$LINENO" 5 +fi + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ability to compile source files using libpq" >&5 +$as_echo_n "checking for ability to compile source files using libpq... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +PQexec(nullptr,"") + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + as_fn_error $? " +Could not compile a call to a basic libpq function. There must be something +seriously wrong with the headers that \"pg_config --includedir\" or \"pkg-config +libpq --cflags\" pointed to; the contents of config.log may give you a clue +about the nature of the failure. +Source including the libpq header libpq-fe.h can be compiled, but a call to the +most basic libpq function PQexec() failed to compile successfully. This is the +litmus test for a working libpq. +" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + +if test "x${with_postgres_lib}" = "x"; then + with_postgres_libpath="" +else + with_postgres_libpath="-L${with_postgres_lib}" +fi +LDFLAGS="$LDFLAGS ${with_postgres_libpath}" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQexec in -lpq" >&5 +$as_echo_n "checking for PQexec in -lpq... " >&6; } +if ${ac_cv_lib_pq_PQexec+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpq ${with_postgres_libpath} $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char PQexec (); +int +main () +{ +return PQexec (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_pq_PQexec=yes +else + ac_cv_lib_pq_PQexec=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQexec" >&5 +$as_echo "$ac_cv_lib_pq_PQexec" >&6; } +if test "x$ac_cv_lib_pq_PQexec" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPQ 1 +_ACEOF + + LIBS="-lpq $LIBS" + +else + as_fn_error $? " +Did not find the PQexec() function in libpq. This is the litmus test for a +working libpq installation. + +A source file using the PQexec() function did compile without problems, and the +libpq library is available for linking, but for some reason a call to PQexec() +failed to link properly to the libpq library. This may be because the libpq +library file is damaged, or in some incorrect format, or if your libpq is much +more recent than libpqxx version $PQXX_ABI, perhaps libpq has undergone a +radical ABI change. + +The last parts of config.log may give you a clue as to what really went wrong, +but be warned that this is no easy reading. Look for the last error message +occurring in the file. +" "$LINENO" 5 +fi + + + +# PQencryptPasswordConn was added in postgres 10. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQencryptPasswordConn" >&5 +$as_echo_n "checking for PQencryptPasswordConn... " >&6; } +have_pqencryptpasswordconn=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + extern PGconn *conn; + PQencryptPasswordConn( + conn, "pwd", "user", "scram-sha-256") + + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_PQENCRYPTPASSWORDCONN 1" >>confdefs.h + +else + have_pqencryptpasswordconn=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pqencryptpasswordconn" >&5 +$as_echo "$have_pqencryptpasswordconn" >&6; } + + +# "Pipeline mode" was introduced in libpq 14. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpq pipeline mode" >&5 +$as_echo_n "checking for libpq pipeline mode... " >&6; } +have_pq_pipeline=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + extern PGconn *conn; + PQenterPipelineMode(conn) + + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_PQ_PIPELINE 1" >>confdefs.h + +else + have_pq_pipeline=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pq_pipeline" >&5 +$as_echo "$have_pq_pipeline" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for usable std::filesystem::path" >&5 +$as_echo_n "checking for usable std::filesystem::path... " >&6; } +have_path=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Check for working std::filesystem support. + +#include + + + + + +int main() + +{ + + // Apparently some versions of MinGW lack this comparison operator. + + return std::filesystem::path{} != std::filesystem::path{}; + +} + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define PQXX_HAVE_PATH 1" >>confdefs.h + +else + have_path=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_path" >&5 +$as_echo "$have_path" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need a link option for support" >&5 +$as_echo_n "checking whether we need a link option for support... " >&6; } +LIBS_SAVE="$LIBS" +found_fslib=no +for l in '' '-lstdc++fs' '-lc++fs' +do + if test "$found_fslib" != "yes" + then + LIBS="$LIBS $l" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +// Check whether we need to link to the stdc++fs library. + +// + +// We assume that the presence of the header means that we have + +// support for the basics of std::filesystem. This check will succeed if + +// either there is no header, or there is one and it works without + +// any special options. If the link fails, we assume that -lstdc++fs will fix + +// it for us. + + + +#include + + + +#if __has_include() + +# include + +#endif + + + + + +int main() + +{ + +#if __has_include() + + std::cout << std::filesystem::path{"foo.bar"}.c_str() << '\n'; + +#endif + +} + + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + found_fslib=yes +else + LIBS="$LIBS_SAVE" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$found_fslib" = "yes" + then + result_msg="$l" + # (And keep our current value of $LIBS.) + fi + fi +done + +if test "$found_fslib" != "yes" +then + as_fn_error $? " +There seems to be support, but I could not figure out now to make +it work. You'll have to add set your own build options for this. + " "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $result_msg" >&5 +$as_echo "$result_msg" >&6; } + + +# Remove redundant occurrances of -lpq +LIBS=$(echo "$LIBS" | sed -e 's/-lpq * -lpq\>/-lpq/g') + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that type of libpq's Oid is as expected" >&5 +$as_echo_n "checking that type of libpq's Oid is as expected... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include"${srcdir}/include/pqxx/internal/libpq-forward.hxx" + extern void f(pqxx::oid&); + +int +main () +{ +Oid o;f(o) + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + as_fn_error $? " +The Oid typedef in libpq has changed. Please notify the libpqxx authors of the +change! +" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + +ac_config_files="$ac_config_files Makefile config/Makefile doc/Makefile doc/Doxyfile src/Makefile test/Makefile tools/Makefile include/Makefile include/pqxx/Makefile libpqxx.pc" + + + +ac_config_commands="$ac_config_commands configitems" + + +ac_config_files="$ac_config_files compile_flags" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_REFERENCE_TRUE}" && test -z "${BUILD_REFERENCE_FALSE}"; then + as_fn_error $? "conditional \"BUILD_REFERENCE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by libpqxx $as_me 7.7.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +libpqxx config.status 7.7.3 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "include/pqxx/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/pqxx/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "config/Makefile") CONFIG_FILES="$CONFIG_FILES config/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "include/pqxx/Makefile") CONFIG_FILES="$CONFIG_FILES include/pqxx/Makefile" ;; + "libpqxx.pc") CONFIG_FILES="$CONFIG_FILES libpqxx.pc" ;; + "configitems") CONFIG_COMMANDS="$CONFIG_COMMANDS configitems" ;; + "compile_flags") CONFIG_FILES="$CONFIG_FILES compile_flags" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? + done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# The names of the tagged configurations supported by this script. +available_tags='CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + "configitems":C) "${srcdir}/tools/splitconfig" "${srcdir}" ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/ext/libpqxx-7.7.3/configure.ac b/ext/libpqxx-7.7.3/configure.ac new file mode 100644 index 0000000..d6351fa --- /dev/null +++ b/ext/libpqxx-7.7.3/configure.ac @@ -0,0 +1,738 @@ +# Generate configure script for libpqxx. This needs the autoconf archive +# package installed. (The configure script itself does not require it though.) + +AC_PREREQ(2.69) +AC_INIT( + libpqxx, + [m4_esyscmd_s([./tools/extract_version])], + [Jeroen T. Vermeulen]) +AC_LANG(C++) + +AC_CONFIG_SRCDIR([src/connection.cxx]) +AC_CONFIG_AUX_DIR(config) +AC_CONFIG_MACRO_DIR([config/m4]) +AM_INIT_AUTOMAKE([subdir-objects]) + +PQXX_ABI=m4_esyscmd_s([./tools/extract_version --abi]) +AC_SUBST(PQXXVERSION, $PACKAGE_VERSION) +AC_SUBST(PQXX_ABI) + +AC_CONFIG_HEADER([include/pqxx/config.h]) + +# Default prefix for installs. +AC_PREFIX_DEFAULT(/usr/local) + + +# Read test programme from config-test. +AC_DEFUN([read_test], [AC_LANG_SOURCE( + esyscmd(tools/m4esc.py --input=config-tests/$1))]) + + +# Checks for programs. +AC_PROG_CXX +AC_PROG_INSTALL +AC_DISABLE_SHARED +AC_PROG_LIBTOOL +AC_PROG_MAKE_SET +AC_PATH_PROG([MKDIR], [mkdir]) + +# Documentation. +AC_ARG_ENABLE( + documentation, + [AS_HELP_STRING([--enable-documentation], [Generate documentation])], + [], + [enable_documentation=auto]) +AC_ARG_VAR([DOXYGEN], + [Path to doxygen needed to build reference documentation]) +AC_PATH_TOOL([DOXYGEN], [doxygen], [nodoxygen]) +AC_ARG_VAR([HAVE_DOT], + [Variable used by doxygen to declare availibility of dot]) +AC_CHECK_TOOL([HAVE_DOT], [dot], [YES], [NO]) +AS_IF([test "$enable_documentation" = "yes" && test "$DOXYGEN" = "nodoxygen"], + [AC_MSG_ERROR([could not find tools necessary to build documentation])]) +AM_CONDITIONAL([BUILD_REFERENCE], + [test "$enable_documentation" != "no" -a "$DOXYGEN" != "nodoxygen"]) + +AM_MAINTAINER_MODE + +# See if we want stricter compiler warnings. +AC_MSG_CHECKING([maintainer mode]) +AC_ARG_ENABLE(maintainer-mode) +AC_MSG_RESULT(${enable_maintainer_mode}) + +# See if we want runtime debug checking. +AC_MSG_CHECKING([audit]) +AC_ARG_ENABLE(audit) +AC_MSG_RESULT(${enable_audit}) + +# See if we want "suggestions," such as "this class could be final." +# (The suggestions are often useful, but can also easily be wrong.) +AC_MSG_CHECKING([suggest]) +AC_ARG_ENABLE(suggest) +AC_MSG_RESULT(${enable_suggest}) + + +AC_ARG_ENABLE(shared) +AS_IF( + [test "${shared}" = "yes" ], + [CPPFLAGS="$CPPFLAGS -DPQXX_SHARED"]) + + +# Add options to compiler command line, if compiler accepts them. +add_compiler_opts_if_ok() { + for option in $* + do + ACO_SAVE_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $option" + AC_MSG_CHECKING([whether $CXX accepts $option]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([], [])], + has_option=yes, + has_option=no) + AC_MSG_RESULT($has_option) + AS_IF( + [test "$has_option" = "no" ], + [CXXFLAGS="$ACO_SAVE_CXXFLAGS"]) + done +} + + +# Add options to compiler command line, unconditionally. +add_compiler_opts() { + CXXFLAGS="$CXXFLAGS $*" +} + + +# It's tempting to use Autoconf Archive's AX_CXX_COMPILE_STDCXX_17 for this, +# but it's 2022 and the C++20 equivalent isn't quite ready for use. +# Seems simpler and more reliable for the user to arrange for the desired +# language versions by setting the appropriate option for their compiler. +AC_MSG_CHECKING([for sufficient C++ language/library level]) +sufficient_cxx=yes +AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([ + #if __cplusplus < 201611L + #error "Need C++17 or better." + #endif + ])], + sufficient_cxx=yes, + sufficient_cxx=no) +AC_MSG_RESULT($sufficient_cxx) +if test "$sufficient_cxx" != "yes" +then + AC_MSG_ERROR([This libpqxx version needs at least C++17.]) +fi + + +# Let's try to get the compiler to be helpful. +# +# (Omit options -Weffc++ and -Wabi because they currently yield too many +# warnings in gcc's standard headers; omit -Wunreachable-code because it isn't +# always right) +if test "$GCC" = "yes" +then + # In maintainer mode, enable all the warning options we can. + if test "$enable_maintainer_mode" = "yes" + then + # "Eternal" (FLW) g++ options. These have been around for + # ages, and both g++ and clang++ support them. Don't bother + # checking for support; just add them to the compiler options. + add_compiler_opts \ + -fstrict-enums \ + -Werror \ + -Wall \ + -pedantic \ + -Wcast-align \ + -Wcast-qual \ + -Wconversion \ + -Wctor-dtor-privacy \ + -Wendif-labels \ + -Wextra \ + -Wfloat-equal \ + -Wformat=2 \ + -Wformat-security \ + -Wmissing-include-dirs \ + -Wno-div-by-zero \ + -Wnon-virtual-dtor \ + -Wold-style-cast \ + -Woverlength-strings \ + -Woverloaded-virtual \ + -Wpointer-arith \ + -Wredundant-decls \ + -Wshadow \ + -Wsign-promo \ + -Wundef \ + -Wunused \ + -Wwrite-strings + + # "Iffy" g++ options. Some reasonably current g++-like + # compilers may not support these. + add_compiler_opts_if_ok \ + -fnothrow-opt \ + -Wattribute-alias=2 \ + -Wextra-semi \ + -Wlogical-op \ + -Wmismatched-tags \ + -Wnoexcept \ + -Wredundant-tags \ + -Wrestrict \ + -Wstringop-overflow \ + -Wzero-as-null-pointer-constant \ + -Warray-bounds=2 \ + -Wduplicated-branches \ + -Wduplicated-cond \ + -Wsuggest-attribute=noreturn \ + -Wsuggest-override \ + -Wtrampolines + fi + + # In "audit," enable all runtime checks we can. + if test "$enable_audit" = "yes" + then + add_compiler_opts_if_ok \ + -D_FORTIFY_SOURCE=2 \ + -fsanitize=address \ + -fsanitize-address-use-after-scope \ + -fsanitize=alignment \ + -fsanitize=bool \ + -fsanitize=bounds \ + -fsanitize=bounds-strict \ + -fsanitize=builtin \ + -fsanitize=enum \ + -fsanitize=float-cast-overflow \ + -fsanitize=float-divide-by-zero \ + -fsanitize=integer-divide-by-zero \ + -fsanitize=leak \ + -fsanitize=nonnull-attribute \ + -fsanitize=null \ + -fsanitize=object-size \ + -fsanitize=pointer-compare \ + -fsanitize=pointer-overflow \ + -fsanitize=pointer-subtract \ + -fsanitize=return \ + -fsanitize=returns-nonnull-attribute \ + -fsanitize=shift \ + -fsanitize=shift-base \ + -fsanitize=shift-exponent \ + -fsanitize=signed-integer-overflow \ + -fsanitize=undefined \ + -fsanitize=unreachable \ + -fsanitize=vla-bound \ + -fsanitize=vptr \ + -fstack-protector-all + fi + + # In "suggest" mode, enable a bunch of code suggestions. + if test "$enable_suggest" = "yes" + then + add_compiler_opts_if_ok \ + -Wsuggest-attribute=cold \ + -Wsuggest-attribute=const \ + -Wsuggest-attribute=malloc \ + -Wsuggest-attribute=pure \ + -Wsuggest-final-types \ + -Wsuggest-final-methods + fi + +AC_MSG_CHECKING([g++ visibility attribute]) +gcc_visibility=yes +SAVE_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS -Werror" +AC_COMPILE_IFELSE( + [read_test(gcc_visibility.cxx)], + AC_DEFINE( + [PQXX_HAVE_GCC_VISIBILITY], + 1, + [Define if g++ supports visibility attribute.]), + gcc_visibility=no) +AC_MSG_RESULT($gcc_visibility) +CXXFLAGS="$SAVE_CXXFLAGS" +if test "$gcc_visibility" = "yes" +then + # Make internal definitions accessible only to the library itself. + # Only definitions marked PQXX_LIBEXPORT will be accessible. + add_compiler_opts -fvisibility=hidden + add_compiler_opts -fvisibility-inlines-hidden +fi + +AC_MSG_CHECKING([g++ pure attribute]) +gcc_pure=yes +AC_COMPILE_IFELSE( + [read_test(gcc_pure.cxx)], + AC_DEFINE( + [PQXX_HAVE_GCC_PURE], + 1, + [Define if g++ supports pure attribute]), + gcc_pure=no) +AC_MSG_RESULT($gcc_pure) + +fi # End of gcc-specific part. + + +# Check for __cxa_demangle. +AC_MSG_CHECKING([__cxa_demangle]) +cxa_demangle=yes +AC_COMPILE_IFELSE( + [read_test(cxa_demangle.cxx)], + AC_DEFINE( + [PQXX_HAVE_CXA_DEMANGLE], + 1, + [Define if compiler supports __cxa_demangle]), + cxa_demangle=no) +AC_MSG_RESULT($cxa_demangle) + + +# Check for sufficient Concepts support, introduced with C++20. +AC_MSG_CHECKING([concepts]) +concepts=yes +AC_COMPILE_IFELSE( + [read_test(concepts.cxx)], + AC_DEFINE( + [PQXX_HAVE_CONCEPTS], + 1, + [Define if compiler supports Concepts and header.]), + concepts=no) +AC_MSG_RESULT($concepts) + + +# Check for C++20 std::span. +AC_MSG_CHECKING([std::span]) +span=yes +AC_COMPILE_IFELSE( + [read_test(span.cxx)], + AC_DEFINE([PQXX_HAVE_SPAN], 1, [Define if compiler has std::span.]), + span=no) +AC_MSG_RESULT($span) + + +# Check for multidimensional subscript operator support. Proposed for C++23. +AC_MSG_CHECKING([for multidimensional subscript operator support]) +multidim_subscript=yes +AC_COMPILE_IFELSE( + [read_test(multidim-subscript.cxx)], + AC_DEFINE( + [PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT], 1, + [Define if operator[] can take multiple arguments.]), + multidim_subscript=no) +AC_MSG_RESULT($multidim_subscript) + + +AC_MSG_CHECKING([for strerror_r()]) +strerror_r=yes +AC_LINK_IFELSE( + [read_test(strerror_r.cxx)], + AC_DEFINE( + [PQXX_HAVE_STRERROR_R], + 1, + [Define if strerror_r() is available.]), + strerror_r=no) +AC_MSG_RESULT($strerror_r) + + + +AC_MSG_CHECKING([for strerror_s()]) +strerror_s=yes +AC_LINK_IFELSE( + [read_test(strerror_s.cxx)], + AC_DEFINE( + [PQXX_HAVE_STRERROR_S], + 1, + [Define if strerror_s() is available.]), + strerror_s=no) +AC_MSG_RESULT($strerror_s) + + +AC_MSG_CHECKING([for std::chrono::year_month_day etc]) +year_month_day=yes +AC_LINK_IFELSE( + [read_test(year_month_day.cxx)], + AC_DEFINE( + [PQXX_HAVE_YEAR_MONTH_DAY], + 1, + [Define if std::chrono has year_month_day etc.]), + year_month_day=no) +AC_MSG_RESULT($year_month_day) + + +# Check for [[likely]] and [[unlikely]] attributes. +AC_MSG_CHECKING([attributes "likely" and "unlikely".]) +likely=yes +AC_COMPILE_IFELSE( + [read_test(likely.cxx)], + AC_DEFINE([PQXX_HAVE_LIKELY], 1, [Define if likely & unlikely work.]), + likely=no) +AC_MSG_RESULT($likely) + + +# It's mid-2019, and gcc's charconv supports integers but not yet floats. +# So for now, we test for int and float conversion... separately. +# +# It's worse for older clang versions, which compile the integer conversions +# but then fail at link time because of a missing symbol "__muloti4" with the +# "long long" version. I couldn't resolve that symbol by adding -lm either. +# So don't just compile these tests; link them as well. +AC_MSG_CHECKING([for C++17 charconv integer conversion]) +have_charconv_int=yes +AC_LINK_IFELSE( + [read_test(charconv_int.cxx)], + AC_DEFINE( + [PQXX_HAVE_CHARCONV_INT], + 1, + [Define if supports integer conversion.]), + have_charconv_int=no) +AC_MSG_RESULT($have_charconv_int) + +AC_MSG_CHECKING([for C++17 charconv floating-point conversion]) +have_charconv_float=yes +AC_LINK_IFELSE( + [read_test(charconv_float.cxx)], + AC_DEFINE( + [PQXX_HAVE_CHARCONV_FLOAT], + 1, + [Define if supports floating-point conversion.]), + have_charconv_float=no) +AC_MSG_RESULT($have_charconv_float) + +# As per #262, clang with libcxxrt does not support thread_local on non-POD +# objects. Luckily we can live without those, it's just less efficient. +AC_MSG_CHECKING([for full thread_local support]) +have_thread_local=yes +AC_LINK_IFELSE( + [read_test(thread_local.cxx)], + AC_DEFINE( + [PQXX_HAVE_THREAD_LOCAL], + 1, + [Define if thread_local is fully supported.]), + have_thread_local=no) +AC_MSG_RESULT($have_thread_local) + +AC_MSG_CHECKING([for std::this_thread::sleep_for]) +have_sleep_for=yes +AC_LINK_IFELSE( + [read_test(sleep_for.cxx)], + AC_DEFINE( + [PQXX_HAVE_SLEEP_FOR], + 1, + [Define if std::this_thread::sleep_for works.]), + have_sleep_for=no) +AC_MSG_RESULT($have_sleep_for) + + +AC_MSG_CHECKING([for std::cmp_greater, std::cmp_less_equal, etc]) +have_cmp=yes +AC_COMPILE_IFELSE( + [read_test(cmp.cxx)], + AC_DEFINE( + [PQXX_HAVE_CMP], + 1, + [Define if compiler has C++20 std::cmp_greater etc.]), + have_cmp=no) +AC_MSG_RESULT($have_cmp) + + +# Doing my own check for poll(). There's one built into autoconf-archive, but +# it produces warnings in C++ (about unnecessarily using "struct", and using 0 +# as a null pointer constant). In maintainer mode, those warnings turn into +# errors. +AC_MSG_CHECKING([for poll()]) +ax_cv_have_poll=yes +AC_LINK_IFELSE( + [read_test(poll.cxx)], + AC_DEFINE( + [PQXX_HAVE_POLL], + 1, + [Define if poll() is available.]), + ax_cv_have_poll=no) +AC_MSG_RESULT($ax_cv_have_poll) + +if test "$ax_cv_have_poll" != "yes" +then +# No poll(); we'll fall back to select(). + +# Some systems keep select() in a separate library which is not linked by +# default. See if we need one of those. +socklibok=no +AC_SEARCH_LIBS(select, socket nsl ws2_32 wsock32 winsock, [socklibok=yes]) + +# Microsoft proprietary libraries do not work with code that is generated with +# autoconf's SEARCH_LIBS macro, so we need to check manually and just use the +# first socket library available. +# We only do this if select() is not available by other means, to avoid picking +# up an unnecessary Windows compatibility library on a non-Windows system. +for l in ws2_32 wsock32 winsock +do + if test "${socklibok}" != "yes" + then + AC_CHECK_LIB($l,main,LIBS="$LIBS -l$l";[socklibok=yes]) + fi +done + +if test "${socklibok}" != "yes" +then + AC_MSG_ERROR([ +Could not figure out how to link a simple sockets-based program. Please read +the config.log file for more clues as to why this failed. +]) +fi + +fi # No poll() + + +# Find PostgreSQL includes and libraries +AC_PATH_PROG([PKG_CONFIG], [pkg-config]) +AC_PATH_PROGS(PG_CONFIG, pg_config) + +AC_ARG_WITH( + [postgres-include], + [AS_HELP_STRING( + [--with-postgres-include=DIR], + [Use PostgreSQL includes from DIR. Defaults to querying pg_config or pkg-config, whichever is available.])], + AS_IF( + [test "x$with_postgres_include" = "xyes"], + [with_postgres_include=""])) + +if test -n "$with_postgres_include" +then + POSTGRES_INCLUDE="-I$with_postgres_include" +else + if test -x "$PKG_CONFIG" || test -x "$PG_CONFIG" + then + # We should prefer pkg-config over pg_config, but there seems to be a + # problem in pkg-config 1.6.3. Until that's been resolved (#291), go + # with pg_config if we can. + if test -x "$PG_CONFIG" + then + # From pg_config we can either get the C compiler options used to + # compile postgres, which isn't quite what we want; or we can get + # the headers directory, without the full option. That's something + # we can work with. The compiler must support the "-I" option for + # that, but both scripts assume that anyway. + POSTGRES_INCLUDE="-I$($PG_CONFIG --includedir)" + else + # From pkg-config we can get the compiler options to extend the + # include path. We use that. + POSTGRES_INCLUDE=$($PKG_CONFIG libpq --cflags-only-I) + fi + AC_MSG_NOTICE([finding PostgreSQL headers using $POSTGRES_INCLUDE]) + else + POSTGRES_INCLUDE="" + + # We have nothing to tell us where the libpq headers are. That's fine + # if the compiler can find it, but if not, fail here. + AC_CHECK_HEADER( + [libpq-fe.h], + [], + [AC_MSG_ERROR([ +Can't find the main PostgreSQL client header, libpq-fe.h. Make sure that it +is installed, and either use the --with-postgres-include option or install +pkg-config. +])]) + fi +fi +AC_SUBST(POSTGRES_INCLUDE) + +# Add the compiler option so we can compile configure tests which rely on the +# libpq headers. +CPPFLAGS="$CPPFLAGS $POSTGRES_INCLUDE" + + +AC_ARG_WITH( + [postgres-lib], + [AS_HELP_STRING( + [--with-postgres-lib=DIR], + [Use PostgreSQL libraries from DIR. Defaults to querying pg_config.])], + AS_IF( + [test "x$with_postgres_lib" = "xyes"], + [with_postgres_lib=""])) + +# If no --with-postgres-lib was given, and we have pkg-config, use that. +AS_IF( + [test -z "$with_postgres_lib" -a -x "$PKG_CONFIG"], + [with_postgres_lib=$($PKG_CONFIG libpq --libs-only-L | sed 's/^-L//')]) + +# pg_config is deprecated, but for some users it may still provide the only +# right answer. For instance, `pkg-config` may not know where `libpq` is +# installed. +AS_IF( + [test -z "$with_postgres_lib" -a -x "$PG_CONFIG"], + [with_postgres_lib=$($PG_CONFIG --libdir)]) + +AS_IF( + [test -n "$with_postgres_lib"], + [AC_MSG_NOTICE([using PostgreSQL libraries at $with_postgres_lib])], + [AC_MSG_NOTICE([using PostgreSQL libraries in default location])]) + +AC_SUBST(with_postgres_lib) + + +AC_CHECK_HEADER( + [libpq-fe.h], + [], + [AC_MSG_ERROR([ +Can't find the main PostgreSQL client header, libpq-fe.h. Are you sure the +libpq headers are installed correctly, and that we've got the right path? +])]) + + +AC_MSG_CHECKING([for ability to compile source files using libpq]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include]], + [[PQexec(nullptr,"")]] + )], + [], + [AC_MSG_ERROR([ +Could not compile a call to a basic libpq function. There must be something +seriously wrong with the headers that "pg_config --includedir" or "pkg-config +libpq --cflags" pointed to; the contents of config.log may give you a clue +about the nature of the failure. +Source including the libpq header libpq-fe.h can be compiled, but a call to the +most basic libpq function PQexec() failed to compile successfully. This is the +litmus test for a working libpq. +])]) +AC_MSG_RESULT(yes) + + +if test "x${with_postgres_lib}" = "x"; then + with_postgres_libpath="" +else + with_postgres_libpath="-L${with_postgres_lib}" +fi +LDFLAGS="$LDFLAGS ${with_postgres_libpath}" + +AC_CHECK_LIB( + [pq], + [PQexec], + [], + [AC_MSG_ERROR([ +Did not find the PQexec() function in libpq. This is the litmus test for a +working libpq installation. + +A source file using the PQexec() function did compile without problems, and the +libpq library is available for linking, but for some reason a call to PQexec() +failed to link properly to the libpq library. This may be because the libpq +library file is damaged, or in some incorrect format, or if your libpq is much +more recent than libpqxx version $PQXX_ABI, perhaps libpq has undergone a +radical ABI change. + +The last parts of config.log may give you a clue as to what really went wrong, +but be warned that this is no easy reading. Look for the last error message +occurring in the file. +])], + ${with_postgres_libpath}) + + +# PQencryptPasswordConn was added in postgres 10. +AC_MSG_CHECKING([for PQencryptPasswordConn]) +have_pqencryptpasswordconn=yes +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include], + [ + extern PGconn *conn; + PQencryptPasswordConn( + conn, "pwd", "user", "scram-sha-256") + ] + )], + AC_DEFINE( + [PQXX_HAVE_PQENCRYPTPASSWORDCONN], + 1, + [Define if libpq has PQencryptPasswordConn (since pg 10).]), + [have_pqencryptpasswordconn=no]) +AC_MSG_RESULT($have_pqencryptpasswordconn) + + +# "Pipeline mode" was introduced in libpq 14. +AC_MSG_CHECKING([for libpq pipeline mode]) +have_pq_pipeline=yes +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include], + [ + extern PGconn *conn; + PQenterPipelineMode(conn) + ] + )], + AC_DEFINE( + [PQXX_HAVE_PQ_PIPELINE], + 1, + [Define if libpq has pipeline mode (since pg 14).]), + [have_pq_pipeline=no]) +AC_MSG_RESULT($have_pq_pipeline) + + +AC_MSG_CHECKING([for usable std::filesystem::path]) +have_path=yes +AC_COMPILE_IFELSE( + [read_test(fs.cxx)], + AC_DEFINE( + [PQXX_HAVE_PATH], + 1, + [Define if compiler has usable std::filesystem::path.]), + have_path=no) +AC_MSG_RESULT($have_path) + + +AC_MSG_CHECKING([whether we need a link option for support]) +LIBS_SAVE="$LIBS" +found_fslib=no +for l in '' '-lstdc++fs' '-lc++fs' +do + if test "$found_fslib" != "yes" + then + LIBS="$LIBS $l" + AC_LINK_IFELSE( + [read_test(need_fslib.cxx)], + [found_fslib=yes], + [LIBS="$LIBS_SAVE"]) + if test "$found_fslib" = "yes" + then + result_msg="$l" + # (And keep our current value of $LIBS.) + fi + fi +done + +if test "$found_fslib" != "yes" +then + AC_MSG_ERROR([ +There seems to be support, but I could not figure out now to make +it work. You'll have to add set your own build options for this. + ]) +fi +AC_MSG_RESULT($result_msg) + + +# Remove redundant occurrances of -lpq +LIBS=[$(echo "$LIBS" | sed -e 's/-lpq * -lpq\>/-lpq/g')] + + +AC_MSG_CHECKING([that type of libpq's Oid is as expected]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include + #include"${srcdir}/include/pqxx/internal/libpq-forward.hxx" + extern void f(pqxx::oid&); + ], + [Oid o;f(o)], + )], + [], + [AC_MSG_ERROR([ +The Oid typedef in libpq has changed. Please notify the libpqxx authors of the +change! +])]) +AC_MSG_RESULT(yes) + + +AC_PROG_MAKE_SET + +AC_CONFIG_FILES([ + Makefile config/Makefile doc/Makefile doc/Doxyfile src/Makefile + test/Makefile tools/Makefile include/Makefile include/pqxx/Makefile + libpqxx.pc]) + + +AC_CONFIG_COMMANDS([configitems], ["${srcdir}/tools/splitconfig" "${srcdir}"]) + +AC_OUTPUT(compile_flags) diff --git a/ext/libpqxx-7.7.3/doc/CMakeLists.txt b/ext/libpqxx-7.7.3/doc/CMakeLists.txt new file mode 100644 index 0000000..d48d2a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/CMakeLists.txt @@ -0,0 +1,50 @@ +find_program(HAVE_DOXYGEN doxygen) + +if(NOT HAVE_DOXYGEN) + message(FATAL_ERROR "***************************************************** +Doxygen not found. +Install it, or configure with -DBUILD_DOC=OFF +*****************************************************" + ) +endif() + +set(PQXXVERSION "${CMAKE_PROJECT_VERSION}") +set(top_srcdir "${PROJECT_SOURCE_DIR}") +set(PQXX_ABI "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") +set(PQXX_MAJOR "${PROJECT_VERSION_MAJOR}") +set(PQXX_MINOR "${PROJECT_VERSION_MINOR}") + +find_program(HAVE_DOT dot) +if(HAVE_DOT) + set(HAVE_DOT YES) +else() + set(HAVE_DOT NO) +endif() + +configure_file(Doxyfile.in Doxyfile) + +if(HAVE_DOXYGEN) + file( + GLOB DOXYGEN_SOURCES + "${PROJECT_SOURCE_DIR}/include/pqxx/*.hxx" + "${PROJECT_SOURCE_DIR}/include/pqxx/doc/*.md" + "${PROJECT_SOURCE_DIR}/*.cxx" + ) + set(DOXYGEN_STAMP_FILE "${CMAKE_CURRENT_BINARY_DIR}/doxygen.stamp") + add_custom_command(OUTPUT ${DOXYGEN_STAMP_FILE} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html + COMMAND doxygen Doxyfile + COMMAND ${CMAKE_COMMAND} -E touch ${DOXYGEN_STAMP_FILE} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ${DOXYGEN_SOURCES} + COMMENT "Generate API documentation" + VERBATIM + ) + add_custom_target(doxygen ALL + DEPENDS ${DOXYGEN_STAMP_FILE} + SOURCES ${DOXYGEN_SOURCES} + ) + install( + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html + DESTINATION ${CMAKE_INSTALL_DOCDIR}/html + ) +endif() diff --git a/ext/libpqxx-7.7.3/doc/Doxyfile.in b/ext/libpqxx-7.7.3/doc/Doxyfile.in new file mode 100644 index 0000000..f349fe8 --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/Doxyfile.in @@ -0,0 +1,1280 @@ +# Doxyfile 1.5.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libpqxx + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @PQXXVERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = html + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = ../ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = NO + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @top_srcdir@/include/pqxx \ + @top_srcdir@/include/pqxx/doc \ + @top_srcdir@/src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.cxx \ + *.hxx \ + *.h \ + *.md + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = *.o \ + *.lo \ + *.a \ + .cvsignore + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = . + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = YES + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = "../include" "@top_srcdir@/include" + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = *.h *.hxx + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = PQXX_ABI="@PQXX_ABI@" \ + PQXX_LIBEXPORT= \ + PQXX_NOVTABLE= \ + PQXX_PRIVATE= \ + PQXX_TYPENAME=typename \ + PQXX_VERSION="@PQXXVERSION@" \ + PQXX_MAJOR=@PQXX_MAJOR@ \ + PQXX_MINOR=@PQXX_MINOR@ + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = @HAVE_DOT@ + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/ext/libpqxx-7.7.3/doc/Makefile.am b/ext/libpqxx-7.7.3/doc/Makefile.am new file mode 100644 index 0000000..38caa91 --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/Makefile.am @@ -0,0 +1,51 @@ +MAINTAINERCLEANFILES = Makefile.in + +maintainer-clean-local: + $(RM) -rf html + $(RM) reference-stamp + $(MKDIR) html + +EXTRA_DIST= Doxyfile.in libpqxx.xml reference-stamp + +all-local: docs + +if BUILD_REFERENCE +DOCS = reference +else +DOCS = +endif + +if MAINTAINER_MODE +REFERENCE_STAMP_DEP = ../src/libpqxx.la +else +REFERENCE_STAMP_DEP = +endif + +docs: $(DOCS) + +reference: reference-stamp +reference-stamp: Doxyfile.in $(REFERENCE_STAMP_DEP) + if [ -x "$(DOXYGEN)" ]; then \ + $(MKDIR_P) html; \ + $(DOXYGEN) Doxyfile; \ + touch $@; \ + else \ + echo >&2; \ + echo >&2 "*****************************************************"; \ + echo >&2; \ + echo >&2 "Doxygen not found."; \ + echo >&2 "Install it, or configure with --disable-documentation"; \ + echo >&2; \ + echo >&2 "*****************************************************"; \ + exit 1; \ + fi + +../src/libpqxx.la: + cd ../src; \ + $(MAKE) libpqxx.la + + +dist-hook: reference + if [ -d $(srcdir)/html ]; then \ + cp -pR html $(distdir)/ ; \ + fi diff --git a/ext/libpqxx-7.7.3/doc/Makefile.in b/ext/libpqxx-7.7.3/doc/Makefile.in new file mode 100644 index 0000000..835845b --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/Makefile.in @@ -0,0 +1,507 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h +CONFIG_CLEAN_FILES = Doxyfile +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in \ + $(top_srcdir)/config/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = Doxyfile.in libpqxx.xml reference-stamp +@BUILD_REFERENCE_FALSE@DOCS = +@BUILD_REFERENCE_TRUE@DOCS = reference +@MAINTAINER_MODE_FALSE@REFERENCE_STAMP_DEP = +@MAINTAINER_MODE_TRUE@REFERENCE_STAMP_DEP = ../src/libpqxx.la +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am +check: check-am +all-am: Makefile all-local +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am all-local check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags-am dist-hook distclean \ + distclean-generic distclean-libtool distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic maintainer-clean-local mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +maintainer-clean-local: + $(RM) -rf html + $(RM) reference-stamp + $(MKDIR) html + +all-local: docs + +docs: $(DOCS) + +reference: reference-stamp +reference-stamp: Doxyfile.in $(REFERENCE_STAMP_DEP) + if [ -x "$(DOXYGEN)" ]; then \ + $(MKDIR_P) html; \ + $(DOXYGEN) Doxyfile; \ + touch $@; \ + else \ + echo >&2; \ + echo >&2 "*****************************************************"; \ + echo >&2; \ + echo >&2 "Doxygen not found."; \ + echo >&2 "Install it, or configure with --disable-documentation"; \ + echo >&2; \ + echo >&2 "*****************************************************"; \ + exit 1; \ + fi + +../src/libpqxx.la: + cd ../src; \ + $(MAKE) libpqxx.la + +dist-hook: reference + if [ -d $(srcdir)/html ]; then \ + cp -pR html $(distdir)/ ; \ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/doc/conf.py b/ext/libpqxx-7.7.3/doc/conf.py new file mode 100644 index 0000000..1cac1c2 --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/conf.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +""" +libpqxx documentation build configuration file, created by +sphinx-quickstart on Sun Dec 3 00:43:33 2017. + +This file is execfile()d with the current directory set to its containing dir. + +All configuration values have a default; values that are commented out serve +to show the default. +""" + +import codecs +import os +from subprocess import check_call + + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import sys +# sys.path.insert(0, os.path.abspath(os.path.curdir)) + + +read_the_docs_build = os.environ.get('READTHEDOCS') == 'True' + +if read_the_docs_build: + check_call( + [os.path.join(os.path.curdir, 'configure'), 'CXXFLAGS=-std=c++17 -O0'], + cwd=os.path.pardir) + check_call('doxygen', cwd=os.path.join(os.path.pardir, 'doc')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + ] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'libpqxx' +copyright = u'2000-2022, Jeroen T. Vermeulen' +author = u'Jeroen T. Vermeulen' + + +def read_version(): + """Return version number as specified in the VERSION file.""" + version_file = os.path.join( + os.path.dirname(__file__), os.path.pardir, 'VERSION') + with codecs.open(version_file, encoding='ascii') as stream: + return stream.read().strip() + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = read_version() + +# The short X.Y version. +version = '.'.join(release.split('.')[:2]) + +html_title = "libpqxx %s" % release +html_short_title = "libpqxx" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + ] +} + +# Looks like the setup is that our build generates the HTML itself, and then +# has readthedocs copy the full generated HTML tree to the output directory. +# +# Problem is, that doesn't seem to be working now. This needs debugging. +html_extra_path = ["html"] + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'libpqxxdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + master_doc, + 'libpqxx.tex', + u'libpqxx Documentation', + u'Jeroen T. Vermeulen', + 'manual', + ), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'libpqxx', u'libpqxx Documentation', [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'libpqxx', u'libpqxx Documentation', + author, 'libpqxx', "C++ client API for PostgreSQL.", + 'Miscellaneous'), +] diff --git a/ext/libpqxx-7.7.3/doc/index.rst b/ext/libpqxx-7.7.3/doc/index.rst new file mode 100644 index 0000000..30f2cfd --- /dev/null +++ b/ext/libpqxx-7.7.3/doc/index.rst @@ -0,0 +1,20 @@ +.. x documentation master file, created by + sphinx-quickstart on Sun Dec 3 01:30:12 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +libpqxx +======= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/ext/libpqxx-7.7.3/include/CMakeLists.txt b/ext/libpqxx-7.7.3/include/CMakeLists.txt new file mode 100644 index 0000000..263dd2e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/CMakeLists.txt @@ -0,0 +1,68 @@ +# ############################################################################## +# AUTOMATICALLY GENERATED FILE -- DO NOT EDIT. +# +# This file is generated automatically by libpqxx's template2mak.py script, and +# will be rewritten from time to time. +# +# If you modify this file, chances are your modifications will be lost. +# +# The template2mak.py script should be available in the tools directory of the +# libpqxx source archive. +# +# Generated from template './include/CMakeLists.txt.template'. +# ############################################################################## +install( + DIRECTORY pqxx "${PROJECT_BINARY_DIR}/include/pqxx" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + # For each X.hxx, install both X.hxx itself and plain X. + PATTERN *.hxx + # TODO: Is there any way to do this with CMake's globbing? + PATTERN array + PATTERN binarystring + PATTERN blob + PATTERN composite + PATTERN connection + PATTERN cursor + PATTERN dbtransaction + PATTERN errorhandler + PATTERN except + PATTERN field + PATTERN isolation + PATTERN largeobject + PATTERN nontransaction + PATTERN notification + PATTERN params + PATTERN pipeline + PATTERN prepared_statement + PATTERN range + PATTERN result + PATTERN robusttransaction + PATTERN row + PATTERN separated_list + PATTERN strconv + PATTERN stream_from + PATTERN stream_to + PATTERN subtransaction + PATTERN time + PATTERN transaction + PATTERN transaction_base + PATTERN transaction_focus + PATTERN transactor + PATTERN types + PATTERN util + PATTERN version + PATTERN zview + PATTERN internal/*.hxx + PATTERN internal/gates/*.hxx + PATTERN config-public-compiler.h + PATTERN pqxx + PATTERN doc EXCLUDE +) + +install( + DIRECTORY pqxx/doc/ + DESTINATION ${CMAKE_INSTALL_DOCDIR} + FILES_MATCHING + PATTERN *.md +) diff --git a/ext/libpqxx-7.7.3/include/CMakeLists.txt.template b/ext/libpqxx-7.7.3/include/CMakeLists.txt.template new file mode 100644 index 0000000..5ebc666 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/CMakeLists.txt.template @@ -0,0 +1,23 @@ +install( + DIRECTORY pqxx "${PROJECT_BINARY_DIR}/include/pqxx" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + # For each X.hxx, install both X.hxx itself and plain X. + PATTERN *.hxx + # TODO: Is there any way to do this with CMake's globbing? +###MAKTEMPLATE:FOREACH include/pqxx/*.hxx + PATTERN ###BASENAME### +###MAKTEMPLATE:ENDFOREACH + PATTERN internal/*.hxx + PATTERN internal/gates/*.hxx + PATTERN config-public-compiler.h + PATTERN pqxx + PATTERN doc EXCLUDE +) + +install( + DIRECTORY pqxx/doc/ + DESTINATION ${CMAKE_INSTALL_DOCDIR} + FILES_MATCHING + PATTERN *.md +) diff --git a/ext/libpqxx-7.7.3/include/Makefile.am b/ext/libpqxx-7.7.3/include/Makefile.am new file mode 100644 index 0000000..83d2b19 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/Makefile.am @@ -0,0 +1,79 @@ +SUBDIRS = pqxx + +nobase_include_HEADERS= pqxx/pqxx \ + pqxx/array pqxx/array.hxx \ + pqxx/binarystring pqxx/binarystring.hxx \ + pqxx/blob pqxx/blob.hxx \ + pqxx/composite pqxx/composite.hxx \ + pqxx/connection pqxx/connection.hxx \ + pqxx/cursor pqxx/cursor.hxx \ + pqxx/dbtransaction pqxx/dbtransaction.hxx \ + pqxx/errorhandler pqxx/errorhandler.hxx \ + pqxx/except pqxx/except.hxx \ + pqxx/field pqxx/field.hxx \ + pqxx/isolation pqxx/isolation.hxx \ + pqxx/largeobject pqxx/largeobject.hxx \ + pqxx/nontransaction pqxx/nontransaction.hxx \ + pqxx/notification pqxx/notification.hxx \ + pqxx/params pqxx/params.hxx \ + pqxx/pipeline pqxx/pipeline.hxx \ + pqxx/prepared_statement pqxx/prepared_statement.hxx \ + pqxx/range pqxx/range.hxx \ + pqxx/result pqxx/result.hxx \ + pqxx/robusttransaction pqxx/robusttransaction.hxx \ + pqxx/separated_list pqxx/separated_list.hxx \ + pqxx/strconv pqxx/strconv.hxx \ + pqxx/stream_from pqxx/stream_from.hxx \ + pqxx/stream_to pqxx/stream_to.hxx \ + pqxx/subtransaction pqxx/subtransaction.hxx \ + pqxx/time pqxx/time.hxx \ + pqxx/transaction pqxx/transaction.hxx \ + pqxx/transaction_base pqxx/transaction_base.hxx \ + pqxx/transaction_focus pqxx/transaction_focus.hxx \ + pqxx/transactor pqxx/transactor.hxx \ + pqxx/row pqxx/row.hxx \ + pqxx/util pqxx/util.hxx \ + pqxx/types pqxx/types.hxx \ + pqxx/zview pqxx/zview.hxx \ + pqxx/version pqxx/version.hxx \ + pqxx/internal/array-composite.hxx \ + pqxx/internal/callgate.hxx \ + pqxx/internal/concat.hxx \ + pqxx/internal/conversions.hxx \ + pqxx/internal/encoding_group.hxx \ + pqxx/internal/encodings.hxx \ + pqxx/internal/header-pre.hxx \ + pqxx/internal/header-post.hxx \ + pqxx/internal/ignore-deprecated-post.hxx \ + pqxx/internal/ignore-deprecated-pre.hxx \ + pqxx/internal/libpq-forward.hxx \ + pqxx/internal/result_iter.hxx \ + pqxx/internal/result_iterator.hxx \ + pqxx/internal/sql_cursor.hxx \ + pqxx/internal/statement_parameters.hxx \ + pqxx/internal/stream_iterator.hxx \ + pqxx/internal/wait.hxx \ + pqxx/internal/gates/connection-errorhandler.hxx \ + pqxx/internal/gates/connection-largeobject.hxx \ + pqxx/internal/gates/connection-notification_receiver.hxx \ + pqxx/internal/gates/connection-pipeline.hxx \ + pqxx/internal/gates/connection-sql_cursor.hxx \ + pqxx/internal/gates/connection-transaction.hxx \ + pqxx/internal/gates/errorhandler-connection.hxx \ + pqxx/internal/gates/icursorstream-icursor_iterator.hxx \ + pqxx/internal/gates/icursor_iterator-icursorstream.hxx \ + pqxx/internal/gates/result-connection.hxx \ + pqxx/internal/gates/result-creation.hxx \ + pqxx/internal/gates/result-pipeline.hxx \ + pqxx/internal/gates/result-sql_cursor.hxx \ + pqxx/internal/gates/transaction-sql_cursor.hxx \ + pqxx/internal/gates/transaction-transaction_focus.hxx + + +nobase_nodist_include_HEADERS = \ + pqxx/config-public-compiler.h + +EXTRA_DIST = \ + pqxx/doc/*.md \ + pqxx/doc/mainpage.md.template \ + pqxx/version.hxx.template diff --git a/ext/libpqxx-7.7.3/include/Makefile.in b/ext/libpqxx-7.7.3/include/Makefile.in new file mode 100644 index 0000000..6b9eac9 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/Makefile.in @@ -0,0 +1,802 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/pqxx/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)" +HEADERS = $(nobase_include_HEADERS) $(nobase_nodist_include_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/config/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +SUBDIRS = pqxx +nobase_include_HEADERS = pqxx/pqxx \ + pqxx/array pqxx/array.hxx \ + pqxx/binarystring pqxx/binarystring.hxx \ + pqxx/blob pqxx/blob.hxx \ + pqxx/composite pqxx/composite.hxx \ + pqxx/connection pqxx/connection.hxx \ + pqxx/cursor pqxx/cursor.hxx \ + pqxx/dbtransaction pqxx/dbtransaction.hxx \ + pqxx/errorhandler pqxx/errorhandler.hxx \ + pqxx/except pqxx/except.hxx \ + pqxx/field pqxx/field.hxx \ + pqxx/isolation pqxx/isolation.hxx \ + pqxx/largeobject pqxx/largeobject.hxx \ + pqxx/nontransaction pqxx/nontransaction.hxx \ + pqxx/notification pqxx/notification.hxx \ + pqxx/params pqxx/params.hxx \ + pqxx/pipeline pqxx/pipeline.hxx \ + pqxx/prepared_statement pqxx/prepared_statement.hxx \ + pqxx/range pqxx/range.hxx \ + pqxx/result pqxx/result.hxx \ + pqxx/robusttransaction pqxx/robusttransaction.hxx \ + pqxx/separated_list pqxx/separated_list.hxx \ + pqxx/strconv pqxx/strconv.hxx \ + pqxx/stream_from pqxx/stream_from.hxx \ + pqxx/stream_to pqxx/stream_to.hxx \ + pqxx/subtransaction pqxx/subtransaction.hxx \ + pqxx/time pqxx/time.hxx \ + pqxx/transaction pqxx/transaction.hxx \ + pqxx/transaction_base pqxx/transaction_base.hxx \ + pqxx/transaction_focus pqxx/transaction_focus.hxx \ + pqxx/transactor pqxx/transactor.hxx \ + pqxx/row pqxx/row.hxx \ + pqxx/util pqxx/util.hxx \ + pqxx/types pqxx/types.hxx \ + pqxx/zview pqxx/zview.hxx \ + pqxx/version pqxx/version.hxx \ + pqxx/internal/array-composite.hxx \ + pqxx/internal/callgate.hxx \ + pqxx/internal/concat.hxx \ + pqxx/internal/conversions.hxx \ + pqxx/internal/encoding_group.hxx \ + pqxx/internal/encodings.hxx \ + pqxx/internal/header-pre.hxx \ + pqxx/internal/header-post.hxx \ + pqxx/internal/ignore-deprecated-post.hxx \ + pqxx/internal/ignore-deprecated-pre.hxx \ + pqxx/internal/libpq-forward.hxx \ + pqxx/internal/result_iter.hxx \ + pqxx/internal/result_iterator.hxx \ + pqxx/internal/sql_cursor.hxx \ + pqxx/internal/statement_parameters.hxx \ + pqxx/internal/stream_iterator.hxx \ + pqxx/internal/wait.hxx \ + pqxx/internal/gates/connection-errorhandler.hxx \ + pqxx/internal/gates/connection-largeobject.hxx \ + pqxx/internal/gates/connection-notification_receiver.hxx \ + pqxx/internal/gates/connection-pipeline.hxx \ + pqxx/internal/gates/connection-sql_cursor.hxx \ + pqxx/internal/gates/connection-transaction.hxx \ + pqxx/internal/gates/errorhandler-connection.hxx \ + pqxx/internal/gates/icursorstream-icursor_iterator.hxx \ + pqxx/internal/gates/icursor_iterator-icursorstream.hxx \ + pqxx/internal/gates/result-connection.hxx \ + pqxx/internal/gates/result-creation.hxx \ + pqxx/internal/gates/result-pipeline.hxx \ + pqxx/internal/gates/result-sql_cursor.hxx \ + pqxx/internal/gates/transaction-sql_cursor.hxx \ + pqxx/internal/gates/transaction-transaction_focus.hxx + +nobase_nodist_include_HEADERS = \ + pqxx/config-public-compiler.h + +EXTRA_DIST = \ + pqxx/doc/*.md \ + pqxx/doc/mainpage.md.template \ + pqxx/version.hxx.template + +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-nobase_includeHEADERS: $(nobase_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +install-nobase_nodist_includeHEADERS: $(nobase_nodist_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_nodist_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-nobase_includeHEADERS \ + install-nobase_nodist_includeHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-nobase_includeHEADERS \ + uninstall-nobase_nodist_includeHEADERS + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-nobase_includeHEADERS \ + install-nobase_nodist_includeHEADERS install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-nobase_includeHEADERS \ + uninstall-nobase_nodist_includeHEADERS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/include/pqxx/Makefile.am b/ext/libpqxx-7.7.3/include/pqxx/Makefile.am new file mode 100644 index 0000000..c7f6881 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/Makefile.am @@ -0,0 +1,13 @@ +MAINTAINERCLEANFILES=Makefile.in stamp-h.in + +noinst_HEADERS = \ + config-internal-autotools.h + +nodist_noinst_HEADERS = \ + config.h \ + config-internal-compiler.h + +DISTCLEANFILES = \ + config-internal-autotools.h \ + config-internal-compiler.h \ + config-public-compiler.h diff --git a/ext/libpqxx-7.7.3/include/pqxx/Makefile.in b/ext/libpqxx-7.7.3/include/pqxx/Makefile.in new file mode 100644 index 0000000..4b02fb7 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/Makefile.in @@ -0,0 +1,556 @@ +# Makefile.in generated by automake 1.16.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/pqxx +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(nodist_noinst_HEADERS) $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/config/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +POSTGRES_INCLUDE = @POSTGRES_INCLUDE@ +PQXXVERSION = @PQXXVERSION@ +PQXX_ABI = @PQXX_ABI@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_postgres_lib = @with_postgres_lib@ +MAINTAINERCLEANFILES = Makefile.in stamp-h.in +noinst_HEADERS = \ + config-internal-autotools.h + +nodist_noinst_HEADERS = \ + config.h \ + config-internal-compiler.h + +DISTCLEANFILES = \ + config-internal-autotools.h \ + config-internal-compiler.h \ + config-public-compiler.h + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/pqxx/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/pqxx/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status include/pqxx/config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) config.h +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ext/libpqxx-7.7.3/include/pqxx/array b/ext/libpqxx-7.7.3/include/pqxx/array new file mode 100644 index 0000000..689f5b2 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/array @@ -0,0 +1,6 @@ +/** Handling of SQL arrays. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/array.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/array.hxx b/ext/libpqxx-7.7.3/include/pqxx/array.hxx new file mode 100644 index 0000000..8440a24 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/array.hxx @@ -0,0 +1,103 @@ +/* Handling of SQL arrays. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ARRAY +#define PQXX_H_ARRAY + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx +{ +/// Low-level array parser. +/** Use this to read an array field retrieved from the database. + * + * This parser will only work reliably if your client encoding is UTF-8, ASCII, + * or a single-byte encoding which is a superset of ASCII (such as Latin-1). + * + * Also, the parser only supports array element types which use either a comma + * or a semicolon ("," or ";") as the separator between array elements. All + * built-in types use comma, except for one which uses semicolon, but some + * custom types may not work. + * + * The input is a C-style string containing the textual representation of an + * array, as returned by the database. The parser reads this representation + * on the fly. The string must remain in memory until parsing is done. + * + * Parse the array by making calls to @ref get_next until it returns a + * @ref juncture of "done". The @ref juncture tells you what the parser found + * in that step: did the array "nest" to a deeper level, or "un-nest" back up? + */ +class PQXX_LIBEXPORT array_parser +{ +public: + /// What's the latest thing found in the array? + enum class juncture + { + /// Starting a new row. + row_start, + /// Ending the current row. + row_end, + /// Found a NULL value. + null_value, + /// Found a string value. + string_value, + /// Parsing has completed. + done, + }; + + // TODO: constexpr noexcept. Breaks ABI. + /// Constructor. You don't need this; use @ref field::as_array instead. + /** The parser only remains valid while the data underlying the @ref result + * remains valid. Once all `result` objects referring to that data have been + * destroyed, the parser will no longer refer to valid memory. + */ + explicit array_parser( + std::string_view input, + internal::encoding_group = internal::encoding_group::MONOBYTE); + + /// Parse the next step in the array. + /** Returns what it found. If the juncture is @ref juncture::string_value, + * the string will contain the value. Otherwise, it will be empty. + * + * Call this until the @ref array_parser::juncture it returns is + * @ref juncture::done. + */ + std::pair get_next(); + +private: + std::string_view m_input; + internal::glyph_scanner_func *const m_scan; + + /// Current parsing position in the input. + std::string::size_type m_pos = 0u; + + std::string::size_type scan_single_quoted_string() const; + std::string parse_single_quoted_string(std::string::size_type end) const; + std::string::size_type scan_double_quoted_string() const; + std::string parse_double_quoted_string(std::string::size_type end) const; + std::string::size_type scan_unquoted_string() const; + std::string parse_unquoted_string(std::string::size_type end) const; + + std::string::size_type scan_glyph(std::string::size_type pos) const; + std::string::size_type + scan_glyph(std::string::size_type pos, std::string::size_type end) const; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/binarystring b/ext/libpqxx-7.7.3/include/pqxx/binarystring new file mode 100644 index 0000000..77551d9 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/binarystring @@ -0,0 +1,6 @@ +/** BYTEA (binary string) conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx b/ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx new file mode 100644 index 0000000..47c82a0 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/binarystring.hxx @@ -0,0 +1,236 @@ +/* Deprecated representation for raw, binary data. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BINARYSTRING +#define PQXX_H_BINARYSTRING + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class binarystring; +template<> struct string_traits; + + +/// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type. +/** @ingroup escaping-functions + * @deprecated Use @c std::basic_string and + * @c std::basic_string_view for binary data. In C++20 or better, + * any @c contiguous_range of @c std::byte will do. + * + * This class represents a binary string as stored in a field of type @c bytea. + * + * Internally a binarystring is zero-terminated, but it may also contain null + * bytes, they're just like any other byte value. So don't assume that it's + * safe to treat the contents as a C-style string. + * + * The binarystring retains its value even if the result it was obtained from + * is destroyed, but it cannot be copied or assigned. + * + * \relatesalso transaction_base::quote_raw + * + * To include a @c binarystring value in an SQL query, escape and quote it + * using the transaction's @c quote_raw function. + * + * @warning This class is implemented as a reference-counting smart pointer. + * Copying, swapping, and destroying binarystring objects that refer to the + * same underlying data block is not thread-safe. If you wish to pass + * binarystrings around between threads, make sure that each of these + * operations is protected against concurrency with similar operations on the + * same object, or other objects pointing to the same data block. + */ +class PQXX_LIBEXPORT binarystring +{ +public: + using char_type = unsigned char; + using value_type = std::char_traits::char_type; + using size_type = std::size_t; + using difference_type = long; + using const_reference = value_type const &; + using const_pointer = value_type const *; + using const_iterator = const_pointer; + using const_reverse_iterator = std::reverse_iterator; + + [[deprecated("Use std::byte for binary data.")]] binarystring( + binarystring const &) = default; + + /// Read and unescape bytea field. + /** The field will be zero-terminated, even if the original bytea field + * isn't. + * @param F the field to read; must be a bytea field + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + field const &); + + /// Copy binary data from std::string_view on binary data. + /** This is inefficient in that it copies the data to a buffer allocated on + * the heap. + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + std::string_view); + + /// Copy binary data of given length straight out of memory. + [[deprecated("Use std::byte for binary data.")]] binarystring( + void const *, std::size_t); + + /// Efficiently wrap a buffer of binary data in a @c binarystring. + [[deprecated("Use std::byte for binary data.")]] binarystring( + std::shared_ptr ptr, size_type size) : + m_buf{std::move(ptr)}, m_size{size} + {} + + /// Size of converted string in bytes. + [[nodiscard]] size_type size() const noexcept { return m_size; } + /// Size of converted string in bytes. + [[nodiscard]] size_type length() const noexcept { return size(); } + [[nodiscard]] bool empty() const noexcept { return size() == 0; } + + [[nodiscard]] const_iterator begin() const noexcept { return data(); } + [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); } + [[nodiscard]] const_iterator end() const noexcept { return data() + m_size; } + [[nodiscard]] const_iterator cend() const noexcept { return end(); } + + [[nodiscard]] const_reference front() const noexcept { return *begin(); } + [[nodiscard]] const_reference back() const noexcept + { + return *(data() + m_size - 1); + } + + [[nodiscard]] const_reverse_iterator rbegin() const + { + return const_reverse_iterator{end()}; + } + [[nodiscard]] const_reverse_iterator crbegin() const { return rbegin(); } + [[nodiscard]] const_reverse_iterator rend() const + { + return const_reverse_iterator{begin()}; + } + [[nodiscard]] const_reverse_iterator crend() const { return rend(); } + + /// Unescaped field contents. + [[nodiscard]] value_type const *data() const noexcept { return m_buf.get(); } + + [[nodiscard]] const_reference operator[](size_type i) const noexcept + { + return data()[i]; + } + + [[nodiscard]] PQXX_PURE bool operator==(binarystring const &) const noexcept; + [[nodiscard]] bool operator!=(binarystring const &rhs) const noexcept + { + return not operator==(rhs); + } + + binarystring &operator=(binarystring const &); + + /// Index contained string, checking for valid index. + const_reference at(size_type) const; + + /// Swap contents with other binarystring. + void swap(binarystring &); + + /// Raw character buffer (no terminating zero is added). + /** @warning No terminating zero is added! If the binary data did not end in + * a null character, you will not find one here. + */ + [[nodiscard]] char const *get() const noexcept + { + return reinterpret_cast(m_buf.get()); + } + + /// Read contents as a std::string_view. + [[nodiscard]] std::string_view view() const noexcept + { + return std::string_view(get(), size()); + } + + /// Read as regular C++ string (may include null characters). + /** This creates and returns a new string object. Don't call this + * repeatedly; retrieve your string once and keep it in a local variable. + * Also, do not expect to be able to compare the string's address to that of + * an earlier invocation. + */ + [[nodiscard]] std::string str() const; + + /// Access data as a pointer to @c std::byte. + [[nodiscard]] std::byte const *bytes() const + { + return reinterpret_cast(get()); + } + + /// Read data as a @c std::basic_string_view. + [[nodiscard]] std::basic_string_view bytes_view() const + { + return std::basic_string_view{bytes(), size()}; + } + +private: + std::shared_ptr m_buf; + size_type m_size{0}; +}; + + +template<> struct nullness : no_null +{}; + + +/// String conversion traits for @c binarystring. +/** Defines the conversions between a @c binarystring and its PostgreSQL + * textual format, for communication with the database. + * + * These conversions rely on the "hex" format which was introduced in + * PostgreSQL 9.0. Both your libpq and the server must be recent enough to + * speak this format. + */ +template<> struct string_traits +{ + static std::size_t size_buffer(binarystring const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, binarystring const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, binarystring const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + std::string_view text{value.view()}; + internal::esc_bin(binary_cast(text), begin); + return begin + budget; + } + + static binarystring from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::shared_ptr buf{ + new unsigned char[size], [](unsigned char const *x) { delete[] x; }}; + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.get())); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return binarystring{std::move(buf), size}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/blob b/ext/libpqxx-7.7.3/include/pqxx/blob new file mode 100644 index 0000000..3fd0afa --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/blob @@ -0,0 +1,6 @@ +/** Binary Large Objects interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/blob.hxx b/ext/libpqxx-7.7.3/include/pqxx/blob.hxx new file mode 100644 index 0000000..6d77be7 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/blob.hxx @@ -0,0 +1,351 @@ +/* Binary Large Objects interface. + * + * Read or write large objects, stored in their own storage on the server. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BLOB +#define PQXX_H_BLOB + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#if defined(PQXX_HAVE_PATH) +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/** Binary large object. + * + * This is how you store data that may be too large for the `BYTEA` type. + * Access operations are similar to those for a file: you can read, write, + * query or set the current reading/writing position, and so on. + * + * These large objects live in their own storage on the server, indexed by an + * integer object identifier ("oid"). + * + * Two `blob` objects may refer to the same actual large object in the + * database at the same time. Each will have its own reading/writing position, + * but writes to the one will of course affect what the other sees. + */ +class PQXX_LIBEXPORT blob +{ +public: + /// Create a new, empty large object. + /** You may optionally specify an oid for the new blob. If you do, then + * the new object will have that oid -- or creation will fail if there + * already is an object with that oid. + */ + [[nodiscard]] static oid create(dbtransaction &, oid = 0); + + /// Delete a large object, or fail if it does not exist. + static void remove(dbtransaction &, oid); + + /// Open blob for reading. Any attempt to write to it will fail. + [[nodiscard]] static blob open_r(dbtransaction &, oid); + // Open blob for writing. Any attempt to read from it will fail. + [[nodiscard]] static blob open_w(dbtransaction &, oid); + // Open blob for reading and/or writing. + [[nodiscard]] static blob open_rw(dbtransaction &, oid); + + /// You can default-construct a blob, but it won't do anything useful. + /** Most operations on a default-constructed blob will throw @ref + * usage_error. + */ + blob() = default; + + /// You can move a blob, but not copy it. The original becomes unusable. + blob(blob &&); + /// You can move a blob, but not copy it. The original becomes unusable. + blob &operator=(blob &&); + + blob(blob const &) = delete; + blob &operator=(blob const &) = delete; + ~blob(); + + /// Maximum number of bytes that can be read or written at a time. + /** The underlying protocol only supports reads and writes up to 2 GB + * exclusive. + * + * If you need to read or write more data to or from a binary large object, + * you'll have to break it up into chunks. + */ + static constexpr std::size_t chunk_limit = 0x7fffffff; + + /// Read up to `size` bytes of the object into `buf`. + /** Uses a buffer that you provide, resizing it as needed. If it suits you, + * this lets you allocate the buffer once and then re-use it multiple times. + * + * Resizes `buf` as needed. + * + * @warning The underlying protocol only supports reads up to 2GB at a time. + * If you need to read more, try making repeated calls to @ref append_to_buf. + */ + std::size_t read(std::basic_string &buf, std::size_t size); + +#if defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::span read(std::span buf) + { + return buf.subspan(0, raw_read(std::data(buf), std::size(buf))); + } +#endif // PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template std::span read(DATA &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#else // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + /// Read up to `std::size(buf)` bytes from the object. + /** @deprecated As libpqxx moves to C++20 as its baseline language version, + * this will take and return `std::span`. + * + * Retrieves bytes from the blob, at the current position, until `buf` is + * full (i.e. its current size is reached), or there are no more bytes to + * read, whichever comes first. + * + * This function will not change either the size or the capacity of `buf`, + * only its contents. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::basic_string_view read(std::vector &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#endif // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) + /// Write `data` to large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#else + /// Write `data` large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#endif + + /// Resize large object to `size` bytes. + /** If the blob is more than `size` bytes long, this removes the end so as + * to make the blob the desired length. + * + * If the blob is less than `size` bytes long, it adds enough zero bytes to + * make it the desired length. + */ + void resize(std::int64_t size); + + /// Return the current reading/writing position in the large object. + [[nodiscard]] std::int64_t tell() const; + + /// Set the current reading/writing position to an absolute offset. + /** Returns the new file offset. */ + std::int64_t seek_abs(std::int64_t offset = 0); + /// Move the current reading/writing position forwards by an offset. + /** To move backwards, pass a negative offset. + * + * Returns the new file offset. + */ + std::int64_t seek_rel(std::int64_t offset = 0); + /// Set the current position to an offset relative to the end of the blob. + /** You'll probably want an offset of zero or less. + * + * Returns the new file offset. + */ + std::int64_t seek_end(std::int64_t offset = 0); + + /// Create a binary large object containing given `data`. + /** You may optionally specify an oid for the new object. If you do, and an + * object with that oid already exists, creation will fail. + */ + static oid from_buf( + dbtransaction &tx, std::basic_string_view data, oid id = 0); + + /// Append `data` to binary large object. + /** The underlying protocol only supports appending blocks up to 2 GB. + */ + static void append_from_buf( + dbtransaction &tx, std::basic_string_view data, oid id); + + /// Read client-side file and store it server-side as a binary large object. + [[nodiscard]] static oid from_file(dbtransaction &, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + [[nodiscard]] static oid + from_file(dbtransaction &tx, std::filesystem::path const &path) + { + return from_file(tx, path.c_str()); + } +#endif + + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + */ + static oid from_file(dbtransaction &, char const path[], oid); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + * + * This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static oid + from_file(dbtransaction &tx, std::filesystem::path const &path, oid id) + { + return from_file(tx, path.c_str(), id); + } +#endif + + /// Convenience function: Read up to `max_size` bytes from blob with `id`. + /** You could easily do this yourself using the @ref open_r and @ref read + * functions, but it can save you a bit of code to do it this way. + */ + static void to_buf( + dbtransaction &, oid, std::basic_string &, + std::size_t max_size); + + /// Read part of the binary large object with `id`, and append it to `buf`. + /** Use this to break up a large read from one binary large object into one + * massive buffer. Just keep calling this function until it returns zero. + * + * The `offset` is how far into the large object your desired chunk is, and + * `append_max` says how much to try and read in one go. + */ + static std::size_t append_to_buf( + dbtransaction &tx, oid id, std::int64_t offset, + std::basic_string &buf, std::size_t append_max); + + /// Write a binary large object's contents to a client-side file. + static void to_file(dbtransaction &, oid, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Write a binary large object's contents to a client-side file. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static void + to_file(dbtransaction &tx, oid id, std::filesystem::path const &path) + { + to_file(tx, id, path.c_str()); + } +#endif + + /// Close this blob. + /** This does not delete the blob from the database; it only terminates your + * local object for accessing the blob. + * + * Resets the blob to a useless state similar to one that was + * default-constructed. + * + * The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + */ + void close(); + +private: + PQXX_PRIVATE blob(connection &conn, int fd) noexcept : + m_conn{&conn}, m_fd{fd} + {} + static PQXX_PRIVATE blob open_internal(dbtransaction &, oid, int); + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::connection *) noexcept; + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::dbtransaction const &) noexcept; + static PQXX_PRIVATE std::string errmsg(connection const *); + static PQXX_PRIVATE std::string errmsg(dbtransaction const &tx) + { + return errmsg(&tx.conn()); + } + PQXX_PRIVATE std::string errmsg() const { return errmsg(m_conn); } + PQXX_PRIVATE std::int64_t seek(std::int64_t offset, int whence); + std::size_t raw_read(std::byte buf[], std::size_t size); + void raw_write(std::byte const buf[], std::size_t size); + + connection *m_conn = nullptr; + int m_fd = -1; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/composite b/ext/libpqxx-7.7.3/include/pqxx/composite new file mode 100644 index 0000000..2bfa7ad --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/composite @@ -0,0 +1,6 @@ +/** Handling of SQL "composite types." + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/composite.hxx b/ext/libpqxx-7.7.3/include/pqxx/composite.hxx new file mode 100644 index 0000000..439b133 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/composite.hxx @@ -0,0 +1,149 @@ +#ifndef PQXX_H_COMPOSITE +#define PQXX_H_COMPOSITE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Parse a string representation of a value of a composite type. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own @ref string_traits + * for a composite type. + * + * This function interprets `text` as the string representation of a value of + * some composite type, and sets each of `fields` to the respective values of + * its fields. The field types must be copy-assignable. + * + * The number of fields must match the number of fields in the composite type, + * and there must not be any other text in the input. The function is meant to + * handle any value string that the backend can produce, but not necessarily + * every valid alternative spelling. + * + * Fields in composite types can be null. When this happens, the C++ type of + * the corresponding field reference must be of a type that can handle nulls. + * If you are working with a type that does not have an inherent null value, + * such as e.g. `int`, consider using `std::optional`. + */ +template +inline void parse_composite( + pqxx::internal::encoding_group enc, std::string_view text, T &...fields) +{ + static_assert(sizeof...(fields) > 0); + + auto const scan{pqxx::internal::get_glyph_scanner(enc)}; + auto const data{std::data(text)}; + auto const size{std::size(text)}; + if (size == 0) + throw conversion_error{"Cannot parse composite value from empty string."}; + + std::size_t here{0}, next{scan(data, size, here)}; + if (next != 1 or data[here] != '(') + throw conversion_error{ + internal::concat("Invalid composite value string: ", text)}; + + here = next; + + constexpr auto num_fields{sizeof...(fields)}; + std::size_t index{0}; + (pqxx::internal::parse_composite_field( + index, text, here, fields, scan, num_fields - 1), + ...); + if (here != std::size(text)) + throw conversion_error{internal::concat( + "Composite value did not end at the closing parenthesis: '", text, + "'.")}; + if (text[here - 1] != ')') + throw conversion_error{internal::concat( + "Composive value did not end in parenthesis: '", text, "'")}; +} + + +/// Parse a string representation of a value of a composite type. +/** @warning This version only works for UTF-8 and single-byte encodings. + * + * For proper encoding support, use the composite-type support in the + * `field` class. + */ +template +inline void parse_composite(std::string_view text, T &...fields) +{ + parse_composite(pqxx::internal::encoding_group::MONOBYTE, text, fields...); +} +} // namespace pqxx + + +namespace pqxx::internal +{ +constexpr char empty_composite_str[]{"()"}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Estimate the buffer size needed to represent a value of a composite type. +/** Returns a conservative estimate. + */ +template +[[nodiscard]] inline std::size_t +composite_size_buffer(T const &...fields) noexcept +{ + constexpr auto num{sizeof...(fields)}; + + // Size for a multi-field composite includes room for... + // + opening parenthesis + // + field budgets + // + separating comma per field + // - comma after final field + // + closing parenthesis + // + terminating zero + + if constexpr (num == 0) + return std::size(pqxx::internal::empty_composite_str); + else + return 1 + (pqxx::internal::size_composite_field_buffer(fields) + ...) + + num + 1; +} + + +/// Render a series of values as a single composite SQL value. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own `string_traits` + * for a composite type. + */ +template +inline char *composite_into_buf(char *begin, char *end, T const &...fields) +{ + if (std::size_t(end - begin) < composite_size_buffer(fields...)) + throw conversion_error{ + "Buffer space may not be enough to represent composite value."}; + + constexpr auto num_fields{sizeof...(fields)}; + if constexpr (num_fields == 0) + { + constexpr char empty[]{"()"}; + std::memcpy(begin, empty, std::size(empty)); + return begin + std::size(empty); + } + + char *pos{begin}; + *pos++ = '('; + + (pqxx::internal::write_composite_field(pos, end, fields), ...); + + // If we've got multiple fields, "backspace" that last comma. + if constexpr (num_fields > 1) + --pos; + *pos++ = ')'; + *pos++ = '\0'; + return pos; +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/config.h.in b/ext/libpqxx-7.7.3/include/pqxx/config.h.in new file mode 100644 index 0000000..7435799 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/config.h.in @@ -0,0 +1,121 @@ +/* include/pqxx/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `pq' library (-lpq). */ +#undef HAVE_LIBPQ + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define if supports floating-point conversion. */ +#undef PQXX_HAVE_CHARCONV_FLOAT + +/* Define if supports integer conversion. */ +#undef PQXX_HAVE_CHARCONV_INT + +/* Define if compiler has C++20 std::cmp_greater etc. */ +#undef PQXX_HAVE_CMP + +/* Define if compiler supports Concepts and header. */ +#undef PQXX_HAVE_CONCEPTS + +/* Define if compiler supports __cxa_demangle */ +#undef PQXX_HAVE_CXA_DEMANGLE + +/* Define if g++ supports pure attribute */ +#undef PQXX_HAVE_GCC_PURE + +/* Define if g++ supports visibility attribute. */ +#undef PQXX_HAVE_GCC_VISIBILITY + +/* Define if likely & unlikely work. */ +#undef PQXX_HAVE_LIKELY + +/* Define if operator[] can take multiple arguments. */ +#undef PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT + +/* Define if compiler has usable std::filesystem::path. */ +#undef PQXX_HAVE_PATH + +/* Define if poll() is available. */ +#undef PQXX_HAVE_POLL + +/* Define if libpq has PQencryptPasswordConn (since pg 10). */ +#undef PQXX_HAVE_PQENCRYPTPASSWORDCONN + +/* Define if libpq has pipeline mode (since pg 14). */ +#undef PQXX_HAVE_PQ_PIPELINE + +/* Define if std::this_thread::sleep_for works. */ +#undef PQXX_HAVE_SLEEP_FOR + +/* Define if compiler has std::span. */ +#undef PQXX_HAVE_SPAN + +/* Define if strerror_r() is available. */ +#undef PQXX_HAVE_STRERROR_R + +/* Define if strerror_s() is available. */ +#undef PQXX_HAVE_STRERROR_S + +/* Define if thread_local is fully supported. */ +#undef PQXX_HAVE_THREAD_LOCAL + +/* Define if std::chrono has year_month_day etc. */ +#undef PQXX_HAVE_YEAR_MONTH_DAY + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/ext/libpqxx-7.7.3/include/pqxx/connection b/ext/libpqxx-7.7.3/include/pqxx/connection new file mode 100644 index 0000000..82ff43a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/connection @@ -0,0 +1,8 @@ +/** pqxx::connection class. + * + * pqxx::connection encapsulates a connection to a database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/connection.hxx b/ext/libpqxx-7.7.3/include/pqxx/connection.hxx new file mode 100644 index 0000000..92454bb --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/connection.hxx @@ -0,0 +1,1261 @@ +/* Definition of the connection class. + * + * pqxx::connection encapsulates a connection to a database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CONNECTION +#define PQXX_H_CONNECTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Double-check in order to suppress an overzealous Visual C++ warning (#418). +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/params.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +/** + * @addtogroup connections + * + * Use of the libpqxx library starts here. + * + * Everything that can be done with a database through libpqxx must go through + * a @ref pqxx::connection object. It connects to a database when you create + * it, and it terminates that communication during destruction. + * + * Many things come together in this class. Handling of error and warning + * messages, for example, is defined by @ref pqxx::errorhandler objects in the + * context of a connection. Prepared statements are also defined here. + * + * When you connect to a database, you pass a connection string containing any + * parameters and options, such as the server address and the database name. + * + * These are identical to the ones in libpq, the C language binding upon which + * libpqxx itself is built: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * There are also environment variables you can set to provide defaults, again + * as defined by libpq: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * You can also create a database connection _asynchronously_ using an + * intermediate @ref pqxx::connecting object. + */ + +namespace pqxx::internal +{ +class sql_cursor; + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: T is a range of pairs of zero-terminated strings. +template +concept ZKey_ZValues = std::ranges::input_range and requires(T t) +{ + {std::cbegin(t)}; + { + std::get<0>(*std::cbegin(t)) + } -> ZString; + { + std::get<1>(*std::cbegin(t)) + } -> ZString; +} and std::tuple_size_v::value_type> +== 2; +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class connection_dbtransaction; +class connection_errorhandler; +class connection_largeobject; +class connection_notification_receiver; +class connection_pipeline; +class connection_sql_cursor; +class connection_stream_from; +class connection_stream_to; +class connection_transaction; +class const_connection_largeobject; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Representation of a PostgreSQL table path. +/** A "table path" consists of a table name, optionally prefixed by a schema + * name, which in turn is optionally prefixed by a database name. + * + * A minimal example of a table path would be `{mytable}`. But a table path + * may also take the forms `{myschema,mytable}` or + * `{mydb,myschema,mytable}`. + */ +using table_path = std::initializer_list; + + +/// Encrypt a password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] std::string + PQXX_LIBEXPORT + encrypt_password(char const user[], char const password[]); + +/// Encrypt password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] inline std::string +encrypt_password(zview user, zview password) +{ +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return encrypt_password(user.c_str(), password.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Error verbosity levels. +enum class error_verbosity : int +{ + // These values must match those in libpq's PGVerbosity enum. + terse = 0, + normal = 1, + verbose = 2 +}; + + +/// Connection to a database. +/** This is the first class to look at when you wish to work with a database + * through libpqxx. The connection opens during construction, and closes upon + * destruction. + * + * When creating a connection, you can pass a connection URI or a postgres + * connection string, to specify the database server's address, a login + * username, and so on. If you don't, the connection will try to obtain them + * from certain environment variables. If those are not set either, the + * default is to try and connect to the local system's port 5432. + * + * Find more about connection strings here: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * The variables are documented here: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * To query or manipulate the database once connected, use one of the + * transaction classes (see pqxx/transaction_base.hxx) and perhaps also the + * transactor framework (see pqxx/transactor.hxx). + * + * When a connection breaks, you will typically get a @ref broken_connection + * exception. This can happen at almost any point. + * + * @warning On Unix-like systems, including GNU and BSD systems, your program + * may receive the SIGPIPE signal when the connection to the backend breaks. By + * default this signal will abort your program. Use "signal(SIGPIPE, SIG_IGN)" + * if you want your program to continue running after a connection fails. + */ +class PQXX_LIBEXPORT connection +{ +public: + connection() : connection{""} {} + + /// Connect to a database, using `options` string. + explicit connection(char const options[]) + { + check_version(); + init(options); + } + + /// Connect to a database, using `options` string. + explicit connection(zview options) : connection{options.c_str()} + { + // (Delegates to other constructor which calls check_version for us.) + } + + /// Move constructor. + /** Moving a connection is not allowed if it has an open transaction, or has + * error handlers or notification receivers registered on it. In those + * situations, other objects may hold references to the old object which + * would become invalid and might produce hard-to-diagnose bugs. + */ + connection(connection &&rhs); + +#if defined(PQXX_HAVE_CONCEPTS) + /// Connect to a database, passing options as a range of key/value pairs. + /** @warning Experimental. Requires C++20 "concepts" support. Define + * `PQXX_HAVE_CONCEPTS` to enable it. + * + * There's no need to escape the parameter values. + * + * See the PostgreSQL libpq documentation for the full list of possible + * options: + * + * https://postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS + * + * The options can be anything that can be iterated as a series of pairs of + * zero-terminated strings: `std::pair`, or + * `std::tuple`, or + * `std::map`, and so on. + */ + template + inline connection(MAPPING const ¶ms); +#endif // PQXX_HAVE_CONCEPTS + + ~connection() + { + try + { + close(); + } + catch (std::exception const &) + {} + } + + /// Move assignment. + /** Neither connection can have an open transaction, registered error + * handlers, or registered notification receivers. + */ + connection &operator=(connection &&rhs); + + connection(connection const &) = delete; + connection &operator=(connection const &) = delete; + + /// Is this connection open at the moment? + /** @warning This function is **not** needed in most code. Resist the + * temptation to check it after opening a connection. The `connection` + * constructor will throw a @ref broken_connection exception if can't connect + * to the database. + */ + [[nodiscard]] bool PQXX_PURE is_open() const noexcept; + + /// Invoke notice processor function. The message should end in newline. + void process_notice(char const[]) noexcept; + /// Invoke notice processor function. Newline at end is recommended. + /** The zview variant, with a message ending in newline, is the most + * efficient way to call process_notice. + */ + void process_notice(zview) noexcept; + + /// Enable tracing to a given output stream, or nullptr to disable. + void trace(std::FILE *) noexcept; + + /** + * @name Connection properties + * + * These are probably not of great interest, since most are derived from + * information supplied by the client program itself, but they are included + * for completeness. + * + * The connection needs to be currently active for these to work. + */ + //@{ + /// Name of database we're connected to, if any. + [[nodiscard]] char const *dbname() const; + + /// Database user ID we're connected under, if any. + [[nodiscard]] char const *username() const; + + /// Address of server, or nullptr if none specified (i.e. default or local) + [[nodiscard]] char const *hostname() const; + + /// Server port number we're connected to. + [[nodiscard]] char const *port() const; + + /// Process ID for backend process, or 0 if inactive. + [[nodiscard]] int PQXX_PURE backendpid() const &noexcept; + + /// Socket currently used for connection, or -1 for none. Use with care! + /** Query the current socket number. This is intended for event loops based + * on functions such as select() or poll(), where you're waiting for any of + * multiple file descriptors to become ready for communication. + * + * Please try to stay away from this function. It is really only meant for + * event loops that need to wait on more than one file descriptor. If all + * you need is to block until a notification arrives, for instance, use + * await_notification(). If you want to issue queries and retrieve results + * in nonblocking fashion, check out the pipeline class. + */ + [[nodiscard]] int PQXX_PURE sock() const &noexcept; + + /// What version of the PostgreSQL protocol is this connection using? + /** The answer can be 0 (when there is no connection); 3 for protocol 3.0; or + * possibly higher values as newer protocol versions come into use. + */ + [[nodiscard]] int PQXX_PURE protocol_version() const noexcept; + + /// What version of the PostgreSQL server are we connected to? + /** The result is a bit complicated: each of the major, medium, and minor + * release numbers is written as a two-digit decimal number, and the three + * are then concatenated. Thus server version 9.4.2 will be returned as the + * decimal number 90402. If there is no connection to the server, this + * returns zero. + * + * @warning When writing version numbers in your code, don't add zero at the + * beginning! Numbers beginning with zero are interpreted as octal (base-8) + * in C++. Thus, 070402 is not the same as 70402, and 080000 is not a number + * at all because there is no digit "8" in octal notation. Use strictly + * decimal notation when it comes to these version numbers. + */ + [[nodiscard]] int PQXX_PURE server_version() const noexcept; + //@} + + /// @name Text encoding + /** + * Each connection is governed by a "client encoding," which dictates how + * strings and other text is represented in bytes. The database server will + * send text data to you in this encoding, and you should use it for the + * queries and data which you send to the server. + * + * Search the PostgreSQL documentation for "character set encodings" to find + * out more about the available encodings, how to extend them, and how to use + * them. Not all server-side encodings are compatible with all client-side + * encodings or vice versa. + * + * Encoding names are case-insensitive, so e.g. "UTF8" is equivalent to + * "utf8". + * + * You can change the client encoding, but this may not work when the + * connection is in a special state, such as when streaming a table. It's + * not clear what happens if you change the encoding during a transaction, + * and then abort the transaction. + */ + //@{ + /// Get client-side character encoding, by name. + [[nodiscard]] std::string get_client_encoding() const; + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(zview encoding) & + { + set_client_encoding(encoding.c_str()); + } + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(char const encoding[]) &; + + /// Get the connection's encoding, as a PostgreSQL-defined code. + [[nodiscard]] int PQXX_PRIVATE encoding_id() const; + + //@} + + /// Set session variable, using SQL's `SET` command. + /** @deprecated To set a session variable, use @ref set_session_var. To set + * a transaction-local variable, execute an SQL `SET` command. + * + * @warning When setting a string value, you must escape and quote it first. + * Use the @ref quote() function to do that. + * + * @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + * + * @param var Variable to set. + * @param value New value for Var. This can be any SQL expression. If it's + * a string, be sure that it's properly escaped and quoted. + */ + [[deprecated("To set session variables, use set_session_var.")]] void + set_variable(std::string_view var, std::string_view value) &; + + /// Set one of the session variables to a new value. + /** This executes SQL, so do not do it while a pipeline or stream is active + * on the connection. + * + * The value you set here will last for the rest of the connection's + * duration, or until you set a new value. + * + * If you set the value while in a @ref dbtransaction (i.e. any transaction + * that is not a @ref nontransaction), then rolling back the transaction will + * undo the change. + * + * All applies to setting _session_ variables. You can also set the same + * variables as _local_ variables, in which case they will always revert to + * their previous value when the transaction ends (or when you overwrite them + * of course). To set a local variable, simply execute an SQL statement + * along the lines of "`SET LOCAL var = 'value'`" inside your transaction. + * + * @param var The variable to set. + * @param value The new value for the variable. + * @throw @ref variable_set_to_null if the value is null; this is not + * allowed. + */ + template + void set_session_var(std::string_view var, TYPE const &value) & + { + if constexpr (nullness::has_null) + { + if (nullness::is_null(value)) + throw variable_set_to_null{ + internal::concat("Attempted to set variable ", var, " to null.")}; + } + exec(internal::concat("SET ", quote_name(var), "=", quote(value))); + } + + /// Read session variable, using SQL's `SHOW` command. + /** @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + */ + [[deprecated("Use get_var instead.")]] std::string + get_variable(std::string_view); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * @return a blank `std::optional` if the variable's value is null, or its + * string value otherwise. + */ + std::string get_var(std::string_view var); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * If there is any possibility that the variable is null, ensure that `TYPE` + * can represent null values. + */ + template TYPE get_var_as(std::string_view var) + { + return from_string(get_var(var)); + } + + /** + * @name Notifications and Receivers + */ + //@{ + /// Check for pending notifications and take appropriate action. + /** This does not block. To wait for incoming notifications, either call + * await_notification() (it calls this function); or wait for incoming data + * on the connection's socket (i.e. wait to read), and then call this + * function repeatedly until it returns zero. After that, there are no more + * pending notifications so you may want to wait again. + * + * If any notifications are pending when you call this function, it + * processes them by finding any receivers that match the notification string + * and invoking those. If no receivers match, there is nothing to invoke but + * we do consider the notification processed. + * + * If any of the client-registered receivers throws an exception, the + * function will report it using the connection's errorhandlers. It does not + * re-throw the exceptions. + * + * @return Number of notifications processed. + */ + int get_notifs(); + + /// Wait for a notification to come in. + /** There are other events that will also terminate the wait, such as the + * backend failing. It will also wake up periodically. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs() repeatedly until it returns zero. + * + * @return Number of notifications processed. + */ + int await_notification(); + + /// Wait for a notification to come in, or for given timeout to pass. + /** There are other events that will also terminate the wait, such as the + * backend failing, or timeout expiring. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs repeatedly until it returns zero. + * + * @return Number of notifications processed + */ + int await_notification(std::time_t seconds, long microseconds); + //@} + + /** + * @name Password encryption + * + * Use this when setting a new password for the user if password encryption + * is enabled. Inputs are the SQL name for the user for whom you with to + * encrypt a password; the plaintext password; and the hash algorithm. + * + * The algorithm must be one of "md5", "scram-sha-256" (introduced in + * PostgreSQL 10), or `nullptr`. If the pointer is null, this will query + * the `password_encryption setting` from the server, and use the default + * algorithm as defined there. + * + * @return encrypted version of the password, suitable for encrypted + * PostgreSQL authentication. + * + * Thus you can change a user's password with: + * ```cxx + * void setpw(transaction_base &t, string const &user, string const &pw) + * { + * t.exec0("ALTER USER " + user + " " + * "PASSWORD '" + t.conn().encrypt_password(user,pw) + "'"); + * } + * ``` + * + * When building this against a libpq older than version 10, this will use + * an older function which only supports md5. In that case, requesting a + * different algorithm than md5 will result in a @ref feature_not_supported + * exception. + */ + //@{ + /// Encrypt a password for a given user. + [[nodiscard]] std::string + encrypt_password(zview user, zview password, zview algorithm) + { + return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str()); + } + /// Encrypt a password for a given user. + [[nodiscard]] std::string encrypt_password( + char const user[], char const password[], char const *algorithm = nullptr); + //@} + + /** + * @name Prepared statements + * + * PostgreSQL supports prepared SQL statements, i.e. statements that you can + * register under a name you choose, optimized once by the backend, and + * executed any number of times under the given name. + * + * Prepared statement definitions are not sensitive to transaction + * boundaries. A statement defined inside a transaction will remain defined + * outside that transaction, even if the transaction itself is subsequently + * aborted. Once a statement has been prepared, it will only go away if you + * close the connection or explicitly "unprepare" the statement. + * + * Use the `pqxx::transaction_base::exec_prepared` functions to execute a + * prepared statement. See @ref prepared for a full discussion. + * + * @warning Using prepared statements can save time, but if your statement + * takes parameters, it may also make your application significantly slower! + * The reason is that the server works out a plan for executing the query + * when you prepare it. At that time, of course it does not know the values + * for the parameters that you will pass. If you execute a query without + * preparing it, then the server works out the plan on the spot, with full + * knowledge of the parameter values. + * + * A statement's definition can refer to its parameters as `$1`, `$2`, etc. + * The first parameter you pass to the call provides a value for `$1`, and + * so on. + * + * Here's an example of how to use prepared statements. + * + * ```cxx + * using namespace pqxx; + * void foo(connection &c) + * { + * c.prepare("findtable", "select * from pg_tables where name=$1"); + * work tx{c}; + * result r = tx.exec_prepared("findtable", "mytable"); + * if (std::empty(r)) throw runtime_error{"mytable not found!"}; + * } + * ``` + */ + //@{ + + /// Define a prepared statement. + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(zview name, zview definition) & + { + prepare(name.c_str(), definition.c_str()); + } + + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(char const name[], char const definition[]) &; + + /// Define a nameless prepared statement. + /** + * This can be useful if you merely want to pass large binary parameters to a + * statement without otherwise wishing to prepare it. If you use this + * feature, always keep the definition and the use close together to avoid + * the nameless statement being redefined unexpectedly by code somewhere + * else. + */ + void prepare(char const definition[]) &; + void prepare(zview definition) & { return prepare(definition.c_str()); } + + /// Drop prepared statement. + void unprepare(std::string_view name); + + //@} + + // C++20: constexpr. Breaks ABI. + /// Suffix unique number to name to make it unique within session context. + /** Used internally to generate identifiers for SQL objects (such as cursors + * and nested transactions) based on a given human-readable base name. + */ + [[nodiscard]] std::string adorn_name(std::string_view); + + /** + * @defgroup escaping-functions String-escaping functions + */ + //@{ + + /// Escape string for use as SQL string literal on this connection. + /** @warning This accepts a length, and it does not require a terminating + * zero byte. But if there is a zero byte, escaping stops there even if + * it's not at the end of the string! + */ + [[deprecated("Use std::string_view or pqxx:zview.")]] std::string + esc(char const text[], std::size_t maxlen) const + { + return esc(std::string_view{text, maxlen}); + } + + /// Escape string for use as SQL string literal on this connection. + [[nodiscard]] std::string esc(char const text[]) const + { + return esc(std::string_view{text}); + } + +#if defined(PQXX_HAVE_SPAN) + /// Escape string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `text`, there must be at least 2 bytes of space in + * `buffer`; plus there must be one byte of space for a trailing zero. + * Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + [[nodiscard]] std::string_view + esc(std::string_view text, std::span buffer) + { + auto const size{std::size(text)}, space{std::size(buffer)}; + auto const needed{2 * size + 1}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + auto const data{buffer.data()}; + return {data, esc_to_buf(text, data)}; + } +#endif + + /// Escape string for use as SQL string literal on this connection. + /** @warning This is meant for text strings only. It cannot contain bytes + * whose value is zero ("nul bytes"). + */ + [[nodiscard]] std::string esc(std::string_view text) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** This is identical to `esc_raw(data)`. */ + template [[nodiscard]] std::string esc(DATA const &data) const + { + return esc_raw(data); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `data`, there must be at least two bytes of space in + * `buffer`; plus there must be two bytes of space for a header and one for + * a trailing zero. Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + template + [[nodiscard]] zview esc(DATA const &data, std::span buffer) const + { + auto const size{std::size(data)}, space{std::size(buffer)}; + auto const needed{internal::size_esc_bin(std::size(data))}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape binary string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + + std::basic_string_view view{std::data(data), std::size(data)}; + auto const out{std::data(buffer)}; + // Actually, in the modern format, we know beforehand exactly how many + // bytes we're going to fill. Just leave out the trailing zero. + internal::esc_bin(view, out); + return zview{out, needed - 1}; + } +#endif + + /// Escape binary string for use as SQL string literal on this connection. + [[deprecated("Use std::byte for binary data.")]] std::string + esc_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string esc_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string + esc_raw(std::basic_string_view, std::span buffer) const; +#endif + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + template + [[nodiscard]] std::string esc_raw(DATA const &data) const + { + return esc_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + template + [[nodiscard]] zview esc_raw(DATA const &data, std::span buffer) const + { + return this->esc(binary_cast(data), buffer); + } +#endif + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return unesc_raw(text.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const text[]) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + * + * (The data must be encoded in PostgreSQL's "hex" format. The legacy + * "bytea" escape format, used prior to PostgreSQL 9.0, is no longer + * supported.) + */ + [[nodiscard]] std::basic_string + unesc_bin(std::string_view text) const + { + std::basic_string buf; + buf.resize(pqxx::internal::size_unesc_bin(std::size(text))); + pqxx::internal::unesc_bin(text, buf.data()); + return buf; + } + + /// Escape and quote a string of binary data. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape and quote a string of binary data. + std::string quote_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape and quote a string of binary data. + /** You can also just use @ref quote with binary data. */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return quote_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table name. + /** When passing just a table name, this is just another name for + * @ref quote_name. + */ + [[nodiscard]] std::string quote_table(std::string_view name) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table path. + /** A table path consists of a table name, optionally prefixed by a schema + * name; and if both are given, they are in turn optionally prefixed by a + * database name. + * + * Each portion of the path (database name, schema name, table name) will be + * quoted separately, and they will be joined together by dots. So for + * example, `myschema.mytable` will become `"myschema"."mytable"`. + */ + [[nodiscard]] std::string quote_table(table_path) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Quote and comma-separate a series of column names. + /** Use this to save a bit of work in cases where you repeatedly need to pass + * the same list of column names, e.g. with @ref stream_to and @ref + * stream_from. Some functions that need to quote the columns list + * internally, will have a "raw" alternative which let you do the quoting + * yourself. It's a bit of extra work, but it can in rare cases let you + * eliminate some duplicate work in quoting them repeatedly. + */ + template + inline std::string quote_columns(STRINGS const &columns) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Represent object as SQL string, including quoting & escaping. + /** + * Recognises nulls and represents them as SQL nulls. They get no quotes. + */ + template + [[nodiscard]] inline std::string quote(T const &t) const; + + [[deprecated("Use std::byte for binary data.")]] std::string + quote(binarystring const &) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote binary data for use as a BYTEA value in SQL statement. + [[nodiscard]] std::string + quote(std::basic_string_view bytes) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape string for literal LIKE match. + /** Use this when part of an SQL "LIKE" pattern should match only as a + * literal string, not as a pattern, even if it contains "%" or "_" + * characters that would normally act as wildcards. + * + * The string does not get string-escaped or quoted. You do that later. + * + * For instance, let's say you have a string `name` entered by the user, + * and you're searching a `file` column for items that match `name` + * followed by a dot and three letters. Even if `name` contains wildcard + * characters "%" or "_", you only want those to match literally, so "_" + * only matches "_" and "%" only matches a single "%". + * + * You do that by "like-escaping" `name`, appending the wildcard pattern + * `".___"`, and finally, escaping and quoting the result for inclusion in + * your query: + * + * ```cxx + * tx.exec( + * "SELECT file FROM item WHERE file LIKE " + + * tx.quote(tx.esc_like(name) + ".___")); + * ``` + * + * The SQL "LIKE" operator also lets you choose your own escape character. + * This is supported, but must be a single-byte character. + */ + [[nodiscard]] std::string + esc_like(std::string_view text, char escape_char = '\\') const; + //@} + + /// Attempt to cancel the ongoing query, if any. + /** You can use this from another thread, and/or while a query is executing + * in a pipeline, but it's up to you to ensure that you're not canceling the + * wrong query. This may involve locking. + */ + void cancel_query(); + +#if defined(_WIN32) || __has_include() + /// Set socket to blocking (true) or nonblocking (false). + /** @warning Do not use this unless you _really_ know what you're doing. + * @warning This function is available on most systems, but not necessarily + * all. + */ + void set_blocking(bool block) &; +#endif // defined(_WIN32) || __has_include() + + /// Set session verbosity. + /** Set the verbosity of error messages to "terse", "normal" (the default), + * or "verbose." + * + * If "terse", returned messages include severity, primary text, and + * position only; this will normally fit on a single line. "normal" produces + * messages that include the above plus any detail, hint, or context fields + * (these might span multiple lines). "verbose" includes all available + * fields. + */ + void set_verbosity(error_verbosity verbosity) &noexcept; + + /// Return pointers to the active errorhandlers. + /** The entries are ordered from oldest to newest handler. + * + * You may use this to find errorhandlers that your application wants to + * delete when destroying the connection. Be aware, however, that libpqxx + * may also add errorhandlers of its own, and those will be included in the + * list. If this is a problem for you, derive your errorhandlers from a + * custom base class derived from pqxx::errorhandler. Then use dynamic_cast + * to find which of the error handlers are yours. + * + * The pointers point to the real errorhandlers. The container it returns + * however is a copy of the one internal to the connection, not a reference. + */ + [[nodiscard]] std::vector get_errorhandlers() const; + + /// Return a connection string encapsulating this connection's options. + /** The connection must be currently open for this to work. + * + * Returns a reconstruction of this connection's connection string. It may + * not exactly match the connection string you passed in when creating this + * connection. + */ + [[nodiscard]] std::string connection_string() const; + + /// Explicitly close the connection. + /** The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + * + * Closing a connection is idempotent. Closing a connection that's already + * closed does nothing. + */ + void close(); + + /// Seize control of a raw libpq connection. + /** @warning Do not do this. Please. It's for very rare, very specific + * use-cases. The mechanism may change (or break) in unexpected ways in + * future versions. + * + * @param raw_conn a raw libpq `PQconn` pointer. + */ + static connection seize_raw_connection(internal::pq::PGconn *raw_conn) + { + return connection{raw_conn}; + } + + /// Release the raw connection without closing it. + /** @warning Do not do this. It's for very rare, very specific use-cases. + * The mechanism may change (or break) in unexpected ways in future versions. + * + * The `connection` object becomes unusable after this. + */ + internal::pq::PGconn *release_raw_connection() && + { + return std::exchange(m_conn, nullptr); + } + +private: + friend class connecting; + enum connect_mode + { + connect_nonblocking + }; + connection(connect_mode, zview connection_string); + + /// For use by @ref seize_raw_connection. + explicit connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} {} + + /// Poll for ongoing connection, try to progress towards completion. + /** Returns a pair of "now please wait to read data from socket" and "now + * please wait to write data to socket." Both will be false when done. + * + * Throws an exception if polling indicates that the connection has failed. + */ + std::pair poll_connect(); + + // Initialise based on connection string. + void init(char const options[]); + // Initialise based on parameter names and values. + void init(char const *params[], char const *values[]); + void complete_init(); + + result make_result( + internal::pq::PGresult *pgr, std::shared_ptr const &query, + std::string_view desc = ""sv); + + void PQXX_PRIVATE set_up_state(); + + int PQXX_PRIVATE PQXX_PURE status() const noexcept; + + /// Escape a string, into a buffer allocated by the caller. + /** The buffer must have room for at least `2*std::size(text) + 1` bytes. + * + * Returns the number of bytes written, including the trailing zero. + */ + std::size_t esc_to_buf(std::string_view text, char *buf) const; + + friend class internal::gate::const_connection_largeobject; + char const *PQXX_PURE err_msg() const noexcept; + + void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept; + + result exec_prepared(std::string_view statement, internal::c_params const &); + + /// Throw @ref usage_error if this connection is not in a movable state. + void check_movable() const; + /// Throw @ref usage_error if not in a state where it can be move-assigned. + void check_overwritable() const; + + friend class internal::gate::connection_errorhandler; + void PQXX_PRIVATE register_errorhandler(errorhandler *); + void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept; + + friend class internal::gate::connection_transaction; + result exec(std::string_view, std::string_view = ""sv); + result + PQXX_PRIVATE exec(std::shared_ptr, std::string_view = ""sv); + void PQXX_PRIVATE register_transaction(transaction_base *); + void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept; + + friend class internal::gate::connection_stream_from; + std::pair>, std::size_t> + PQXX_PRIVATE read_copy_line(); + + friend class internal::gate::connection_stream_to; + void PQXX_PRIVATE write_copy_line(std::string_view); + void PQXX_PRIVATE end_copy_write(); + + friend class internal::gate::connection_largeobject; + internal::pq::PGconn *raw_connection() const { return m_conn; } + + friend class internal::gate::connection_notification_receiver; + void add_receiver(notification_receiver *); + void remove_receiver(notification_receiver *) noexcept; + + friend class internal::gate::connection_pipeline; + void PQXX_PRIVATE start_exec(char const query[]); + bool PQXX_PRIVATE consume_input() noexcept; + bool PQXX_PRIVATE is_busy() const noexcept; + internal::pq::PGresult *get_result(); + + friend class internal::gate::connection_dbtransaction; + friend class internal::gate::connection_sql_cursor; + + result exec_params(std::string_view query, internal::c_params const &args); + + /// Connection handle. + internal::pq::PGconn *m_conn = nullptr; + + /// Active transaction on connection, if any. + /** We don't use this for anything, except to check for open transactions + * when we close the connection or start a new transaction. + * + * We also don't allow move construction or move assignment while there's a + * transaction, since moving the connection in that case would leave one or + * more pointers back from the transaction to the connection dangling. + */ + transaction_base const *m_trans = nullptr; + + std::list m_errorhandlers; + + using receiver_list = + std::multimap; + /// Notification receivers. + receiver_list m_receivers; + + /// Unique number to use as suffix for identifiers (see adorn_name()). + int m_unique_id = 0; +}; + + +/// @deprecated Old base class for connection. They are now the same class. +using connection_base = connection; + + +/// An ongoing, non-blocking stepping stone to a connection. +/** Use this when you want to create a connection to the database, but without + * blocking your whole thread. It is only available on systems that have + * the `` header, and Windows. + * + * Connecting in this way is probably not "faster" (it's more complicated and + * has some extra overhead), but in some situations you can use it to make your + * application as a whole faster. It all depends on having other useful work + * to do in the same thread, and being able to wait on a socket. If you have + * other I/O going on at the same time, your event loop can wait for both the + * libpqxx socket and your own sockets, and wake up whenever any of them is + * ready to do work. + * + * Connecting in this way is not properly "asynchronous;" it's merely + * "nonblocking." This means it's not a super-high-performance mechanism like + * you might get with e.g. `io_uring`. In particular, if we need to look up + * the database hostname in DNS, that will happen synchronously. + * + * To use this, create the `connecting` object, passing a connection string. + * Then loop: If @ref wait_to_read returns true, wait for the socket to have + * incoming data on it. If @ref wait_to_write returns true, wait for the + * socket to be ready for writing. Then call @ref process to process any + * incoming or outgoing data. Do all of this until @ref done returns true (or + * there is an exception). Finally, call @ref produce to get the completed + * connection. + * + * For example: + * + * ```cxx + * pqxx::connecting cg{}; + * + * // Loop until we're done connecting. + * while (!cg.done()) + * { + * wait_for_fd(cg.sock(), cg.wait_to_read(), cg.wait_to_write()); + * cg.process(); + * } + * + * pqxx::connection conn = std::move(cg).produce(); + * + * // At this point, conn is a working connection. You can no longer use + * // cg at all. + * ``` + */ +class PQXX_LIBEXPORT connecting +{ +public: + /// Start connecting. + connecting(zview connection_string = ""_zv); + + connecting(connecting const &) = delete; + connecting(connecting &&) = default; + connecting &operator=(connecting const &) = delete; + connecting &operator=(connecting &&) = default; + + /// Get the socket. The socket may change during the connection process. + [[nodiscard]] int sock() const &noexcept { return m_conn.sock(); } + + /// Should we currently wait to be able to _read_ from the socket? + [[nodiscard]] constexpr bool wait_to_read() const &noexcept + { + return m_reading; + } + + /// Should we currently wait to be able to _write_ to the socket? + [[nodiscard]] constexpr bool wait_to_write() const &noexcept + { + return m_writing; + } + + /// Progress towards completion (but don't block). + void process() &; + + /// Is our connection finished? + [[nodiscard]] constexpr bool done() const &noexcept + { + return not m_reading and not m_writing; + } + + /// Produce the completed connection object. + /** Use this only once, after @ref done returned `true`. Once you have + * called this, the `connecting` instance has no more use or meaning. You + * can't call any of its member functions afterwards. + * + * This member function is rvalue-qualified, meaning that you can only call + * it on an rvalue instance of the class. If what you have is not an rvalue, + * turn it into one by wrapping it in `std::move()`. + */ + [[nodiscard]] connection produce() &&; + +private: + connection m_conn; + bool m_reading{false}; + bool m_writing{true}; +}; + + +template inline std::string connection::quote(T const &t) const +{ + if constexpr (nullness::always_null) + { + return "NULL"; + } + else + { + if (is_null(t)) + return "NULL"; + auto const text{to_string(t)}; + + // Okay, there's an easy way to do this and there's a hard way. The easy + // way was "quote, esc(to_string(t)), quote". I'm going with the hard way + // because it's going to save some string manipulation that will probably + // incur some unnecessary memory allocations and deallocations. + std::string buf{'\''}; + buf.resize(2 + 2 * std::size(text) + 1); + auto const content_bytes{esc_to_buf(text, buf.data() + 1)}; + auto const closing_quote{1 + content_bytes}; + buf[closing_quote] = '\''; + auto const end{closing_quote + 1}; + buf.resize(end); + return buf; + } +} + + +template +inline std::string connection::quote_columns(STRINGS const &columns) const +{ + return separated_list( + ","sv, std::cbegin(columns), std::cend(columns), + [this](auto col) { return this->quote_name(*col); }); +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +inline connection::connection(MAPPING const ¶ms) +{ + check_version(); + + std::vector keys, values; + if constexpr (std::ranges::sized_range) + { + auto const size{std::ranges::size(params) + 1}; + keys.reserve(size); + values.reserve(size); + } + for (auto const &[key, value] : params) + { + keys.push_back(internal::as_c_string(key)); + values.push_back(internal::as_c_string(value)); + } + keys.push_back(nullptr); + values.push_back(nullptr); + init(std::data(keys), std::data(values)); +} +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/cursor b/ext/libpqxx-7.7.3/include/pqxx/cursor new file mode 100644 index 0000000..e20b3a4 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/cursor @@ -0,0 +1,8 @@ +/** Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/cursor.hxx new file mode 100644 index 0000000..b392e24 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/cursor.hxx @@ -0,0 +1,483 @@ +/* Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CURSOR +#define PQXX_H_CURSOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Common definitions for cursor types +/** In C++ terms, fetches are always done in pre-increment or pre-decrement + * fashion--i.e. the result does not include the row the cursor is on at the + * beginning of the fetch, and the cursor ends up being positioned on the last + * row in the result. + * + * There are singular positions akin to `end()` at both the beginning and the + * end of the cursor's range of movement, although these fit in so naturally + * with the semantics that one rarely notices them. The cursor begins at the + * first of these, but any fetch in the forward direction will move the cursor + * off this position and onto the first row before returning anything. + */ +class PQXX_LIBEXPORT cursor_base +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Cursor access-pattern policy + /** Allowing a cursor to move forward only can result in better performance, + * so use this access policy whenever possible. + */ + enum access_policy + { + /// Cursor can move forward only + forward_only, + /// Cursor can move back and forth + random_access + }; + + /// Cursor update policy + /** + * @warning Not all PostgreSQL versions support updatable cursors. + */ + enum update_policy + { + /// Cursor can be used to read data but not to write + read_only, + /// Cursor can be used to update data as well as read it + update + }; + + /// Cursor destruction policy + /** The normal thing to do is to make a cursor object the owner of the SQL + * cursor it represents. There may be cases, however, where a cursor needs + * to persist beyond the end of the current transaction (and thus also beyond + * the lifetime of the cursor object that created it!), where it can be + * "adopted" into a new cursor object. See the basic_cursor documentation + * for an explanation of cursor adoption. + * + * If a cursor is created with "loose" ownership policy, the object + * representing the underlying SQL cursor will not take the latter with it + * when its own lifetime ends, nor will its originating transaction. + * + * @warning Use this feature with care and moderation. Only one cursor + * object should be responsible for any one underlying SQL cursor at any + * given time. + */ + enum ownership_policy + { + /// Destroy SQL cursor when cursor object is closed at end of transaction + owned, + /// Leave SQL cursor in existence after close of object and transaction + loose + }; + + cursor_base() = delete; + cursor_base(cursor_base const &) = delete; + cursor_base &operator=(cursor_base const &) = delete; + + /** + * @name Special movement distances. + */ + //@{ + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read until end. + /** @return Maximum value for result::difference_type, so the cursor will + * attempt to read the largest possible result set. + */ + [[nodiscard]] static difference_type all() noexcept; + + /// Special value: read one row only. + /** @return Unsurprisingly, 1. + */ + [[nodiscard]] static constexpr difference_type next() noexcept { return 1; } + + /// Special value: read backwards, one row only. + /** @return Unsurprisingly, -1. + */ + [[nodiscard]] static constexpr difference_type prior() noexcept + { + return -1; + } + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read backwards from current position back to origin. + /** @return Minimum value for result::difference_type. + */ + [[nodiscard]] static difference_type backward_all() noexcept; + + //@} + + /// Name of underlying SQL cursor + /** + * @returns Name of SQL cursor, which may differ from original given name. + * @warning Don't use this to access the SQL cursor directly without going + * through the provided wrapper classes! + */ + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_name; + } + +protected: + cursor_base(connection &, std::string_view Name, bool embellish_name = true); + + std::string const m_name; +}; +} // namespace pqxx + + +#include + + +namespace pqxx +{ +/// "Stateless cursor" class: easy API for retrieving parts of result sets +/** This is a front-end for SQL cursors, but with a more C++-like API. + * + * Actually, stateless_cursor feels entirely different from SQL cursors. You + * don't keep track of positions, fetches, and moves; you just say which rows + * you want. See the retrieve() member function. + */ +template +class stateless_cursor +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Create cursor. + /** + * @param tx The transaction within which you want to create the cursor. + * @param query The SQL query whose results the cursor should traverse. + * @param cname A hint for the cursor's name. The actual SQL cursor's name + * will be based on this (though not necessarily identical). + * @param hold Create a `WITH HOLD` cursor? Such cursors stay alive after + * the transaction has ended, so you can continue to use it. + */ + stateless_cursor( + transaction_base &tx, std::string_view query, std::string_view cname, + bool hold) : + m_cur{tx, query, cname, cursor_base::random_access, up, op, hold} + {} + + /// Adopt an existing scrolling SQL cursor. + /** This lets you define a cursor yourself, and then wrap it in a + * libpqxx-managed `stateless_cursor` object. + * + * @param tx The transaction within which you want to manage the cursor. + * @param adopted_cursor Your cursor's SQL name. + */ + stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) : + m_cur{tx, adopted_cursor, op} + { + // Put cursor in known position + m_cur.move(cursor_base::backward_all()); + } + + /// Close this cursor. + /** The destructor will do this for you automatically. + * + * Closing a cursor is idempotent. Closing a cursor that's already closed + * does nothing. + */ + void close() noexcept { m_cur.close(); } + + /// Number of rows in cursor's result set + /** @note This function is not const; it may need to scroll to find the size + * of the result set. + */ + [[nodiscard]] size_type size() + { + return internal::obtain_stateless_cursor_size(m_cur); + } + + /// Retrieve rows from begin_pos (inclusive) to end_pos (exclusive) + /** Rows are numbered starting from 0 to size()-1. + * + * @param begin_pos First row to retrieve. May be one row beyond the end of + * the result set, to avoid errors for empty result sets. Otherwise, must be + * a valid row number in the result set. + * @param end_pos Row up to which to fetch. Rows are returned ordered from + * begin_pos to end_pos, i.e. in ascending order if begin_pos < end_pos but + * in descending order if begin_pos > end_pos. The end_pos may be + * arbitrarily inside or outside the result set; only existing rows are + * included in the result. + */ + result retrieve(difference_type begin_pos, difference_type end_pos) + { + return internal::stateless_cursor_retrieve( + m_cur, result::difference_type(size()), begin_pos, end_pos); + } + + /// Return this cursor's name. + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_cur.name(); + } + +private: + internal::sql_cursor m_cur; +}; + + +class icursor_iterator; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class icursor_iterator_icursorstream; +class icursorstream_icursor_iterator; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Simple read-only cursor represented as a stream of results +/** SQL cursors can be tricky, especially in C++ since the two languages seem + * to have been designed on different planets. An SQL cursor has two singular + * positions akin to `end()` on either side of the underlying result set. + * + * These cultural differences are hidden from view somewhat by libpqxx, which + * tries to make SQL cursors behave more like familiar C++ entities such as + * iterators, sequences, streams, and containers. + * + * Data is fetched from the cursor as a sequence of result objects. Each of + * these will contain the number of rows defined as the stream's stride, except + * of course the last block of data which may contain fewer rows. + * + * This class can create or adopt cursors that live outside any backend + * transaction, which your backend version may not support. + */ +class PQXX_LIBEXPORT icursorstream +{ +public: + using size_type = cursor_base::size_type; + using difference_type = cursor_base::difference_type; + + /// Set up a read-only, forward-only cursor. + /** Roughly equivalent to a C++ Standard Library istream, this cursor type + * supports only two operations: reading a block of rows while moving + * forward, and moving forward without reading any data. + * + * @param context Transaction context in which this cursor will be active. + * @param query SQL query whose results this cursor shall iterate. + * @param basename Suggested name for the SQL cursor; the library will append + * a unique code to ensure its uniqueness. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + */ + icursorstream( + transaction_base &context, std::string_view query, + std::string_view basename, difference_type sstride = 1); + + /// Adopt existing SQL cursor. Use with care. + /** Forms a cursor stream around an existing SQL cursor, as returned by e.g. + * a server-side function. The SQL cursor will be cleaned up by the stream's + * destructor as if it had been created by the stream; cleaning it up by hand + * or adopting the same cursor twice is an error. + * + * Passing the name of the cursor as a string is not allowed, both to avoid + * confusion with the other constructor and to discourage unnecessary use of + * adopted cursors. + * + * @warning It is technically possible to adopt a "WITH HOLD" cursor, i.e. a + * cursor that stays alive outside its creating transaction. However, any + * cursor stream (including the underlying SQL cursor, naturally) must be + * destroyed before its transaction context object is destroyed. Therefore + * the only way to use SQL's WITH HOLD feature is to adopt the cursor, but + * defer doing so until after entering the transaction context that will + * eventually destroy it. + * + * @param context Transaction context in which this cursor will be active. + * @param cname Result field containing the name of the SQL cursor to adopt. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + * @param op Ownership policy. Determines whether the cursor underlying this + * stream will be destroyed when the stream is closed. + */ + icursorstream( + transaction_base &context, field const &cname, difference_type sstride = 1, + cursor_base::ownership_policy op = cursor_base::owned); + + /// Return `true` if this stream may still return more data. + constexpr operator bool() const &noexcept { return not m_done; } + + /// Read new value into given result object; same as operator `>>`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C.get(r1).get(r2);") + */ + icursorstream &get(result &res) + { + res = fetchblock(); + return *this; + } + /// Read new value into given result object; same as `get(result&)`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C >> r1 >> r2;") + */ + icursorstream &operator>>(result &res) { return get(res); } + + /// Move given number of rows forward without reading data. + /** Ignores any stride that you may have set. It moves by a given number of + * rows, not a number of strides. + * + * @return Reference to this stream itself, to facilitate "chained" + * invocations. + */ + icursorstream &ignore(std::streamsize n = 1) &; + + /// Change stride, i.e. the number of rows to fetch per read operation. + /** + * @param stride Must be a positive number. + */ + void set_stride(difference_type stride) &; + [[nodiscard]] constexpr difference_type stride() const noexcept + { + return m_stride; + } + +private: + result fetchblock(); + + friend class internal::gate::icursorstream_icursor_iterator; + size_type forward(size_type n = 1); + void insert_iterator(icursor_iterator *) noexcept; + void remove_iterator(icursor_iterator *) const noexcept; + + void service_iterators(difference_type); + + internal::sql_cursor m_cur; + + difference_type m_stride; + difference_type m_realpos, m_reqpos; + + mutable icursor_iterator *m_iterators; + + bool m_done; +}; + + +/// Approximate istream_iterator for icursorstream. +/** Intended as an implementation of an input_iterator (as defined by the C++ + * Standard Library), this class supports only two basic operations: reading + * the current element, and moving forward. In addition to the minimal + * guarantees for istream_iterators, this class supports multiple successive + * reads of the same position (the current result set is cached in the + * iterator) even after copying and even after new data have been read from the + * stream. This appears to be a requirement for input_iterators. Comparisons + * are also supported in the general case. + * + * The iterator does not care about its own position, however. Moving an + * iterator forward moves the underlying stream forward and reads the data from + * the new stream position, regardless of the iterator's old position in the + * stream. + * + * The stream's stride defines the granularity for all iterator movement or + * access operations, i.e. "ici += 1" advances the stream by one stride's worth + * of rows, and "*ici++" reads one stride's worth of rows from the stream. + * + * @warning Do not read from the underlying stream or its cursor, move its read + * position, or change its stride, between the time the first icursor_iterator + * on it is created and the time its last icursor_iterator is destroyed. + * + * @warning Manipulating these iterators within the context of a single cursor + * stream is not thread-safe. Creating a new iterator, copying one, + * or destroying one affects the stream as a whole. + */ +class PQXX_LIBEXPORT icursor_iterator +{ +public: + using iterator_category = std::input_iterator_tag; + using value_type = result; + using pointer = result const *; + using reference = result const &; + using istream_type = icursorstream; + using size_type = istream_type::size_type; + using difference_type = istream_type::difference_type; + + icursor_iterator() noexcept; + explicit icursor_iterator(istream_type &) noexcept; + icursor_iterator(icursor_iterator const &) noexcept; + ~icursor_iterator() noexcept; + + result const &operator*() const + { + refresh(); + return m_here; + } + result const *operator->() const + { + refresh(); + return &m_here; + } + icursor_iterator &operator++(); + icursor_iterator operator++(int); + icursor_iterator &operator+=(difference_type); + icursor_iterator &operator=(icursor_iterator const &) noexcept; + + [[nodiscard]] bool operator==(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + [[nodiscard]] bool operator<(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator>(icursor_iterator const &rhs) const + { + return rhs < *this; + } + [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const + { + return not(*this > rhs); + } + [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const + { + return not(*this < rhs); + } + +private: + void refresh() const; + + friend class internal::gate::icursor_iterator_icursorstream; + difference_type pos() const noexcept { return m_pos; } + void fill(result const &); + + icursorstream *m_stream{nullptr}; + result m_here; + difference_type m_pos; + icursor_iterator *m_prev{nullptr}, *m_next{nullptr}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/dbtransaction b/ext/libpqxx-7.7.3/include/pqxx/dbtransaction new file mode 100644 index 0000000..fa8d264 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/dbtransaction @@ -0,0 +1,8 @@ +/** pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/dbtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx new file mode 100644 index 0000000..d85cb17 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/dbtransaction.hxx @@ -0,0 +1,70 @@ +/* Definition of the pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/dbtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_DBTRANSACTION +#define PQXX_H_DBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/transaction_base.hxx" + +namespace pqxx +{ +/// Abstract transaction base class: bracket transactions on the database. +/** + * @ingroup transactions + * + * Use a dbtransaction-derived object such as "work" (transaction<>) to enclose + * operations on a database in a single "unit of work." This ensures that the + * whole series of operations either succeeds as a whole or fails completely. + * In no case will it leave half-finished work behind in the database. + * + * Once processing on a transaction has succeeded and any changes should be + * allowed to become permanent in the database, call commit(). If something + * has gone wrong and the changes should be forgotten, call abort() instead. + * If you do neither, an implicit abort() is executed at destruction time. + * + * It is an error to abort a transaction that has already been committed, or to + * commit a transaction that has already been aborted. Aborting an already + * aborted transaction or committing an already committed one is allowed, to + * make error handling easier. Repeated aborts or commits have no effect after + * the first one. + * + * Database transactions are not suitable for guarding long-running processes. + * If your transaction code becomes too long or too complex, consider ways to + * break it up into smaller ones. Unfortunately there is no universal recipe + * for this. + * + * The actual operations for committing/aborting the backend transaction are + * implemented by a derived class. The implementing concrete class must also + * call @ref close from its destructor. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE dbtransaction : public transaction_base +{ +protected: + /// Begin transaction. + explicit dbtransaction(connection &c) : transaction_base{c} {} + /// Begin transaction. + dbtransaction(connection &c, std::string_view tname) : + transaction_base{c, tname} + {} + /// Begin transaction. + dbtransaction( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + transaction_base{c, tname, rollback_cmd} + {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md b/ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md new file mode 100644 index 0000000..920fb6f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/accessing-results.md @@ -0,0 +1,157 @@ +Accessing results and result rows {#accessing-results} +--------------------------------- + +When you execute a query using one of the transaction `exec` functions, you +normally get a `result` object back. A `result` is a container of `row`s. + +(There are exceptions. The `exec1` functions expect exactly one row of data, +so they return just a `row`, not a full `result`.) + +Result objects are an all-or-nothing affair. The `exec` function waits until +it's received all the result data, and then gives it to you in the form of the +`result`. _(There is a faster, easier way of executing simple queries, so see +"streaming rows" below as well.)_ + +For example, your code might do: + +```cxx + pqxx::result r = tx.exec("SELECT * FROM mytable"); +``` + +Now, how do you access the data inside `r`? + +Result sets act as standard C++ containers of rows. Rows act as standard +C++ containers of fields. So the easiest way to go through them is: + +```cxx + for (auto const &row: r) + { + for (auto const &field: row) std::cout << field.c_str() << '\t'; + std::cout << '\n'; + } +``` + +But results and rows also support other kinds of access. Array-style +indexing, for instance, such as `r[rownum]`: + +```cxx + std::size_t const num_rows = std::size(r); + for (std::size_t rownum=0u; rownum < num_rows; ++rownum) + { + pqxx::row const row = r[rownum]; + std::size_t const num_cols = std::size(row); + for (std::size_t colnum=0u; colnum < num_cols; ++colnum) + { + pqxx::field const field = row[colnum]; + std::cout << field.c_str() << '\t'; + } + + std::cout << '\n'; + } +``` + +Every row in the result has the same number of columns, so you don't need to +look up the number of fields again for each one: + +```cxx + std::size_t const num_rows = std::size(r); + std::size_t const num_cols = r.columns(); + for (std::size_t rownum=0u; rownum < num_rows; ++rownum) + { + pqxx::row const row = r[rownum]; + for (std::size_t colnum=0u; colnum < num_cols; ++colnum) + { + pqxx::field const field = row[colnum]; + std::cout << field.c_str() << '\t'; + } + + std::cout << '\n'; + } +``` + +You can even address a field by indexing the `row` using the field's _name:_ + +```cxx + std::cout << row["salary"] << '\n'; +``` + +But try not to do that if speed matters, because looking up the column by name +takes time. At least you'd want to look up the column index before your loop +and then use numerical indexes inside the loop. + +For C++23 or better, there's also a two-dimensional array access operator: + +```cxx + for (std::size_t rownum=0u; rownum < num_rows; ++rownum) + { + for (std::size_t colnum=0u; colnum < num_cols; ++colnum) + std::cout result[rownum, colnum].c_str() << '\t'; + std::cout << '\n'; + } +``` + +And of course you can use classic "begin/end" loops: + +```cxx + for (auto row = std::begin(r); row != std::end(r); row++) + { + for (auto field = std::begin(row); field != std::end(row); field++) + std::cout << field->c_str() << '\t'; + std::cout << '\n'; + } +``` + +Result sets are immutable, so all iterators on results and rows are actually +`const_iterator`s. There are also `const_reverse_iterator` types, which +iterate backwards from `rbegin()` to `rend()` exclusive. + +All these iterator types provide one extra bit of convenience that you won't +normally find in C++ iterators: referential transparency. You don't need to +dereference them to get to the row or field they refer to. That is, instead +of `row->end()` you can also choose to say `row.end()`. Similarly, you +may prefer `field.c_str()` over `field->c_str()`. + +This becomes really helpful with the array-indexing operator. With regular +C++ iterators you would need ugly expressions like `(*row)[0]` or +`row->operator[](0)`. With the iterator types defined by the result and +row classes you can simply say `row[0]`. + + +Streaming rows +-------------- + +There's another way to go through the rows coming out of a query. It's +usually easier and faster, but there are drawbacks. + +**One,** you start getting rows before all the data has come in from the +database. That speeds things up, but what happens if you lose your network +connection while transferring the data? Your application may already have +processed some of the data before finding out that the rest isn't coming. If +that is a problem for your application, streaming may not be the right choice. + +**Two,** streaming only works for some types of query. The `stream()` function +wraps your query in a PostgreSQL `COPY` command, and `COPY` only supports a few +commands: `SELECT`, `VALUES`, `or an `INSERT`, `UPDATE`, or `DELETE` with a +`RETURNING` clause. See the `COPY` documentation here: +https://www.postgresql.org/docs/current/sql-copy.html + +**Three,** when you convert a field to a "view" type (such as +`std::string_view` or `std::basic_string_view`), the view points to +underlying data which only stays valid until you iterate to the next row or +exit the loop. So if you want to use that data for longer than a single +iteration of the streaming loop, you'll have to store it somewhere yourself. + +Now for the good news. Streaming does make it very easy to query data and loop +over it: + +```cxx + for (auto [id, name, x, y] : + tx.stream( + "SELECT id, name, x, y FROM point")) + process(id + 1, "point-" + name, x * 10.0, y * 10.0); +``` + +The conversion to C++ types (here `int`, `std::string_view`, and two `float`s) +is built into the function. You never even see `row` objects, `field` objects, +iterators, or conversion methods. You just put in your query and you receive +your data. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md b/ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md new file mode 100644 index 0000000..20da8dc --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/binary-data.md @@ -0,0 +1,56 @@ +Binary data {#binary} +=========== + +The database has two ways of storing binary data: `BYTEA` is like a string, but +containing bytes rather than text characters. And _large objects_ are more +like a separate table containing binary objects. + +Generally you'll want to use `BYTEA` for reasonably-sized values, and large +objects for very large values. + +That's the database side. On the C++ side, in libpqxx, all binary data must be +either `std::basic_string` or `std::basic_string_view`; +or if you're building in C++20 or better, anything that's a block of +contiguous `std::byte` in memory. + +So for example, if you want to write a large object, you'd create a +`pqxx::blob` object. And you might use that to write data in the form of +`std::basic_string_view`. + +Your particular binary data may look different though. You may have it in a +`std::string`, or a `std::vector`, or a pointer to `char` +accompanied by a size (which could be signed or unsigned, and of any of a few +different widths). Sometimes that's your choice, or sometimes some other +library will dictate what form it takes. + +So long as it's _basically_ still a block of bytes though, you can use +`pqxx::binary_cast` to construct a `std::basic_string_view` from it. + +There are two forms of `binary_cast`. One takes a single argument that must +support `std::data()` and `std::size()`: + + std::string hi{"Hello binary world"}; + my_blob.write(pqxx::binary_cast(hi); + +The other takes a pointer and a size: + + char const greeting[] = "Hello binary world"; + char const *hi = greeting; + my_blob.write(pqxx::binary_cast(hi, sizeof(greeting))); + + +Caveats +------- + +There are some restrictions on `binary_cast` that you must be aware of. + +First, your data must of a type that gives us _bytes._ So: `char`, +`unsigned char`, `signed char`, `int8_t`, `uint8_t`, or of course `std::byte`. +You can't feed in a vector of `double`, or anything like that. + +Second, the data must be laid out as a contiguous block in memory. If there's +no `std::data()` implementation for your type, it's not suitable. + +Third, `binary_cast` only constructs something like a `std::string_view`. It +does not make a copy of your actual data. So, make sure that your data remains +alive and in the same place while you're using it. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md b/ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md new file mode 100644 index 0000000..bc14c8b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/datatypes.md @@ -0,0 +1,373 @@ +Supporting additional data types {#datatypes} +================================ + +Communication with the database mostly happens in a text format. When you +include an integer value in a query, you use `to_string` to convert it to that +text format. When you get a query result field "as a float," it converts from +the text format to a floating-point type. These conversions are everywhere in +libpqxx. + +The conversion sydstem supports many built-in types, but it is also extensible. +You can "teach" libpqxx (in the scope of your own application) to convert +additional types of values to and from PostgreSQL's string format. + +This is massively useful, but it's not for the faint of heart. You'll need to +specialise some templates. And, **the API for doing this can change with any +major libpqxx release.** + + +Converting types +---------------- + +In your application, a conversion is driven entirely by a C++ type you specify. +The value's SQL type has nothing to do with it, nor is there anything in the +string that would identify its type. + +So, if you've SELECTed a 64-bit integer from the database, and you try to +convert it to a C++ "short," one of two things will happen: either the number +is small enough to fit in your `short` (and it just works), or else it throws a +conversion exception. + +Or, your database table might have a text column, but a given field may contain +a string that _looks_ just like a number. You can convert that value to an +integer type just fine. Or to a floating-point type. All that matters to the +conversion is the actual value, and the type. + +In some cases the templates for these conversions can tell the type from the +arguments you pass them: + + auto x = to_string(99); + +In other cases you may need to instantiate template explicitly: + + auto y = from_string("99"); + + +Supporting a new type +--------------------- + +Let's say you have some other SQL type which you want to be able to store in, +or retrieve from, the database. What would it take to support that? + +Sometimes you do not need _complete_ support. You might need a conversion _to_ +a string but not _from_ a string, for example. The conversion is defined at +compile time, so don't be too afraid to be incomplete. If you leave out one of +these steps, it's not going to crash at run time or mess up your data. The +worst that can happen is that your code won't build. + +So what do you need for a complete conversion? + +First off, of course, you need a C++ type. It may be your own, but it +doesn't have to be. It could be a type from a third-party library, or even one +from the standard library that libpqxx does not yet support. + +You also specialise the `pqxx::type_name` variable to specify the type's name. +This is important for all code which mentions your type in human-readable text, +such as error messages. + +Then, does your type have a built-in null value? You specialise the +`pqxx::nullness` template to specify the details. + +Finally, you specialise the `pqxx::string_traits` template. This is where you +define the actual conversions. + +Let's go through these steps one by one. + + +Your type +--------- + +You'll need a type for which the conversions are not yet defined, because the +C++ type is what determines the right conversion. One type, one set of +conversions. + +The type doesn't have to be one that you create. The conversion logic was +designed such that you can build it around any type. So you can just as +easily build a conversion for a type that's defined somewhere else. There's +no need to include any special methods or other members inside it. That's also +how libpqxx can support converting built-in types like `int`. + +By the way, if the type is an enum, you don't need to do any of this. Just +invoke the preprocessor macro `PQXX_DECLARE_ENUM_CONVERSION`, from the global +namespace near the top of your translation unit, and pass the type as an +argument. + +The library also provides specialisations for `std::optional`, +`std::shared_ptr`, and `std::unique_ptr`. If you have conversions for +`T`, you'll also have conversions for those. + + +Specialise `type_name` +---------------------- + +When errors happen during conversion, libpqxx will compose error messages for +the user. Sometimes these will include the name of the type that's being +converted. + +To tell libpqxx the name of each type, there's a template variable called +`pqxx::type_name`. For any given type `T`, it should have a specialisation +that provides that `T`'s human-readable name: + + namespace pqxx + { + template<> std::string const type_name{"T"}; + } + +(Yes, this means that you need to define something inside the pqxx namespace. +Future versions of libpqxx may move this into a separate namespace.) + +Define this early on in your translation unit, before any code that might cause +libpqxx to need the name. That way, the libpqxx code which needs to know the +type's name can see your definition. + + +Specialise `nullness` +--------------------- + +A struct template `pqxx::nullness` defines whether your type has a natural +"null value" built in. If so, it also provides member functions for producing +and recognising null values. + +The simplest scenario is also the most common: most types don't have a null +value built in. In that case, derive your nullness traits from +`pqxx::no_null`: + + namespace pqxx + { + template<> struct nullness : pqxx::no_null {}; + } + +(Here again you're defining this in the pqxx namespace.) + +If your type does have a natural null value, the definition gets a little more +complex: + + namespace pqxx + { + template<> struct nullness + { + static constexpr bool has_null{true}; + static constexpr bool always_null{false}; + + static bool is_null(T const &value) + { + // Return whether "value" is null. + return ...; + } + + [[nodiscard]] static T null() + { + // Return a null value. + return ...; + } + }; + } + +You may be wondering why there's a function to produce a null value, but also a +function to check whether a value is null. Why not just compare the value to +the result of `null()`? Because two null values may not be equal. `T` may +have several different null values. Or it may override the comparison +operator, similar to SQL where NULL is not equal to NULL. + +As a third case, your type may be one that _always_ represents a null value. +This is the case for `std::nullptr_t` and `std::nullopt_t`. In that case, you +set `nullness::always_null` to `true` (as well as `has_null` of course), +and you won't need to define any actual conversions. + + +Specialise `string_traits` +------------------------- + +This part is more work. (You can skip it for types that are _always_ null, +but those will be rare.) Specialise the `pqxx::string_traits` template: + + namespace pqxx + { + template<> struct string_traits + { + static T from_string(std::string_view text); + static zview to_buf(char *begin, char *end, T const &value); + static char *into_buf(char *begin, char *end, T const &value); + static std::size_t size_buffer(T const &value) noexcept; + }; + } + +You'll also need to write those member functions, or as many of them as needed +to get your code to build. + + +### `from_string` + +We start off simple: `from_string` parses a string as a value of `T`, and +returns that value. + +The string may not be zero-terminated; it's just the `string_view` from +beginning to end (exclusive). In your tests, cover cases where the string +does not end in a zero byte. + +It's perfectly possible that the string isn't actually a `T` value. Mistakes +happen. In that case, throw a `pqxx::conversion_error`. + +(Of course it's also possible that you run into some other error, so it's fine +to throw different exceptions as well. But when it's definitely "this is not +the right format for a `T`," throw `conversion_error`.) + + +### `to_buf` + +In this function, you convert a value of `T` into a string that the postgres +server will understand. + +The caller will provide you with a buffer where you can write the string, if +you need it: from `begin` to `end` exclusive. It's a half-open interval, so +don't access `*end`. + +If the buffer is insufficient for you to do the conversion, throw a +`pqxx::conversion_overrun`. It doesn't have to be exact: you can be a little +pessimistic and demand a bit more space than you need. Just be sure to throw +the exception if there's any risk of overrunning the buffer. + +You don't _have_ to use the buffer for this function though. For example, +`pqxx::string_traits::to_buf` returns a compile-time constant string and +ignores the buffer. + +Even if you do use the buffer, your string does not _have_ to start at the +beginning of the buffer. For example, the integer conversions start by writing +the _least_ significant digit to the _end_ of the buffer, and then writes the +more significant digits before it. It was just more convenient. + +Return a `pqxx::zview`. This is basically a `std::string_view`, but with one +difference: a `zview` guarantees that there will be a valid zero byte right +after the `string_view`. The zero byte is not counted as part of its size, but +it will be there. + +Expressed in code, this rule must hold: + + void invariant(zview z) + { + assert(z[std::size(z)] == 0); + } + +Make sure you write your trailing zero _before_ the `end`. If the trailing +zero doesn't fit in the buffer, then there's just not enough room to perform +the conversion. + +Beware of locales when converting. If you use standard library features like +`sprintf`, they may obey whatever locale is currently set on the system. That +means that a simple integer like 1000000 may come out as "1000000" on your +system, but as "1,000,000" on mine, or as "1.000.000" for somebody else, and on +an Indian system it may be "1,00,000". Values coming from or going to the +database should be in non-localised formats. You can use libpqxx functions for +those conversions: `pqxx::from_string`, `pqxx::to_string`, `pqxx::to_buf`. + + +### `into_buf` + +This is a stricter version of `to_buf`. All the same requirements apply, but +in addition you must write your string into the buffer provided, starting +_exactly_ at `begin`. + +That's why this function returns just a simple pointer: the address right +behind the trailing zero. If the caller wants to use the string, they can +find it at `begin`. If they want to write a different value into the rest of +the buffer, they can start at the location you returned. + + +### `size_buffer` + +Here you estimate how much buffer space you need for converting a `T` to a +string. Be precise if you can, but pessimistic if you must. It's usually +better to waste a few unnecessary bytes than to spend a lot of time computing +the exact buffer space you need. And failing the conversion because you +under-budgeted the buffer is worst of all. + +Include the trailing zero in the buffer size. If your `to_buf` takes more +space than just what's needed to store the result, include that too. + +Make `size_buffer` a `constexpr` function if you can. It can allow the caller +to allocate the buffer on the stack, with a size known at compile time. + + +Optional: Specialise `is_unquoted_safe` +--------------------------------------- + +When converting arrays or composite values to strings, libpqxx may need to +quote values and escape any special characters. This takes time. + +Some types though, such as integral or floating-point types, can never have +any special characters such as quotes, commas, or backslashes in their string +representations. In such cases, there's no need to quote or escape such values +in arrays or composite types. + +If your type is like that, you can tell libpqxx about this by defining: + + namespace pqxx + { + template<> inline constexpr bool is_unquoted_safe{true}; + } + +The code that converts this type of field to strings in an array or a composite +type can then use a simpler, more efficient variant of the code. It's always +safe to leave this out; it's _just_ an optimisation for when you're completely +sure that it's safe. + +Do not do this if a string representation of your type may contain a comma; +semicolon; parenthesis; brace; quote; backslash; newline; or any other +character that might need escaping. + + +Optional: Specialise `param_format` +----------------------------------- + +This one you don't generally need to worry about. Read on if you're writing a +type which represents raw binary data, or if you're writing a template where +_some specialisations_ may contain raw binary data. + +When you call parameterised statements, or prepared statements with parameters, +libpqxx needs to your parameters on to libpq, the underlying C-level PostgreSQL +client library. + +There are two formats for doing that: _text_ and _binary._ In the first, we +represent all values as strings, and the server then converts them into its own +internal binary representation. That's what the string conversions are all +about, and it's what we do for almost all types of parameters. + +But we do it differently when the parameter is a contiguous series of raw bytes +and the corresponding SQL type is `BYTEA`. There is a text format for those, +but we bypass it for efficiency. The server can use the binary data in the +exact same form, without any conversion or extra processing. The binary data +is also twice as compact during transport. + +(People sometimes ask why we can't just treat all types as binary. However the +general case isn't so clear-cut. The binary formats are not documented, there +are no guarantees that they will be platform-independent or that they will +remain stable, and there's no really solid way to detect when we might get the +format wrong. But also, the conversions aren't necessarily as straightforward +and efficient as they sound. So, for the general case, libpqxx sticks with the +text formats. Raw binary data alone stands out as a clear win.) + +Long story short, the machinery for passing parameters needs to know: is this +parameter a binary string, or not? In the normal case it can assume "no," and +that's what it does. The text format is always a safe choice; we just try to +use the binary format where it's faster. + +The `param_format` function template is what makes the decision. We specialise +it for types which may be binary strings, and use the default for all other +types. + +"Types which _may_ be binary"? You might think we know whether a type is a +binary type or not. But there are some complications with generic types. + +Templates like `std::shared_ptr`, `std::optional`, and so on act like +"wrappers" for another type. A `std::optional` is binary if `T` is binary. +Otherwise, it's not. If you're building support for a template of this nature, +you'll probably want to implement `param_format` for it. + +The decision to use binary format is made based on a given object, not +necessarily based on the type in general. Look at `std::variant`. If you have +a `std::variant` type which can hold an `int` or a binary string, is that a +binary parameter? We can't decide without knowing the individual object. + +Containers are another hard case. Should we pass `std::vector` in binary? +Even when `T` is a binary type, we don't currently have any way to pass an +array in binary format, so we always pass it as text. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md b/ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md new file mode 100644 index 0000000..2ad9fe3 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/escaping.md @@ -0,0 +1,74 @@ +String escaping {#escaping} +=============== + +Writing queries as strings is easy. But sometimes you need a variable in +there: `"SELECT id FROM user WHERE name = '" + name + "'"`. + +This is dangerous. See the bug? If `name` can contain quotes, you may have +an SQL injection vulnerability there, where users can enter nasty stuff like +"`.'; DROP TABLE user`". Or if you're lucky, it's just a nasty bug that you +discover when `name` happens to be "d'Arcy". + +So, you'll need to _escape_ the `name` before you insert it. This is where +quotes and other problematic characters are marked as "this is just a character +in the string, not the end of the string." There are +[several functions](@ref escaping-functions) in libpqxx to do this for you. + + +SQL injection +------------- + +To understand what SQL injection vulnerabilities are and why they should be +prevented, imagine you use the following SQL statement somewhere in your +program: + + TX.exec( + "SELECT number,amount " + "FROM accounts " + "WHERE allowed_to_see('" + userid + "','" + password + "')"); + +This shows a logged-in user important information on all accounts he is +authorized to view. The userid and password strings are variables entered +by the user himself. + +Now, if the user is actually an attacker who knows (or can guess) the +general shape of this SQL statement, imagine he enters the following +password: + + x') OR ('x' = 'x + +Does that make sense to you? Probably not. But if this is inserted into +the SQL string by the C++ code above, the query becomes: + + SELECT number,amount + FROM accounts + WHERE allowed_to_see('user','x') OR ('x' = 'x') + +Is this what you wanted to happen? Probably not! The neat `allowed_to_see()` +clause is completely circumvented by the "`OR ('x' = 'x')`" clause, which is +always `true`. Therefore, the attacker will get to see all accounts in the +database! + + +Using the esc functions +----------------------- + +Here's how you can fix the problem in the example above: + + TX.exec( + "SELECT number,amount " + "FROM accounts " + "WHERE allowed_to_see('" + TX.esc(userid) + "', " + "'" + TX.esc(password) + "')"); + +Now, the quotes embedded in the attacker's string will be neatly escaped so +they can't "break out" of the quoted SQL string they were meant to go into: + + SELECT number,amount + FROM accounts + WHERE allowed_to_see('user', 'x'') OR (''x'' = ''x') + +If you look carefully, you'll see that thanks to the added escape characters +(a single-quote is escaped in SQL by doubling it) all we get is a very +strange-looking password string--but not a change in the SQL statement. + diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md b/ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md new file mode 100644 index 0000000..1b87b88 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/getting-started.md @@ -0,0 +1,142 @@ +Getting started {#getting-started} +=============== + +The most basic three types in libpqxx are the _connection_, the _transaction_, +and the _result_. + +They fit together as follows: +* You connect to the database by creating a `pqxx::connection` object (see + @ref connections). + +* You create a transaction object (see @ref transactions) operating on that + connection. You'll usually want the `pqxx::work` variety. + + Once you're done you call the transaction's `commit` function to make its + work final. If you don't call this, the work will be rolled back when the + transaction object is destroyed. + +* Until then, use the transaction's `exec`, `query_value`, and `stream` + functions (and variants) to execute SQL statements. You pass the statements + themselves in as simple strings. (See @ref streams for more about data + streaming). + +* Most of the `exec` functions return a `pqxx::result` object, which acts + as a standard container of rows: `pqxx::row`. + + Each row in a result, in turn, acts as a container of fields: `pqxx::field`. + See @ref accessing-results for more about results, rows, and fields. + +* Each field's data is stored internally as a text string, in a format defined + by PostgreSQL. You can convert field or row values using their `as()` and + `to()` member functions. + +* After you've closed the transaction, the connection is free to run a next + transaction. + +Here's a very basic example. It connects to the default database (you'll +need to have one set up), queries it for a very simple result, converts it to +an `int`, and prints it out. It also contains some basic error handling. + + #include + #include + + int main() + { + try + { + // Connect to the database. In practice we may have to pass some + // arguments to say where the database server is, and so on. + // The constructor parses options exactly like libpq's + // PQconnectdb/PQconnect, see: + // https://www.postgresql.org/docs/10/static/libpq-connect.html + pqxx::connection c; + + // Start a transaction. In libpqxx, you always work in one. + pqxx::work w(c); + + // work::exec1() executes a query returning a single row of data. + // We'll just ask the database to return the number 1 to us. + pqxx::row r = w.exec1("SELECT 1"); + + // Commit your transaction. If an exception occurred before this + // point, execution will have left the block, and the transaction will + // have been destroyed along the way. In that case, the failed + // transaction would implicitly abort instead of getting to this point. + w.commit(); + + // Look at the first and only field in the row, parse it as an integer, + // and print it. + // + // "r[0]" returns the first field, which has an "as<...>()" member + // function template to convert its contents from their string format + // to a type of your choice. + std::cout << r[0].as() << std::endl; + } + catch (std::exception const &e) + { + std::cerr << e.what() << std::endl; + return 1; + } + } + +This prints the number 1. Notice that you can keep the result object around +after you've closed the transaction or even the connection. There are +situations where you can't do it, but generally it's fine. If you're +interested: you can install your own callbacks for receiving error messages +from the database, and in that case you'll have to keep the connection object +alive. But otherwise, it's nice to be able to "fire and forget" your +connection and deal with the data. + +You can also convert an entire row to a series of C++-side types in one go, +using the @c as member function on the row: + + pqxx::connection c; + pqxx::work w(c); + pqxx::row r = w.exec1("SELECT 1, 2, 'Hello'"); + auto [one, two, hello] = r.as(); + std::cout << (one + two) << ' ' << std::strlen(hello) << std::endl; + +Here's a slightly more complicated example. It takes an argument from the +command line and retrieves a string with that value. The interesting part is +that it uses the escaping-and-quoting function `quote` to embed this +string value in SQL safely. It also reads the result field's value as a +plain C-style string using its `c_str` function. + + #include + #include + #include + + int main(int argc, char *argv[]) + { + try + { + if (!argv[1]) throw std::runtime_error("Give me a string!"); + + pqxx::connection c; + pqxx::work w(c); + + // work::exec() returns a full result set, which can consist of any + // number of rows. + pqxx::result r = w.exec("SELECT " + w.quote(argv[1])); + + // End our transaction here. We can still use the result afterwards. + w.commit(); + + // Print the first field of the first row. Read it as a C string, + // just like std::string::c_str() does. + std::cout << r[0][0].c_str() << std::endl; + } + catch (std::exception const &e) + { + std::cerr << e.what() << std::endl; + return 1; + } + } + +You can find more about converting field values to native types, or +converting values to strings for use with libpqxx, under +@ref stringconversion. More about getting to the rows and fields of a +result is under @ref accessing-results. + +If you want to handle exceptions thrown by libpqxx in more detail, for +example to print the SQL contents of a query that failed, see @ref exception. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md b/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md new file mode 100644 index 0000000..5d4b8f9 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md @@ -0,0 +1,28 @@ +libpqxx {#mainpage} +======= + +@version 7.7.3 +@author Jeroen T. Vermeulen +@see http://pqxx.org +@see https://github.com/jtv/libpqxx + +Welcome to libpqxx, the C++ API to the PostgreSQL database management system. + +Compiling this package requires PostgreSQL to be installed -- including the +C headers for client development. The library builds on top of PostgreSQL's +standard C API, libpq. The libpq headers are not needed to compile client +programs, however. + +For a quick introduction to installing and using libpqxx, see the README.md +file. The latest information can be found at http://pqxx.org/ + + +Some links that should help you find your bearings: +* @ref getting-started +* @ref thread-safety +* @ref connections +* @ref transactions +* @ref escaping +* @ref performance +* @ref transactor +* @ref datatypes diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template b/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template new file mode 100644 index 0000000..d5afb24 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/mainpage.md.template @@ -0,0 +1,28 @@ +libpqxx {#mainpage} +======= + +@version @PQXXVERSION@ +@author Jeroen T. Vermeulen +@see http://pqxx.org +@see https://github.com/jtv/libpqxx + +Welcome to libpqxx, the C++ API to the PostgreSQL database management system. + +Compiling this package requires PostgreSQL to be installed -- including the +C headers for client development. The library builds on top of PostgreSQL's +standard C API, libpq. The libpq headers are not needed to compile client +programs, however. + +For a quick introduction to installing and using libpqxx, see the README.md +file. The latest information can be found at http://pqxx.org/ + + +Some links that should help you find your bearings: +* @ref getting-started +* @ref thread-safety +* @ref connections +* @ref transactions +* @ref escaping +* @ref performance +* @ref transactor +* @ref datatypes diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md b/ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md new file mode 100644 index 0000000..7ac7920 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/parameters.md @@ -0,0 +1,90 @@ +Statement parameters {#parameters} +==================== + +When you execute a prepared statement (see @ref prepared), or a parameterised +statement (using functions like `pqxx::connection::exec_params`), you may write +special _placeholders_ in the query text. They look like `$1`, `$2`, and so +on. + +If you execute the query and pass parameter values, the call will respectively +substitute the first where it finds `$1`, the second where it finds `$2`, et +cetera. + +Doing this saves you work. If you don't use statement parameters, you'll need +to quote and escape your values (see `connection::quote()` and friends) as you +insert them into your query as literal values. + +Or if you forget to do that, you leave yourself open to horrible +[SQL injection attacks](https://xkcd.com/327/). Trust me, I was born in a town +whose name started with an apostrophe! + +Statement parameters save you this work. With these parameters you can pass +your values as-is, and they will go across the wire to the database in a safe +format. + +In some cases it may even be faster! When a parameter represents binary data +(as in the SQL `BYTEA` type), libpqxx will send it directly as binary, which is +a bit more efficient. If you insert the binary data directly in your query +text, your CPU will have some extra work to do, converting the data into a text +format, escaping it, and adding quotes. + + +Dynamic parameter lists +----------------------- + +In rare cases you may just not know how many parameters you'll pass into your +statement when you call it. + +For these situations, have a look at `params`. It lets you compose your +parameters list on the fly, even add whole ranges of parameters at a time. + +You can pass a `params` into your statement as a normal parameter. It will +fill in all the parameter values it contains into that position of the +statement's overall parameter list. + +So if you call your statement passing a regular parameter `a`, a +`params` containing just a parameter `b`, and another regular parameter `c`, +then your call will pass parameters `a`, `b`, and `c`. Or if the params object +is empty, it will pass just `a` and `c`. If the params object contains `x` and +`y`, your call will pass `a, x, y, c`. + +You can mix static and dynamic parameters freely. Don't go overboard though: +complexity is where bugs happen! + + +Generating placeholders +----------------------- + +If your code gets particularly complex, it may sometimes happen that it becomes +hard to track which parameter value belongs with which placeholder. Did you +intend to pass this numeric value as `$7`, or as `$8`? The answer may depend +on an `if` that happened earlier in a different function. + +(Generally if things get that complex, it's a good idea to look for simpler +solutions. But especially when performance matters, sometimes you can't avoid +complexity like that.) + +There's a little helper class called `placeholders`. You can use it as a +counter which produces those placeholder strings, `$1`, `$2`, `$3`, et cetera. +When you start generating a complex statement, you can create both a `params` +and a `placeholders`: + + pqxx::params values; + pqxx::placeholders name; + +Let's say you've got some complex code to generate the conditions for an SQL +"WHERE" clause. You'll generally want to do these things close together in +your, so that you don't accidentally update one part and forget another: + + if (extra_clause) + { + // Extend the query text, using the current placeholder. + query += " AND x = " + name.get(); + // Add the parameter value. + values.append(my_x); + // Move on to the next placeholder value. + name.next(); + } + +Depending on the starting value of `name`, this might add to `query` a fragment +like "` AND x = $3`" or "` AND x = $5`". diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/performance.md b/ext/libpqxx-7.7.3/include/pqxx/doc/performance.md new file mode 100644 index 0000000..6c40368 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/performance.md @@ -0,0 +1,24 @@ +Performance features {#performance} +==================== + +If your program's database interaction is not as efficient as it needs to be, +the first place to look is usually the SQL you're executing. But libpqxx +has a few specialized features to help you squeeze more performance out +of how you issue commands and retrieve data: + +* @ref streams. Use these as a faster way to transfer data between your + code and the database. +* `std::string_view` and `pqxx::zview`. In places where traditional C++ worked + with `std::string`, see whether `std::string_view` or `pqxx::zview` will + do. Of course that means that you'll have to look at the data's lifetime + more carefully, but it'll save the computer a lot of copying. +* @ref prepared. These can be executed many times without the server + parsing and planning them anew each time. They also save you having to + escape string parameters. +* `pqxx::pipeline` lets you send queries to the database in batches, and + continue other processing while they are executing. +* `pqxx::connecting` lets you start setting up a database connection, but + without blocking the thread. + +As always of course, don't risk the quality of your code for optimizations +that you don't need! diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md b/ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md new file mode 100644 index 0000000..5193866 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/prepared-statement.md @@ -0,0 +1,125 @@ +Prepared statements {#prepared} +=================== + +Prepared statements are SQL queries that you define once and then invoke +as many times as you like, typically with varying parameters. It's basically +a function that you can define ad hoc. + +If you have an SQL statement that you're going to execute many times in +quick succession, it may be more efficient to prepare it once and reuse it. +This saves the database backend the effort of parsing complex SQL and +figuring out an efficient execution plan. Another nice side effect is that +you don't need to worry about escaping parameters. Some corporate coding +standards require all SQL parameters to be passed in this way, to reduce the +risk of programmer mistakes leaving room for SQL injections. + + +Preparing a statement +--------------------- + +You create a prepared statement by preparing it on the connection (using the +`pqxx::connection::prepare` functions), passing an identifier and its SQL text. + +The identifier is the name by which the prepared statement will be known; it +should consist of ASCII letters, digits, and underscores only, and start with +an ASCII letter. The name is case-sensitive. + +```cxx + void prepare_my_statement(pqxx::connection &c) + { + c.prepare( + "my_statement", + "SELECT * FROM Employee WHERE name = 'Xavier'"); + } +``` + +Once you've done this, you'll be able to call `my_statement` from any +transaction you execute on the same connection. For this, use the +`pqxx::transaction_base::exec_prepared` functions. + +```cxx + pqxx::result execute_my_statement(pqxx::transaction_base &t) + { + return t.exec_prepared("my_statement"); + } +``` + + +Parameters +---------- + +Did I mention that prepared statements can have parameters? The query text +can contain `$1`, `$2` etc. as placeholders for parameter values that you +will provide when you invoke the prepared satement. + +See @ref parameters for more about this. And here's a simple example of +preparing a statement and invoking it with parameters: + +```cxx + void prepare_find(pqxx::connection &c) + { + // Prepare a statement called "find" that looks for employees with a + // given name (parameter 1) whose salary exceeds a given number + // (parameter 2). + c.prepare( + "find", + "SELECT * FROM Employee WHERE name = $1 AND salary > $2"); + } +``` + +This example looks up the prepared statement "find," passes `name` and +`min_salary` as parameters, and invokes the statement with those values: + +```cxx + pqxx::result execute_find( + pqxx::transaction_base &t, std::string name, int min_salary) + { + return t.exec_prepared("find", name, min_salary); + } +``` + + +A special prepared statement +---------------------------- + +There is one special case: the _nameless_ prepared statement. You may prepare +a statement without a name, i.e. whose name is an empty string. The unnamed +statement can be redefined at any time, without un-preparing it first. + + +Performance note +---------------- + +Don't assume that using prepared statements will speed up your application. +There are cases where prepared statements are actually slower than plain SQL. + +The reason is that the backend can often produce a better execution plan when +it knows the statement's actual parameter values. + +For example, say you've got a web application and you're querying for users +with status "inactive" who have email addresses in a given domain name X. If +X is a very popular provider, the best way for the database engine to plan the +query may be to list the inactive users first and then filter for the email +addresses you're looking for. But in other cases, it may be much faster to +find matching email addresses first and then see which of their owners are +"inactive." A prepared statement must be planned to fit either case, but a +direct query will be optimised based on table statistics, partial indexes, etc. + + +Zero bytes +---------- + +@warning Beware of "nul" bytes! + +Any string you pass as a parameter will end at the _first char with value +zero._ If you pass a string that contains a zero byte, the last byte in the +value will be the one just before the zero. + +So, if you need a zero byte in a string, consider that it's really a _binary +string,_ which is not the same thing as a text string. SQL represents binary +data as the `BYTEA` type, or in binary large objects ("blobs"). + +In libpqxx, you represent binary data as a range of `std::byte`. They must be +contiguous in memory, so that libpqxx can pass pointers to the underlying C +library. So you might use `std::basic_string`, or +`std::basic_string_view`, or `std::vector`. diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/streams.md b/ext/libpqxx-7.7.3/include/pqxx/doc/streams.md new file mode 100644 index 0000000..3df4d61 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/streams.md @@ -0,0 +1,107 @@ +Streams {#streams} +======= + +Most of the time it's fine to retrieve data from the database using `SELECT` +queries, and store data using `INSERT`. But for those cases where efficiency +matters, there are two classes to help you do this better: `stream_from` and +`stream_to`. They're less flexible than SQL queries, and there's the risk of +losing your connection while you're in mid-stream, but you get some speed and +memory efficiencies in return. + +Both stream classes do data conversion for you: `stream_from` receives values +from the database in PostgreSQL's text format, and converts them to the C++ +types you specify. Likewise, `stream_to` converts C++ values you provide to +PostgreSQL's text format for transfer. (On its end, the database of course +converts values to and from their SQL types.) + + +Null values +----------- + +So how do you deal with nulls? It depends on the C++ type you're using. Some +types may have a built-in null value. For instance, if you have a +`char const *` value and you convert it to an SQL string, then converting a +`nullptr` will produce a NULL SQL value. + +But what do you do about C++ types which don't have a built-in null value, such +as `int`? The trick is to wrap it in `std::optional`. The difference between +`int` and `std::optional` is that the former always has an `int` value, +and the latter doesn't have to. + +Actually it's not just `std::optional`. You can do the same thing with +`std::unique_ptr` or `std::shared_ptr`. A smart pointer is less efficient than +`std::optional` in most situations because they allocate their value on the +heap, but sometimes that's what you want in order to save moving or copying +large values around. + +This part is not generic though. It won't work with just any smart-pointer +type, just the ones which are explicitly supported: `shared_ptr` and +`unique_ptr`. If you really need to, you can build support for additional +wrappers and smart pointers by copying the implementation patterns from the +existing smart-pointer support. + + +stream\_from +------------ + +Use `stream_from` to read data directly from the database. It's faster than +the transaction's `exec` functions if the result contains enough rows. But +also, you won't need to keep your full result set in memory. That can really +matter with larger data sets. + +And, you can start processing your data right after the first row of data comes +in from the server. With `exec()` you need to wait to receive all data, and +then you begin processing. With `stream_from` you can be processing data on +the client side while the server is still sending you the rest. + +You don't actually need to create a `stream_from` object yourself, though you +can. Two shorthand functions, @ref pqxx::transaction_base::stream +and @ref pqxx::transaction_base::for_each, can create the streams for you with +a minimum of overhead. + +Not all kinds of queries will work in a stream. Internally the streams make +use of PostgreSQL's `COPY` command, so see the PostgreSQL documentation for +`COPY` for the exact limitations. Basic `SELECT` and `UPDATE ... RETURNING` +queries should just work. + +As you read a row, the stream converts its fields to a tuple type containing +the value types you ask for: + + auto stream pqxx::stream_from::query( + tx, "SELECT name, points FROM score"); + std::tuple row; + while (stream >> row) + process(row); + stream.complete(); + +As the stream reads each row, it converts that row's data into your tuple, +goes through your loop body, and then promptly forgets that row's data. This +means you can easily process more data than will fit in memory. + + +stream\_to +---------- + +Use `stream_to` to write data directly to a database table. This saves you +having to perform an `INSERT` for every row, and so it can be significantly +faster if you want to insert more than just one or two rows at a time. + +As with `stream_from`, you can specify the table and the columns, and not much +else. You insert tuple-like objects of your choice: + + pqxx::stream_to stream{ + tx, + "score", + std::vector{"name", "points"}}; + for (auto const &entry: scores) + stream << entry; + stream.complete(); + +Each row is processed as you provide it, and not retained in memory after that. + +The call to `complete()` is more important here than it is for `stream_from`. +It's a lot like a "commit" or "abort" at the end of a transaction. If you omit +it, it will be done automatically during the stream's destructor. But since +destructors can't throw exceptions, any failures at that stage won't be visible +in your code. So, always call `complete()` on a `stream_to` to close it off +properly! diff --git a/ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md b/ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md new file mode 100644 index 0000000..07c7f99 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/doc/thread-safety.md @@ -0,0 +1,29 @@ +Thread safety {#thread-safety} +============= + +This library does not contain any locking code to protect objects against +simultaneous modification in multi-threaded programs. Therefore it is up +to you, the user of the library, to ensure that your threaded client +programs perform no conflicting operations concurrently. + +Most of the time this isn't hard. Result sets are immutable, so you can +share them between threads without problem. The main rule is: + +@li Treat a connection, together with any and all objects related to it, as +a "world" of its own. You should generally make sure that the same "world" +is never accessed by another thread while you're doing anything non-const +in there. + +That means: don't issue a query on a transaction while you're also opening +a subtransaction, don't access a cursor while you may also be committing, +and so on. + +In particular, cursors are tricky. It's easy to perform a non-const +operation without noticing. So, if you're going to share cursors or +cursor-related objects between threads, lock very conservatively! + +Use `pqxx::describe_thread_safety` to find out at runtime what level of +thread safety is implemented in your build and version of libpqxx. It +returns a `pqxx::thread_safety_model` describing what you can and cannot rely +on. A command-line utility `tools/pqxxthreadsafety` prints out the same +information. diff --git a/ext/libpqxx-7.7.3/include/pqxx/errorhandler b/ext/libpqxx-7.7.3/include/pqxx/errorhandler new file mode 100644 index 0000000..ea572ee --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/errorhandler @@ -0,0 +1,8 @@ +/** pqxx::errorhandler class. + * + * Callbacks for handling errors and warnings. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx b/ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx new file mode 100644 index 0000000..2ffb570 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/errorhandler.hxx @@ -0,0 +1,92 @@ +/* Definition of the pqxx::errorhandler class. + * + * pqxx::errorhandler handlers errors and warnings in a database session. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/errorhandler instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ERRORHANDLER +#define PQXX_H_ERRORHANDLER + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/types.hxx" + + +namespace pqxx::internal::gate +{ +class errorhandler_connection; +} + + +namespace pqxx +{ +/** + * @addtogroup errorhandler + */ +//@{ + +/// Base class for error-handler callbacks. +/** To receive errors and warnings from a connection, subclass this with your + * own error-handler functor, and instantiate it for the connection. Destroying + * the handler un-registers it. + * + * A connection can have multiple error handlers at the same time. When the + * database connection emits an error or warning message, it passes the message + * to each error handler, starting with the most recently registered one and + * progressing towards the oldest one. However an error handler may also + * instruct the connection not to pass the message to further handlers by + * returning "false." + * + * @warning Strange things happen when a result object outlives its parent + * connection. If you register an error handler on a connection, then you must + * not access the result after destroying the connection. This applies even if + * you destroy the error handler first! + */ +class PQXX_LIBEXPORT errorhandler +{ +public: + explicit errorhandler(connection &); + virtual ~errorhandler(); + + /// Define in subclass: receive an error or warning message from the + /// database. + /** + * @return Whether the same error message should also be passed to the + * remaining, older errorhandlers. + */ + virtual bool operator()(char const msg[]) noexcept = 0; + + errorhandler() = delete; + errorhandler(errorhandler const &) = delete; + errorhandler &operator=(errorhandler const &) = delete; + +private: + connection *m_home; + + friend class internal::gate::errorhandler_connection; + void unregister() noexcept; +}; + + +/// An error handler that suppresses any previously registered error handlers. +class quiet_errorhandler : public errorhandler +{ +public: + /// Suppress error notices. + quiet_errorhandler(connection &conn) : errorhandler{conn} {} + + /// Revert to previous handling of error notices. + virtual bool operator()(char const[]) noexcept override { return false; } +}; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/except b/ext/libpqxx-7.7.3/include/pqxx/except new file mode 100644 index 0000000..e5dd508 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/except @@ -0,0 +1,8 @@ +/** libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/except.hxx b/ext/libpqxx-7.7.3/include/pqxx/except.hxx new file mode 100644 index 0000000..24f9594 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/except.hxx @@ -0,0 +1,447 @@ +/* Definition of libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/except instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_EXCEPT +#define PQXX_H_EXCEPT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + + +namespace pqxx +{ +/** + * @addtogroup exception Exception classes + * + * These exception classes follow, roughly, the two-level hierarchy defined by + * the PostgreSQL SQLSTATE error codes (see Appendix A of the PostgreSQL + * documentation corresponding to your server version). This is not a complete + * mapping though. There are other differences as well, e.g. the error code + * for `statement_completion_unknown` has a separate status in libpqxx as + * @ref in_doubt_error, and `too_many_connections` is classified as a + * `broken_connection` rather than a subtype of `insufficient_resources`. + * + * @see http://www.postgresql.org/docs/9.4/interactive/errcodes-appendix.html + * + * @{ + */ + +/// Run-time failure encountered by libpqxx, similar to std::runtime_error. +struct PQXX_LIBEXPORT failure : std::runtime_error +{ + explicit failure(std::string const &); +}; + + +/// Exception class for lost or failed backend connection. +/** + * @warning When this happens on Unix-like systems, you may also get a SIGPIPE + * signal. That signal aborts the program by default, so if you wish to be + * able to continue after a connection breaks, be sure to disarm this signal. + * + * If you're working on a Unix-like system, see the manual page for + * `signal` (2) on how to deal with SIGPIPE. The easiest way to make this + * signal harmless is to make your program ignore it: + * + * ```cxx + * #include + * + * int main() + * { + * signal(SIGPIPE, SIG_IGN); + * // ... + * ``` + */ +struct PQXX_LIBEXPORT broken_connection : failure +{ + broken_connection(); + explicit broken_connection(std::string const &); +}; + + +/// The caller attempted to set a variable to null, which is not allowed. +struct PQXX_LIBEXPORT variable_set_to_null : failure +{ + variable_set_to_null(); + explicit variable_set_to_null(std::string const &); +}; + + +/// Exception class for failed queries. +/** Carries, in addition to a regular error message, a copy of the failed query + * and (if available) the SQLSTATE value accompanying the error. + */ +class PQXX_LIBEXPORT sql_error : public failure +{ + /// Query string. Empty if unknown. + std::string const m_query; + /// SQLSTATE string describing the error type, if known; or empty string. + std::string const m_sqlstate; + +public: + explicit sql_error( + std::string const &whatarg = "", std::string const &Q = "", + char const sqlstate[] = nullptr); + virtual ~sql_error() noexcept override; + + /// The query whose execution triggered the exception + [[nodiscard]] PQXX_PURE std::string const &query() const noexcept; + + /// SQLSTATE error code if known, or empty string otherwise. + [[nodiscard]] PQXX_PURE std::string const &sqlstate() const noexcept; +}; + + +/// "Help, I don't know whether transaction was committed successfully!" +/** Exception that might be thrown in rare cases where the connection to the + * database is lost while finishing a database transaction, and there's no way + * of telling whether it was actually executed by the backend. In this case + * the database is left in an indeterminate (but consistent) state, and only + * manual inspection will tell which is the case. + */ +struct PQXX_LIBEXPORT in_doubt_error : failure +{ + explicit in_doubt_error(std::string const &); +}; + + +/// The backend saw itself forced to roll back the ongoing transaction. +struct PQXX_LIBEXPORT transaction_rollback : sql_error +{ + explicit transaction_rollback( + std::string const &whatarg, std::string const &q = "", + char const sqlstate[] = nullptr); +}; + + +/// Transaction failed to serialize. Please retry it. +/** Can only happen at transaction isolation levels REPEATABLE READ and + * SERIALIZABLE. + * + * The current transaction cannot be committed without violating the guarantees + * made by its isolation level. This is the effect of a conflict with another + * ongoing transaction. The transaction may still succeed if you try to + * perform it again. + */ +struct PQXX_LIBEXPORT serialization_failure : transaction_rollback +{ + explicit serialization_failure( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// We can't tell whether our last statement succeeded. +struct PQXX_LIBEXPORT statement_completion_unknown : transaction_rollback +{ + explicit statement_completion_unknown( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// The ongoing transaction has deadlocked. Retrying it may help. +struct PQXX_LIBEXPORT deadlock_detected : transaction_rollback +{ + explicit deadlock_detected( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// Internal error in libpqxx library +struct PQXX_LIBEXPORT internal_error : std::logic_error +{ + explicit internal_error(std::string const &); +}; + + +/// Error in usage of libpqxx library, similar to std::logic_error +struct PQXX_LIBEXPORT usage_error : std::logic_error +{ + explicit usage_error(std::string const &); +}; + + +/// Invalid argument passed to libpqxx, similar to std::invalid_argument +struct PQXX_LIBEXPORT argument_error : std::invalid_argument +{ + explicit argument_error(std::string const &); +}; + + +/// Value conversion failed, e.g. when converting "Hello" to int. +struct PQXX_LIBEXPORT conversion_error : std::domain_error +{ + explicit conversion_error(std::string const &); +}; + + +/// Could not convert value to string: not enough buffer space. +struct PQXX_LIBEXPORT conversion_overrun : conversion_error +{ + explicit conversion_overrun(std::string const &); +}; + + +/// Something is out of range, similar to std::out_of_range +struct PQXX_LIBEXPORT range_error : std::out_of_range +{ + explicit range_error(std::string const &); +}; + + +/// Query returned an unexpected number of rows. +struct PQXX_LIBEXPORT unexpected_rows : public range_error +{ + explicit unexpected_rows(std::string const &msg) : range_error{msg} {} +}; + + +/// Database feature not supported in current setup. +struct PQXX_LIBEXPORT feature_not_supported : sql_error +{ + explicit feature_not_supported( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Error in data provided to SQL statement. +struct PQXX_LIBEXPORT data_exception : sql_error +{ + explicit data_exception( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT integrity_constraint_violation : sql_error +{ + explicit integrity_constraint_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT restrict_violation : integrity_constraint_violation +{ + explicit restrict_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT not_null_violation : integrity_constraint_violation +{ + explicit not_null_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT foreign_key_violation : integrity_constraint_violation +{ + explicit foreign_key_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT unique_violation : integrity_constraint_violation +{ + explicit unique_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT check_violation : integrity_constraint_violation +{ + explicit check_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_state : sql_error +{ + explicit invalid_cursor_state( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_sql_statement_name : sql_error +{ + explicit invalid_sql_statement_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_name : sql_error +{ + explicit invalid_cursor_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT syntax_error : sql_error +{ + /// Approximate position in string where error occurred, or -1 if unknown. + int const error_position; + + explicit syntax_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr, int pos = -1) : + sql_error{err, Q, sqlstate}, error_position{pos} + {} +}; + +struct PQXX_LIBEXPORT undefined_column : syntax_error +{ + explicit undefined_column( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_function : syntax_error +{ + explicit undefined_function( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_table : syntax_error +{ + explicit undefined_table( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT insufficient_privilege : sql_error +{ + explicit insufficient_privilege( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Resource shortage on the server +struct PQXX_LIBEXPORT insufficient_resources : sql_error +{ + explicit insufficient_resources( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT disk_full : insufficient_resources +{ + explicit disk_full( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT out_of_memory : insufficient_resources +{ + explicit out_of_memory( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT too_many_connections : broken_connection +{ + explicit too_many_connections(std::string const &err) : + broken_connection{err} + {} +}; + +/// PL/pgSQL error +/** Exceptions derived from this class are errors from PL/pgSQL procedures. + */ +struct PQXX_LIBEXPORT plpgsql_error : sql_error +{ + explicit plpgsql_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Exception raised in PL/pgSQL procedure +struct PQXX_LIBEXPORT plpgsql_raise : plpgsql_error +{ + explicit plpgsql_raise( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_no_data_found : plpgsql_error +{ + explicit plpgsql_no_data_found( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_too_many_rows : plpgsql_error +{ + explicit plpgsql_too_many_rows( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT blob_already_exists : failure +{ + explicit blob_already_exists(std::string const &); +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/field b/ext/libpqxx-7.7.3/include/pqxx/field new file mode 100644 index 0000000..37cb69e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/field @@ -0,0 +1,8 @@ +/** pqxx::field class. + * + * pqxx::field refers to a field in a query result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/field.hxx b/ext/libpqxx-7.7.3/include/pqxx/field.hxx new file mode 100644 index 0000000..b8b869f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/field.hxx @@ -0,0 +1,542 @@ +/* Definitions for the pqxx::field class. + * + * pqxx::field refers to a field in a query result. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_FIELD +#define PQXX_H_FIELD + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/array.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" + +namespace pqxx +{ +/// Reference to a field in a result set. +/** A field represents one entry in a row. It represents an actual value + * in the result set, and can be converted to various types. + */ +class PQXX_LIBEXPORT field +{ +public: + using size_type = field_size_type; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + /** Create field as reference to a field in a result set. + * @param r Row that this field is part of. + * @param c Column number of this field. + */ + [[deprecated( + "Do not construct fields yourself. Get them from the row.")]] field(row const &r, row_size_type c) noexcept; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + [[deprecated( + "Do not construct fields yourself. Get them from the " + "row.")]] field() noexcept = default; + + /** + * @name Comparison + */ + //@{ + // TODO: noexcept. Breaks ABI. + /// Byte-by-byte comparison of two fields (all nulls are considered equal) + /** @warning null handling is still open to discussion and change! + * + * Handling of null values differs from that in SQL where a comparison + * involving a null value yields null, so nulls are never considered equal + * to one another or even to themselves. + * + * Null handling also probably differs from the closest equivalent in C++, + * which is the NaN (Not-a-Number) value, a singularity comparable to + * SQL's null. This is because the builtin == operator demands that a == a. + * + * The usefulness of this operator is questionable. No interpretation + * whatsoever is imposed on the data; 0 and 0.0 are considered different, + * as are null vs. the empty string, or even different (but possibly + * equivalent and equally valid) encodings of the same Unicode character + * etc. + */ + [[nodiscard]] PQXX_PURE bool operator==(field const &) const; + + /// Byte-by-byte comparison (all nulls are considered equal) + /** @warning See operator==() for important information about this operator + */ + [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /** + * @name Column information + */ + //@{ + /// Column name. + [[nodiscard]] PQXX_PURE char const *name() const &; + + /// Column type. + [[nodiscard]] oid PQXX_PURE type() const; + + /// What table did this column come from? + [[nodiscard]] PQXX_PURE oid table() const; + + /// Return row number. The first row is row 0, the second is row 1, etc. + PQXX_PURE constexpr row_size_type num() const noexcept { return col(); } + + /// What column number in its originating table did this column come from? + [[nodiscard]] PQXX_PURE row_size_type table_column() const; + //@} + + /** + * @name Content access + */ + //@{ + /// Read as `string_view`, or an empty one if null. + /** The result only remains usable while the data for the underlying + * @ref result exists. Once all `result` objects referring to that data have + * been destroyed, the `string_view` will no longer point to valid memory. + */ + [[nodiscard]] PQXX_PURE std::string_view view() const & + { + return std::string_view(c_str(), size()); + } + + /// Read as plain C string. + /** Since the field's data is stored internally in the form of a + * zero-terminated C string, this is the fastest way to read it. Use the + * to() or as() functions to convert the string to other types such as + * `int`, or to C++ strings. + * + * Do not use this for BYTEA values, or other binary values. To read those, + * convert the value to your desired type using `to()` or `as()`. For + * example: `f.as>()`. + */ + [[nodiscard]] PQXX_PURE char const *c_str() const &; + + /// Is this field's value null? + [[nodiscard]] PQXX_PURE bool is_null() const noexcept; + + /// Return number of bytes taken up by the field's value. + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + + /// Read value into obj; or if null, leave obj untouched and return `false`. + /** This can be used with optional types (except pointers other than C-style + * strings). + */ + template + auto to(T &obj) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + if (is_null()) + { + return false; + } + else + { + auto const bytes{c_str()}; + from_string(bytes, obj); + return true; + } + } + + /// Read field as a composite value, write its components into `fields`. + /** @warning This is still experimental. It may change or be replaced. + * + * Returns whether the field was null. If it was, it will not touch the + * values in `fields`. + */ + template bool composite_to(T &...fields) const + { + if (is_null()) + { + return false; + } + else + { + parse_composite(m_home.m_encoding, view(), fields...); + return true; + } + } + + /// Read value into obj; or leave obj untouched and return `false` if null. + template bool operator>>(T &obj) const { return to(obj); } + + /// Read value into obj; or if null, use default value and return `false`. + /** This can be used with `std::optional`, as well as with standard smart + * pointer types, but not with raw pointers. If the conversion from a + * PostgreSQL string representation allocates a pointer (e.g. using `new`), + * then the object's later deallocation should be baked in as well, right + * from the point where the object is created. So if you want a pointer, use + * a smart pointer, not a raw pointer. + * + * There is one exception, of course: C-style strings. Those are just + * pointers to the field's internal text data. + */ + template + auto to(T &obj, T const &default_value) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = from_string(this->view()); + return not null; + } + + /// Return value as object of given type, or default value if null. + /** Note that unless the function is instantiated with an explicit template + * argument, the Default value's type also determines the result type. + */ + template T as(T const &default_value) const + { + if (is_null()) + return default_value; + else + return from_string(this->view()); + } + + /// Return value as object of given type, or throw exception if null. + /** Use as `as>()` or `as()` as + * an alternative to `get()`; this is disabled for use with raw pointers + * (other than C-strings) because storage for the value can't safely be + * allocated here + */ + template T as() const + { + if (is_null()) + { + if constexpr (not nullness::has_null) + internal::throw_null_conversion(type_name); + else + return nullness::null(); + } + else + { + return from_string(this->view()); + } + } + + /// Return value wrapped in some optional type (empty for nulls). + /** Use as `get()` as before to obtain previous behavior, or specify + * container type with `get()` + */ + template class O = std::optional> + constexpr O get() const + { + return as>(); + } + + // TODO: constexpr noexcept, once array_parser constructor gets those. + /// Parse the field as an SQL array. + /** Call the parser to retrieve values (and structure) from the array. + * + * Make sure the @ref result object stays alive until parsing is finished. If + * you keep the @ref row of `field` object alive, it will keep the @ref + * result object alive as well. + */ + array_parser as_array() const & + { + return array_parser{c_str(), m_home.m_encoding}; + } + //@} + + +protected: + constexpr result const &home() const noexcept { return m_home; } + constexpr result::size_type idx() const noexcept { return m_row; } + constexpr row_size_type col() const noexcept { return m_col; } + + // TODO: Create gates. + friend class pqxx::result; + friend class pqxx::row; + field( + result const &r, result_size_type row_num, row_size_type col_num) noexcept + : + m_col{col_num}, m_home{r}, m_row{row_num} + {} + + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + row_size_type m_col; + +private: + result m_home; + result::size_type m_row; +}; + + +template<> inline bool field::to(std::string &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = std::string{view()}; + return not null; +} + + +template<> +inline bool field::to( + std::string &obj, std::string const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = std::string{view()}; + return not null; +} + + +/// Specialization: `to(char const *&)`. +/** The buffer has the same lifetime as the data in this result (i.e. of this + * result object, or the last remaining one copied from it etc.), so take care + * not to use it after the last result object referring to this query result is + * destroyed. + */ +template<> inline bool field::to(char const *&obj) const +{ + bool const null{is_null()}; + if (not null) + obj = c_str(); + return not null; +} + + +template<> inline bool field::to(std::string_view &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = view(); + return not null; +} + + +template<> +inline bool field::to( + std::string_view &obj, std::string_view const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = view(); + return not null; +} + + +template<> inline std::string_view field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return view(); +} + + +template<> +inline std::string_view +field::as(std::string_view const &default_value) const +{ + return is_null() ? default_value : view(); +} + + +template<> inline bool field::to(zview &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = zview{c_str(), size()}; + return not null; +} + + +template<> +inline bool field::to(zview &obj, zview const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = zview{c_str(), size()}; + return not null; +} + + +template<> inline zview field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return zview{c_str(), size()}; +} + + +template<> inline zview field::as(zview const &default_value) const +{ + return is_null() ? default_value : zview{c_str(), size()}; +} + + +template> +class field_streambuf : public std::basic_streambuf +{ +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = std::ios::openmode; + using seekdir = std::ios::seekdir; + + explicit field_streambuf(field const &f) : m_field{f} { initialize(); } + +protected: + virtual int sync() override { return traits_type::eof(); } + + virtual pos_type seekoff(off_type, seekdir, openmode) override + { + return traits_type::eof(); + } + virtual pos_type seekpos(pos_type, openmode) override + { + return traits_type::eof(); + } + virtual int_type overflow(int_type) override { return traits_type::eof(); } + virtual int_type underflow() override { return traits_type::eof(); } + +private: + field const &m_field; + + int_type initialize() + { + auto g{static_cast(const_cast(m_field.c_str()))}; + this->setg(g, g, g + std::size(m_field)); + return int_type(std::size(m_field)); + } +}; + + +/// Input stream that gets its data from a result field +/** Use this class exactly as you would any other istream to read data from a + * field. All formatting and streaming operations of `std::istream` are + * supported. What you'll typically want to use, however, is the fieldstream + * alias (which defines a @ref basic_fieldstream for `char`). This is similar + * to how e.g. `std::ifstream` relates to `std::basic_ifstream`. + * + * This class has only been tested for the char type (and its default traits). + */ +template> +class basic_fieldstream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + basic_fieldstream(field const &f) : super{nullptr}, m_buf{f} + { + super::init(&m_buf); + } + +private: + field_streambuf m_buf; +}; + +using fieldstream = basic_fieldstream; + +/// Write a result field to any type of stream +/** This can be convenient when writing a field to an output stream. More + * importantly, it lets you write a field to e.g. a `stringstream` which you + * can then use to read, format and convert the field in ways that to() does + * not support. + * + * Example: parse a field into a variable of the nonstandard + * "long long" type. + * + * ```cxx + * extern result R; + * long long L; + * stringstream S; + * + * // Write field's string into S + * S << R[0][0]; + * + * // Parse contents of S into L + * S >> L; + * ``` + */ +template +inline std::basic_ostream & +operator<<(std::basic_ostream &s, field const &value) +{ + s.write(value.c_str(), std::streamsize(std::size(value))); + return s; +} + + +/// Convert a field's value to type `T`. +/** Unlike the "regular" `from_string`, this knows how to deal with null + * values. + */ +template inline T from_string(field const &value) +{ + if (value.is_null()) + { + if constexpr (nullness::has_null) + return nullness::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + return from_string(value.view()); + } +} + + +/// Convert a field's value to `nullptr_t`. +/** Yes, you read that right. This conversion does nothing useful. It always + * returns `nullptr`. + * + * Except... what if the field is not null? In that case, this throws + * @ref conversion_error. + */ +template<> +inline std::nullptr_t from_string(field const &value) +{ + if (not value.is_null()) + throw conversion_error{ + "Extracting non-null field into nullptr_t variable."}; + return nullptr; +} + + +/// Convert a field to a string. +template<> PQXX_LIBEXPORT std::string to_string(field const &value); +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx new file mode 100644 index 0000000..d2b6603 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/array-composite.hxx @@ -0,0 +1,305 @@ +#if !defined(PQXX_ARRAY_COMPOSITE_HXX) +# define PQXX_ARRAY_COMPOSITE_HXX + +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +// Find the end of a double-quoted string. +/** `input[pos]` must be the opening double quote. + * + * Returns the offset of the first position after the closing quote. + */ +inline std::size_t scan_double_quoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + // XXX: find_char<'"', '\\'>(). + auto next{scan(input, size, pos)}; + bool at_quote{false}; + for (pos = next, next = scan(input, size, pos); pos < size; + pos = next, next = scan(input, size, pos)) + { + if (at_quote) + { + if (next - pos == 1 and input[pos] == '"') + { + // We just read a pair of double quotes. Carry on. + at_quote = false; + } + else + { + // We just read one double quote, and now we're at a character that's + // not a second double quote. Ergo, that last character was the + // closing double quote and this is the position right after it. + return pos; + } + } + else if (next - pos == 1) + { + switch (input[pos]) + { + case '\\': + // Backslash escape. Skip ahead by one more character. + pos = next; + next = scan(input, size, pos); + break; + + case '"': + // This is either the closing double quote, or the first of a pair of + // double quotes. + at_quote = true; + break; + } + } + else + { + // Multibyte character. Carry on. + } + } + if (not at_quote) + throw argument_error{ + "Missing closing double-quote: " + std::string{input}}; + return pos; +} + + +/// Un-quote and un-escape a double-quoted SQL string. +inline std::string parse_double_quoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + // Maximum output size is same as the input size, minus the opening and + // closing quotes. Or in the extreme opposite case, the real number could be + // half that. Usually it'll be a pretty close estimate. + output.reserve(std::size_t(end - pos - 2)); + + for (auto here{scan(input, end, pos)}, next{scan(input, end, here)}; + here < end - 1; here = next, next = scan(input, end, here)) + { + // A backslash here is always an escape. So is a double-quote, since we're + // inside the double-quoted string. In either case, we can just ignore the + // escape character and use the next character. This is the one redeeming + // feature of SQL's escaping system. + if ((next - here == 1) and (input[here] == '\\' or input[here] == '"')) + { + // Skip escape. + here = next; + next = scan(input, end, here); + } + output.append(input + here, input + next); + } + return output; +} + + +/// Find the end of an unquoted string in an array or composite-type value. +/** Stops when it gets to the end of the input; or when it sees any of the + * characters in STOP which has not been escaped. + * + * For array values, STOP is a comma, a semicolon, or a closing brace. For + * a value of a composite type, STOP is a comma or a closing parenthesis. + */ +template +inline std::size_t scan_unquoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + bool at_backslash{false}; + auto next{scan(input, size, pos)}; + while ((pos < size) and + ((next - pos) > 1 or at_backslash or ((input[pos] != STOP) and ...))) + { + pos = next; + next = scan(input, size, pos); + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + } + return pos; +} + + +/// Parse an unquoted array entry or cfield of a composite-type field. +inline std::string parse_unquoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + bool at_backslash{false}; + output.reserve(end - pos); + for (auto next{scan(input, end, pos)}; pos < end; + pos = next, next = scan(input, end, pos)) + { + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + if (not at_backslash) + output.append(input + pos, next - pos); + } + return output; +} + + +/// Parse a field of a composite-type value. +/** `T` is the C++ type of the field we're parsing, and `index` is its + * zero-based number. + * + * Strip off the leading parenthesis or bracket yourself before parsing. + * However, this function will parse the lcosing parenthesis or bracket. + * + * After a successful parse, `pos` will point at `std::end(text)`. + * + * For the purposes of parsing, ranges and arrays count as compositve values, + * so this function supports parsing those. If you specifically need a closing + * parenthesis, check afterwards that `text` did not end in a bracket instead. + * + * @param index Index of the current field, zero-based. It will increment for + * the next field. + * @param input Full input text for the entire composite-type value. + * @param pos Starting position (in `input`) of the field that we're parsing. + * After parsing, this will point at the beginning of the next field if + * there is one, or one position past the last character otherwise. + * @param field Destination for the parsed value. + * @param scan Glyph scanning function for the relevant encoding type. + * @param last_field Number of the last field in the value (zero-based). When + * parsing the last field, this will equal `index`. + */ +template +inline void parse_composite_field( + std::size_t &index, std::string_view input, std::size_t &pos, T &field, + glyph_scanner_func *scan, std::size_t last_field) +{ + assert(index <= last_field); + auto next{scan(std::data(input), std::size(input), pos)}; + if ((next - pos) != 1) + throw conversion_error{"Non-ASCII character in composite-type syntax."}; + + // Expect a field. + switch (input[pos]) + { + case ',': + case ')': + case ']': + // The field is empty, i.e, null. + if constexpr (nullness::has_null) + field = nullness::null(); + else + throw conversion_error{ + "Can't read composite field " + to_string(index) + ": C++ type " + + type_name + " does not support nulls."}; + break; + + case '"': { + auto const stop{scan_double_quoted_string( + std::data(input), std::size(input), pos, scan)}; + auto const text{ + parse_double_quoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + + default: { + auto const stop{scan_unquoted_string<',', ')', ']'>( + std::data(input), std::size(input), pos, scan)}; + auto const text{parse_unquoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + } + + // Expect a comma or a closing parenthesis. + next = scan(std::data(input), std::size(input), pos); + + if ((next - pos) != 1) + throw conversion_error{ + "Unexpected non-ASCII character after composite field: " + + std::string{input}}; + + if (index < last_field) + { + if (input[pos] != ',') + throw conversion_error{ + "Found '" + std::string{input[pos]} + + "' in composite value where comma was expected: " + std::data(input)}; + } + else + { + if (input[pos] == ',') + throw conversion_error{ + "Composite value contained more fields than the expected " + + to_string(last_field) + ": " + std::data(input)}; + if (input[pos] != ')' and input[pos] != ']') + throw conversion_error{ + "Composite value has unexpected characters where closing parenthesis " + "was expected: " + + std::string{input}}; + if (next != std::size(input)) + throw conversion_error{ + "Composite value has unexpected text after closing parenthesis: " + + std::string{input}}; + } + + pos = next; + ++index; +} + + +/// Conservatively estimate buffer size needed for a composite field. +template +inline std::size_t size_composite_field_buffer(T const &field) +{ + if constexpr (is_unquoted_safe) + { + // Safe to copy, without quotes or escaping. Drop the terminating zero. + return size_buffer(field) - 1; + } + else + { + // + Opening quote. + // + Field budget. + // - Terminating zero. + // + Escaping for each byte in the field's string representation. + // - Escaping for terminating zero. + // + Closing quote. + return 1 + 2 * (size_buffer(field) - 1) + 1; + } +} + + +template +inline void write_composite_field(char *&pos, char *end, T const &field) +{ + if constexpr (is_unquoted_safe) + { + // No need for quoting or escaping. Convert it straight into its final + // place in the buffer, and "backspace" the trailing zero. + pos = string_traits::into_buf(pos, end, field) - 1; + } + else + { + // The field may need escaping, which means we need an intermediate buffer. + // To avoid allocating that at run time, we use the end of the buffer that + // we have. + auto const budget{size_buffer(field)}; + *pos++ = '"'; + + // Now escape buf into its final position. + for (char const c : string_traits::to_buf(end - budget, end, field)) + { + if ((c == '"') or (c == '\\')) + *pos++ = '\\'; + + *pos++ = c; + } + + *pos++ = '"'; + } + + *pos++ = ','; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx new file mode 100644 index 0000000..42f7703 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/callgate.hxx @@ -0,0 +1,70 @@ +#ifndef PQXX_H_CALLGATE +#define PQXX_H_CALLGATE + +/* +Here's what a typical gate class definition looks like: + +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE @gateclass@ : callgate<@host@> +{ + friend class @client@; + + @gateclass@(reference x) : super(x) {} + + // Methods here. Use home() to access the host-class object. +}; +} // namespace pqxx::internal::gate +*/ + +namespace pqxx::internal +{ +/// Base class for call gates. +/** + * A call gate defines a limited, private interface on the host class that + * specified client classes can access. + * + * The metaphor works as follows: the gate stands in front of a "home," which + * is really a class, and only lets specific friends in. + * + * To implement a call gate that gives client C access to host H, + * * derive a gate class from callgate; + * * make the gate class a friend of H; + * * make C a friend of the gate class; and + * * implement "stuff C can do with H" as private members in the gate class. + * + * This special kind of "gated" friendship gives C private access to H, but + * only through an expressly limited interface. The gate class can access its + * host object as home(). + * + * Keep gate classes entirely stateless. They should be ultra-lightweight + * wrappers for their host classes, and be optimized away as much as possible + * by the compiler. Once you start adding state, you're on a slippery slope + * away from the pure, clean, limited interface pattern that gate classes are + * meant to implement. + * + * Ideally, all member functions of the gate class should be one-liners passing + * calls straight on to the host class. It can be useful however to break this + * rule temporarily during inter-class refactoring. + */ +template class PQXX_PRIVATE callgate +{ +protected: + /// This class, to keep constructors easy. + using super = callgate; + /// A reference to the host class. Helps keep constructors easy. + using reference = HOME &; + + callgate(reference x) : m_home(x) {} + + /// The home object. The gate class has full "private" access. + reference home() const noexcept { return m_home; } + +private: + reference m_home; +}; +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx new file mode 100644 index 0000000..cd28bde --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/concat.hxx @@ -0,0 +1,45 @@ +#if !defined(PQXX_CONCAT_HXX) +# define PQXX_CONCAT_HXX + +# include +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +/// Convert item to a string, write it into [here, end). +template +void render_item(TYPE const &item, char *&here, char *end) +{ + here = string_traits::into_buf(here, end, item) - 1; +} + + +// C++20: Support non-random_access_range ranges. +/// Efficiently combine a bunch of items into one big string. +/** Use this as an optimised version of string concatentation. It takes just + * about any type; it will represent each item as a string according to its + * @ref string_traits. + * + * This is a simpler, more specialised version of @ref separated_list for a + * statically known series of items, possibly of different types. + */ +template +[[nodiscard]] inline std::string concat(TYPE... item) +{ + std::string buf; + // Size to accommodate string representations of all inputs, minus their + // terminating zero bytes. + buf.resize(size_buffer(item...)); + + char *const data{buf.data()}; + char *here = data; + char *end = data + std::size(buf); + (render_item(item, here, end), ...); + + buf.resize(static_cast(here - data)); + return buf; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx new file mode 100644 index 0000000..1df4fde --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/conversions.hxx @@ -0,0 +1,1188 @@ +#include +#include +#include +#include +#include +#include + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include +#include +#include + +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" + + +/* Internal helpers for string conversion, and conversion implementations. + * + * Do not include this header directly. The libpqxx headers do it for you. + */ +namespace pqxx::internal +{ +/// Convert a number in [0, 9] to its ASCII digit. +inline constexpr char number_to_digit(int i) noexcept +{ + return static_cast(i + '0'); +} + + +/// Compute numeric value of given textual digit (assuming that it is a digit). +constexpr int digit_to_number(char c) noexcept +{ + return c - '0'; +} + + +/// Summarize buffer overrun. +/** Don't worry about the exact parameter types: the sizes will be reasonably + * small, and nonnegative. + */ +std::string PQXX_LIBEXPORT +state_buffer_overrun(int have_bytes, int need_bytes); + + +template +inline std::string state_buffer_overrun(HAVE have_bytes, NEED need_bytes) +{ + return state_buffer_overrun( + static_cast(have_bytes), static_cast(need_bytes)); +} + + +/// Throw exception for attempt to convert null to given type. +[[noreturn]] PQXX_LIBEXPORT void +throw_null_conversion(std::string const &type); + + +/// Deliberately nonfunctional conversion traits for `char` types. +/** There are no string conversions for `char` and its signed and unsigned + * variants. Such a conversion would be dangerously ambiguous: should we treat + * it as text, or as a small integer? It'd be an open invitation for bugs. + * + * But the error message when you get this wrong is very cryptic. So, we + * derive dummy @ref string_traits implementations from this dummy type, and + * ensure that the compiler disallows their use. The compiler error message + * will at least contain a hint of the root of the problem. + */ +template struct disallowed_ambiguous_char_conversion +{ + static char *into_buf(char *, char *, CHAR_TYPE) = delete; + static constexpr zview + to_buf(char *, char *, CHAR_TYPE const &) noexcept = delete; + + static constexpr std::size_t + size_buffer(CHAR_TYPE const &) noexcept = delete; + static CHAR_TYPE from_string(std::string_view) = delete; +}; + + +template PQXX_LIBEXPORT extern std::string to_string_float(T); + + +/// Generic implementation for into_buf, on top of to_buf. +template +inline char *generic_into_buf(char *begin, char *end, T const &value) +{ + zview const text{string_traits::to_buf(begin, end, value)}; + auto const space{end - begin}; + // Include the trailing zero. + auto const len = std::size(text) + 1; + if (internal::cmp_greater(len, space)) + throw conversion_overrun{ + "Not enough buffer space to insert " + type_name + ". " + + state_buffer_overrun(space, len)}; + std::memmove(begin, text.data(), len); + return begin + len; +} + + +/// String traits for builtin integral types (though not bool). +template struct integral_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + static constexpr std::size_t size_buffer(T const &) noexcept + { + /** Includes a sign if needed; the number of base-10 digits which the type + * can reliably represent; the one extra base-10 digit which the type can + * only partially represent; and the terminating zero. + */ + return std::is_signed_v + std::numeric_limits::digits10 + 1 + 1; + } +}; + + +/// String traits for builtin floating-point types. +template struct float_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + // Return a nonnegative integral value's number of decimal digits. + static constexpr std::size_t digits10(std::size_t value) noexcept + { + if (value < 10) + return 1; + else + return 1 + digits10(value / 10); + } + + static constexpr std::size_t size_buffer(T const &) noexcept + { + using lims = std::numeric_limits; + // See #328 for a detailed discussion on the maximum number of digits. + // + // In a nutshell: for the big cases, the scientific notation is always + // the shortest one, and therefore the one that to_chars will pick. + // + // So... How long can the scientific notation get? 1 (for sign) + 1 (for + // decimal point) + 1 (for 'e') + 1 (for exponent sign) + max_digits10 + + // max number of digits in the exponent + 1 (terminating zero). + // + // What's the max number of digits in the exponent? It's the max number of + // digits out of the most negative exponent and the most positive one. + // + // The longest positive exponent is easy: 1 + ceil(log10(max_exponent10)). + // (The extra 1 is because 10^n takes up 1 + n digits, not n.) + // + // The longest negative exponent is a bit harder: min_exponent10 gives us + // the smallest power of 10 which a normalised version of T can represent. + // But the smallest denormalised power of 10 that T can represent is + // another max_digits10 powers of 10 below that. + // needs a minus sign. + // + // All this stuff messes with my head a bit because it's on the order of + // log10(log10(n)). It's easy to get the number of logs wrong. + auto const max_pos_exp{digits10(lims::max_exponent10)}; + // Really want std::abs(lims::min_exponent10), but MSVC 2017 apparently has + // problems with std::abs. So we use -lims::min_exponent10 instead. + auto const max_neg_exp{ + digits10(lims::max_digits10 - lims::min_exponent10)}; + return 1 + // Sign. + 1 + // Decimal point. + std::numeric_limits::max_digits10 + // Mantissa digits. + 1 + // Exponent "e". + 1 + // Exponent sign. + // Spell this weirdly to stop Windows compilers from reading this as + // a call to their "max" macro when NOMINMAX is not defined. + (std::max)(max_pos_exp, max_neg_exp) + // Exponent digits. + 1; // Terminating zero. + } +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// The built-in arithmetic types do not have inherent null values. +template +struct nullness>> : no_null +{}; + + +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct string_traits +{ + static PQXX_LIBEXPORT bool from_string(std::string_view text); + + static constexpr zview to_buf(char *, char *, bool const &value) noexcept + { + return value ? "true"_zv : "false"_zv; + } + + static char *into_buf(char *begin, char *end, bool const &value) + { + return pqxx::internal::generic_into_buf(begin, end, value); + } + + static constexpr std::size_t size_buffer(bool const &) noexcept { return 6; } +}; + + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + /// Technically, you could have an optional of an always-null type. + static constexpr bool always_null = nullness::always_null; + static constexpr bool is_null(std::optional const &v) noexcept + { + return ((not v.has_value()) or pqxx::is_null(*v)); + } + static constexpr std::optional null() { return {}; } +}; + + +template +inline constexpr format param_format(std::optional const &value) +{ + return param_format(*value); +} + + +template struct string_traits> +{ + static char *into_buf(char *begin, char *end, std::optional const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview to_buf(char *begin, char *end, std::optional const &value) + { + if (value.has_value()) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::optional from_string(std::string_view text) + { + return std::optional{ + std::in_place, string_traits::from_string(text)}; + } + + static std::size_t size_buffer(std::optional const &value) noexcept + { + return pqxx::size_buffer(value.value()); + } +}; + + +template +inline constexpr bool is_unquoted_safe>{is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = (nullness::has_null or ...); + static constexpr bool always_null = (nullness::always_null and ...); + static constexpr bool is_null(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { + return nullness>::is_null(i); + }, + value); + } + + // We don't support `null()` for `std::variant`. + /** It would be technically possible to have a `null` in the case where just + * one of the types has a null, but it gets complicated and arbitrary. + */ + static constexpr std::variant null() = delete; +}; + + +template struct string_traits> +{ + static char * + into_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::into_buf(begin, end, i); + }, + value); + } + static zview to_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::to_buf(begin, end, i); + }, + value); + } + static std::size_t size_buffer(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { return pqxx::size_buffer(i); }, value); + } + + /** There's no from_string for std::variant. We could have one with a rule + * like "pick the first type which fits the value," but we'd have to look + * into how natural that API feels to users. + */ + static std::variant from_string(std::string_view) = delete; +}; + + +template +inline constexpr format param_format(std::variant const &value) +{ + return std::visit([](auto &v) { return param_format(v); }, value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + (is_unquoted_safe and ...)}; + + +template inline T from_string(std::stringstream const &text) +{ + return from_string(text.str()); +} + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullptr_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullptr_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullptr_t = nullptr) noexcept + { + return 0; + } + static std::nullptr_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullopt_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullopt_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullopt_t) noexcept + { + return 0; + } + static std::nullopt_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::monostate) = delete; + + static constexpr zview + to_buf(char *, char *, std::monostate const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::monostate) noexcept + { + return 0; + } + static std::monostate from_string(std::string_view) = delete; +}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() noexcept { return nullptr; } +}; + + +/// String traits for C-style string ("pointer to char const"). +template<> struct string_traits +{ + static char const *from_string(std::string_view text) { return text.data(); } + + static zview to_buf(char *begin, char *end, char const *const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, char const *const &value) + { + auto const space{end - begin}; + // Count the trailing zero, even though std::strlen() and friends don't. + auto const len{std::strlen(value) + 1}; + if (space < ptrdiff_t(len)) + throw conversion_overrun{ + "Could not copy string: buffer too small. " + + pqxx::internal::state_buffer_overrun(space, len)}; + std::memmove(begin, value, len); + return begin + len; + } + + static std::size_t size_buffer(char const *const &value) noexcept + { + return std::strlen(value) + 1; + } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() { return nullptr; } +}; + + +/// String traits for non-const C-style string ("pointer to char"). +template<> struct string_traits +{ + static char *into_buf(char *begin, char *end, char *const &value) + { + return string_traits::into_buf(begin, end, value); + } + static zview to_buf(char *begin, char *end, char *const &value) + { + return string_traits::to_buf(begin, end, value); + } + static std::size_t size_buffer(char *const &value) noexcept + { + return string_traits::size_buffer(value); + } + + /// Don't allow conversion to this type since it breaks const-safety. + static char *from_string(std::string_view) = delete; +}; + + +template struct nullness : no_null +{}; + + +/// String traits for C-style string constant ("array of char"). +/** @warning This assumes that every array-of-char is a C-style string literal. + * So, it must include a trailing zero. and it must have static duration. + */ +template struct string_traits +{ + static constexpr zview + to_buf(char *, char *, char const (&value)[N]) noexcept + { + return zview{value, N - 1}; + } + + static char *into_buf(char *begin, char *end, char const (&value)[N]) + { + if (internal::cmp_less(end - begin, size_buffer(value))) + throw conversion_overrun{ + "Could not convert char[] to string: too long for buffer."}; + std::memcpy(begin, value, N); + return begin + N; + } + static constexpr std::size_t size_buffer(char const (&)[N]) noexcept + { + return N; + } + + /// Don't allow conversion to this type. + static void from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::string from_string(std::string_view text) + { + return std::string{text}; + } + + static char *into_buf(char *begin, char *end, std::string const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not convert string to string: too long for buffer."}; + // Include the trailing zero. + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + static zview to_buf(char *begin, char *end, std::string const &value) + { + return generic_to_buf(begin, end, value); + } + + static std::size_t size_buffer(std::string const &value) noexcept + { + return std::size(value) + 1; + } +}; + + +/// There's no real null for `std::string_view`. +/** I'm not sure how clear-cut this is: a `string_view` may have a null + * data pointer, which is analogous to a null `char` pointer. + */ +template<> struct nullness : no_null +{}; + + +/// String traits for `string_view`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, std::string_view const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not store string_view: too long for buffer."}; + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static std::string_view from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +/// String traits for `zview`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, zview const &value) + { + auto const size{std::size(value)}; + if (internal::cmp_less_equal(end - begin, std::size(value))) + throw conversion_overrun{"Not enough buffer space to store this zview."}; + value.copy(begin, size); + begin[size] = '\0'; + return begin + size + 1; + } + + static std::string_view to_buf(char *begin, char *end, zview const &value) + { + return {into_buf(begin, end, value), std::size(value)}; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static zview from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::size_t size_buffer(std::stringstream const &) = delete; + + static std::stringstream from_string(std::string_view text) + { + std::stringstream stream; + stream.write(text.data(), std::streamsize(std::size(text))); + return stream; + } + + static char *into_buf(char *, char *, std::stringstream const &) = delete; + static std::string_view + to_buf(char *, char *, std::stringstream const &) = delete; +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullptr_t const &) noexcept + { + return true; + } + static constexpr std::nullptr_t null() noexcept { return nullptr; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullopt_t const &) noexcept + { + return true; + } + static constexpr std::nullopt_t null() noexcept { return std::nullopt; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::monostate const &) noexcept + { + return true; + } + static constexpr std::monostate null() noexcept { return {}; } +}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::unique_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::unique_ptr null() { return {}; } +}; + + +template +struct string_traits> +{ + static std::unique_ptr from_string(std::string_view text) + { + return std::make_unique(string_traits::from_string(text)); + } + + static char * + into_buf(char *begin, char *end, std::unique_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview + to_buf(char *begin, char *end, std::unique_ptr const &value) + { + if (value) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::size_t + size_buffer(std::unique_ptr const &value) noexcept + { + return pqxx::size_buffer(*value.get()); + } +}; + + +template +inline format param_format(std::unique_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::shared_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::shared_ptr null() { return {}; } +}; + + +template struct string_traits> +{ + static std::shared_ptr from_string(std::string_view text) + { + return std::make_shared(string_traits::from_string(text)); + } + + static zview to_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::to_buf(begin, end, *value); + } + static char * + into_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + static std::size_t size_buffer(std::shared_ptr const &value) noexcept + { + return pqxx::size_buffer(*value); + } +}; + + +template format param_format(std::shared_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template<> +struct nullness> + : no_null> +{}; + + +#if defined(PQXX_HAVE_CONCEPTS) +template struct nullness : no_null +{}; + + +template inline constexpr format param_format(DATA const &) +{ + return format::binary; +} + + +template struct string_traits +{ + static std::size_t size_buffer(DATA const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, DATA const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, DATA const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static DATA from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; +#endif // PQXX_HAVE_CONCEPTS + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview + to_buf(char *begin, char *end, std::basic_string const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::basic_string const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static std::basic_string from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; + + +template<> +inline constexpr format param_format(std::basic_string const &) +{ + return format::binary; +} + + +template<> +struct nullness> + : no_null> +{}; + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string_view const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf( + char *begin, char *end, std::basic_string_view const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf( + char *begin, char *end, std::basic_string_view const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + // There's no from_string, because there's nobody to hold the data. +}; + +template<> +inline constexpr format param_format(std::basic_string_view const &) +{ + return format::binary; +} +} // namespace pqxx + + +namespace pqxx::internal +{ +/// String traits for SQL arrays. +template struct array_string_traits +{ +private: + using elt_type = strip_t>; + using elt_traits = string_traits; + static constexpr zview s_null{"NULL"}; + +public: + static zview to_buf(char *begin, char *end, Container const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, Container const &value) + { + std::size_t const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to convert array to string."}; + + char *here = begin; + *here++ = '{'; + + bool nonempty{false}; + for (auto const &elt : value) + { + if (is_null(elt)) + { + s_null.copy(here, std::size(s_null)); + here += std::size(s_null); + } + else if constexpr (is_sql_array) + { + // Render nested array in-place. Then erase the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else if constexpr (is_unquoted_safe) + { + // No need to quote or escape. Just convert the value straight into + // its place in the array, and "backspace" the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else + { + *here++ = '"'; + + // Use the tail end of the destination buffer as an intermediate + // buffer. + auto const elt_budget{pqxx::size_buffer(elt)}; + for (char const c : elt_traits::to_buf(end - elt_budget, end, elt)) + { + if (c == '\\' or c == '"') + *here++ = '\\'; + *here++ = c; + } + *here++ = '"'; + } + *here++ = array_separator; + nonempty = true; + } + + // Erase that last comma, if present. + if (nonempty) + here--; + + *here++ = '}'; + *here++ = '\0'; + + return here; + } + + static std::size_t size_buffer(Container const &value) noexcept + { + if constexpr (is_unquoted_safe) + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + return acc + + (pqxx::is_null(elt) ? + std::size(s_null) : + elt_traits::size_buffer(elt)) - + 1; + }); + else + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + // Opening and closing quotes, plus worst-case escaping, + // but don't count the trailing zeroes. + std::size_t const elt_size{ + pqxx::is_null(elt) ? std::size(s_null) : + elt_traits::size_buffer(elt) - 1}; + return acc + 2 * elt_size + 2; + }); + } + + // We don't yet support parsing of array types using from_string. Doing so + // would require a reference to the connection. +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::vector const &) +{ + return format::text; +} + + +/// A `std::vector` is a binary string. Other vectors are not. +template +inline constexpr format param_format(std::vector const &) +{ + return format::binary; +} + + +template inline constexpr bool is_sql_array>{true}; + + +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::array const &) +{ + return format::text; +} + + +/// An array of `std::byte` is a binary string. +template +inline constexpr format param_format(std::array const &) +{ + return format::binary; +} + + +template +inline constexpr bool is_sql_array>{true}; +} // namespace pqxx + + +namespace pqxx +{ +template inline std::string to_string(T const &value) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + std::string buf; + // We can't just reserve() space; modifying the terminating zero leads to + // undefined behaviour. + buf.resize(size_buffer(value)); + auto const data{buf.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(buf), value)}; + buf.resize(static_cast(end - data - 1)); + return buf; +} + + +template<> inline std::string to_string(float const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(long double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(std::stringstream const &value) +{ + return value.str(); +} + + +template inline void into_string(T const &value, std::string &out) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + // We can't just reserve() data; modifying the terminating zero leads to + // undefined behaviour. + out.resize(size_buffer(value) + 1); + auto const data{out.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(out), value)}; + out.resize(static_cast(end - data - 1)); +} +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx new file mode 100644 index 0000000..e17736e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/encoding_group.hxx @@ -0,0 +1,60 @@ +/** Enum type for supporting encodings in libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODING_GROUP +#define PQXX_H_ENCODING_GROUP + +#include + +namespace pqxx::internal +{ +// Types of encodings supported by PostgreSQL, see +// https://www.postgresql.org/docs/current/static/multibyte.html#CHARSET-TABLE +enum class encoding_group +{ + // Handles all single-byte fixed-width encodings + MONOBYTE, + + // Multibyte encodings. + // Many of these can embed ASCII-like bytes inside multibyte characters, + // notably Big5, SJIS, SHIFT_JIS_2004, GP18030, GBK, JOHAB, UHC. + BIG5, + EUC_CN, + // TODO: Merge EUC_JP and EUC_JIS_2004? + EUC_JP, + EUC_JIS_2004, + EUC_KR, + EUC_TW, + GB18030, + GBK, + JOHAB, + MULE_INTERNAL, + // TODO: Merge SJIS and SHIFT_JIS_2004? + SJIS, + SHIFT_JIS_2004, + UHC, + UTF8, +}; + + +// TODO:: Can we just use string_view now? +/// Function type: "find the end of the current glyph." +/** This type of function takes a text buffer, and a location in that buffer, + * and returns the location one byte past the end of the current glyph. + * + * The start offset marks the beginning of the current glyph. It must fall + * within the buffer. + * + * There are multiple different glyph scanner implementations, for different + * kinds of encodings. + */ +using glyph_scanner_func = + std::size_t(char const buffer[], std::size_t buffer_len, std::size_t start); +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx new file mode 100644 index 0000000..ba7fecc --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/encodings.hxx @@ -0,0 +1,90 @@ +/** Internal string encodings support for libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODINGS +#define PQXX_H_ENCODINGS + +#include "pqxx/internal/encoding_group.hxx" + +#include +#include + + +namespace pqxx::internal +{ +char const *name_encoding(int encoding_id); + +/// Convert libpq encoding enum or encoding name to its libpqxx group. +encoding_group enc_group(int /* libpq encoding ID */); +encoding_group enc_group(std::string_view); + + +/// Look up the glyph scanner function for a given encoding group. +/** To identify the glyph boundaries in a buffer, call this to obtain the + * scanner function appropriate for the buffer's encoding. Then, repeatedly + * call the scanner function to find the glyphs. + */ +PQXX_LIBEXPORT glyph_scanner_func *get_glyph_scanner(encoding_group); + + +// TODO: For ASCII search, treat UTF8/EUC_*/MULE_INTERNAL as MONOBYTE. + +/// Find any of the ASCII characters `NEEDLE` in `haystack`. +/** Scans through `haystack` until it finds a single-byte character that + * matches any value in `NEEDLE`. + * + * If it finds one, returns its offset. If not, returns the end of the + * haystack. + */ +template +inline std::size_t find_char( + glyph_scanner_func *scanner, std::string_view haystack, + std::size_t here = 0u) +{ + auto const sz{std::size(haystack)}; + auto const data{std::data(haystack)}; + while (here < sz) + { + auto next{scanner(data, sz, here)}; + // (For some reason gcc had a problem with a right-fold here. But clang + // was fine.) + if ((... or (data[here] == NEEDLE))) + { + // Also check against a multibyte character starting with a bytes which + // just happens to match one of the ASCII bytes we're looking for. It'd + // be cleaner to check that first, but either works. So, let's apply the + // most selective filter first and skip this check in almost all cases. + if (next == here + 1) + return here; + } + + // Nope, no hit. Move on. + here = next; + } + return sz; +} + + +/// Iterate over the glyphs in a buffer. +/** Scans the glyphs in the buffer, and for each, passes its begin and its + * one-past-end pointers to `callback`. + */ +template +inline void for_glyphs( + encoding_group enc, CALLABLE callback, char const buffer[], + std::size_t buffer_len, std::size_t start = 0) +{ + auto const scan{get_glyph_scanner(enc)}; + for (std::size_t here = start, next; here < buffer_len; here = next) + { + next = scan(buffer, buffer_len, here); + callback(buffer + here, buffer + next); + } +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx new file mode 100644 index 0000000..ffc12a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-errorhandler.hxx @@ -0,0 +1,26 @@ +#include + +namespace pqxx +{ +class connection; +class errorhandler; +} // namespace pqxx + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_errorhandler : callgate +{ + friend class pqxx::errorhandler; + + connection_errorhandler(reference x) : super(x) {} + + void register_errorhandler(errorhandler *h) + { + home().register_errorhandler(h); + } + void unregister_errorhandler(errorhandler *h) + { + home().unregister_errorhandler(h); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx new file mode 100644 index 0000000..49feaf9 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-largeobject.hxx @@ -0,0 +1,35 @@ +#include + +#include +#include + +namespace pqxx +{ +class blob; +class largeobject; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + connection_largeobject(reference x) : super(x) {} + + pq::PGconn *raw_connection() const { return home().raw_connection(); } +}; + + +class PQXX_PRIVATE const_connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + const_connection_largeobject(reference x) : super(x) {} + + std::string error_message() const { return home().err_msg(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx new file mode 100644 index 0000000..0bcb2db --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-notification_receiver.hxx @@ -0,0 +1,29 @@ +#include + +#include "pqxx/connection.hxx" + + +namespace pqxx +{ +class notification_receiver; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_notification_receiver : callgate +{ + friend class pqxx::notification_receiver; + + connection_notification_receiver(reference x) : super(x) {} + + void add_receiver(notification_receiver *receiver) + { + home().add_receiver(receiver); + } + void remove_receiver(notification_receiver *receiver) noexcept + { + home().remove_receiver(receiver); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx new file mode 100644 index 0000000..c6ae6e1 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-pipeline.hxx @@ -0,0 +1,23 @@ +#include "pqxx/internal/libpq-forward.hxx" +#include + +#include "pqxx/pipeline.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_pipeline : callgate +{ + friend class pqxx::pipeline; + + connection_pipeline(reference x) : super(x) {} + + void start_exec(char const query[]) { home().start_exec(query); } + pqxx::internal::pq::PGresult *get_result() { return home().get_result(); } + void cancel_query() { home().cancel_query(); } + + bool consume_input() noexcept { return home().consume_input(); } + bool is_busy() const noexcept { return home().is_busy(); } + + int encoding_id() { return home().encoding_id(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx new file mode 100644 index 0000000..51a8898 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-sql_cursor.hxx @@ -0,0 +1,19 @@ +#include + +namespace pqxx::internal +{ +class sql_cursor; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + connection_sql_cursor(reference x) : super(x) {} + + result exec(char const query[]) { return home().exec(query); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx new file mode 100644 index 0000000..8961e71 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_from.hxx @@ -0,0 +1,15 @@ +#include + +#include "pqxx/connection.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_from : callgate +{ + friend class pqxx::stream_from; + + connection_stream_from(reference x) : super{x} {} + + auto read_copy_line() { return home().read_copy_line(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx new file mode 100644 index 0000000..a6974fb --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-stream_to.hxx @@ -0,0 +1,17 @@ +#include + +#include "pqxx/stream_to.hxx" + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_to : callgate +{ + friend class pqxx::stream_to; + + connection_stream_to(reference x) : super(x) {} + + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx new file mode 100644 index 0000000..74d6592 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/connection-transaction.hxx @@ -0,0 +1,44 @@ +#include + +namespace pqxx +{ +class connection; +} + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_transaction : callgate +{ + friend class pqxx::transaction_base; + + connection_transaction(reference x) : super(x) {} + + template result exec(STRING query, std::string_view desc) + { + return home().exec(query, desc); + } + + void register_transaction(transaction_base *t) + { + home().register_transaction(t); + } + void unregister_transaction(transaction_base *t) noexcept + { + home().unregister_transaction(t); + } + + auto read_copy_line() { return home().read_copy_line(); } + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } + + result exec_prepared(zview statement, internal::c_params const &args) + { + return home().exec_prepared(statement, args); + } + + result exec_params(zview query, internal::c_params const &args) + { + return home().exec_params(query, args); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx new file mode 100644 index 0000000..5560ced --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/errorhandler-connection.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE errorhandler_connection : callgate +{ + friend class pqxx::connection; + + errorhandler_connection(reference x) : super(x) {} + + void unregister() noexcept { home().unregister(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx new file mode 100644 index 0000000..296d221 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursor_iterator_icursorstream : callgate +{ + friend class pqxx::icursorstream; + + icursor_iterator_icursorstream(reference x) : super(x) {} + + icursor_iterator::difference_type pos() const noexcept + { + return home().pos(); + } + + icursor_iterator *get_prev() { return home().m_prev; } + void set_prev(icursor_iterator *i) { home().m_prev = i; } + + icursor_iterator *get_next() { return home().m_next; } + void set_next(icursor_iterator *i) { home().m_next = i; } + + void fill(result const &r) { home().fill(r); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx new file mode 100644 index 0000000..56056d5 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx @@ -0,0 +1,32 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursorstream_icursor_iterator : callgate +{ + friend class pqxx::icursor_iterator; + + icursorstream_icursor_iterator(reference x) : super(x) {} + + void insert_iterator(icursor_iterator *i) noexcept + { + home().insert_iterator(i); + } + + void remove_iterator(icursor_iterator *i) const noexcept + { + home().remove_iterator(i); + } + + icursorstream::size_type forward() { return home().forward(); } + icursorstream::size_type forward(icursorstream::size_type n) + { + return home().forward(n); + } + + void service_iterators(icursorstream::difference_type p) + { + home().service_iterators(p); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx new file mode 100644 index 0000000..daa0808 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-connection.hxx @@ -0,0 +1,14 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_connection : callgate +{ + friend class pqxx::connection; + + result_connection(reference x) : super(x) {} + + operator bool() const { return bool(home()); } + bool operator!() const { return not home(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx new file mode 100644 index 0000000..3d9205f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-creation.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_creation : callgate +{ + friend class pqxx::connection; + friend class pqxx::pipeline; + + result_creation(reference x) : super(x) {} + + static result create( + internal::pq::PGresult *rhs, std::shared_ptr const &query, + encoding_group enc) + { + return result(rhs, query, enc); + } + + void check_status(std::string_view desc = ""sv) const + { + return home().check_status(desc); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx new file mode 100644 index 0000000..3ebe436 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-pipeline.hxx @@ -0,0 +1,16 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_pipeline : callgate +{ + friend class pqxx::pipeline; + + result_pipeline(reference x) : super(x) {} + + std::shared_ptr query_ptr() const + { + return home().query_ptr(); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx new file mode 100644 index 0000000..78b4507 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/result-sql_cursor.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + result_sql_cursor(reference x) : super(x) {} + + char const *cmd_status() const noexcept { return home().cmd_status(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx new file mode 100644 index 0000000..4ed78dc --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-sql_cursor.hxx @@ -0,0 +1,10 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + transaction_sql_cursor(reference x) : super(x) {} +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx new file mode 100644 index 0000000..ca7939a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/gates/transaction-transaction_focus.hxx @@ -0,0 +1,30 @@ +#include + +#include "pqxx/transaction_base.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_transaction_focus : callgate +{ + friend class pqxx::transaction_focus; + + transaction_transaction_focus(reference x) : super(x) {} + + void register_focus(transaction_focus *focus) + { + home().register_focus(focus); + } + void unregister_focus(transaction_focus *focus) noexcept + { + home().unregister_focus(focus); + } + void register_pending_error(zview error) + { + home().register_pending_error(error); + } + void register_pending_error(std::string &&error) + { + home().register_pending_error(std::move(error)); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx new file mode 100644 index 0000000..ff6bf89 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/header-post.hxx @@ -0,0 +1,22 @@ +/* Compiler deficiency workarounds for compiling libpqxx headers. + * + * To be included at the end of each libpqxx header, in order to restore the + * client program's settings. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +// NO GUARDS HERE! This code should be executed every time! + +#if defined(_MSC_VER) +# pragma warning(pop) // Restore compiler's warning state +#endif + +#if !defined(PQXX_HEADER_PRE) +# error "Include pqxx/internal/header-post.hxx AFTER its 'pre' counterpart." +#endif + +#undef PQXX_HEADER_PRE diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx new file mode 100644 index 0000000..abc1a39 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/header-pre.hxx @@ -0,0 +1,169 @@ +/* Compiler settings for compiling libpqxx headers, and workarounds for all. + * + * Include this before including any other libpqxx headers from within libpqxx. + * And to balance it out, also include header-post.hxx at the end of the batch + * of headers. + * + * The public libpqxx headers (e.g. ``) include this already; + * there's no need to do this from within an application. + * + * Include this file at the highest aggregation level possible to avoid nesting + * and to keep things simple. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ + +// NO GUARD HERE! This part should be included every time this file is. +#if defined(_MSC_VER) + +// Save compiler's warning state, and set warning level 4 for maximum +// sensitivity to warnings. +# pragma warning(push, 4) + +// Visual C++ generates some entirely unreasonable warnings. Disable them. +// Copy constructor could not be generated. +# pragma warning(disable : 4511) +// Assignment operator could not be generated. +# pragma warning(disable : 4512) +// Can't expose outside classes without exporting them. Except the MSVC docs +// say please ignore the warning if it's a standard library class. +# pragma warning(disable : 4251) +// Can't derive library classes from outside classes without exporting them. +// Except the MSVC docs say please ignore the warning if the parent class is +// in the standard library. +# pragma warning(disable : 4275) +// Can't inherit from non-exported class. +# pragma warning(disable : 4275) + +#endif // _MSC_VER + + +#if defined(PQXX_HEADER_PRE) +# error "Avoid nesting #include of pqxx/internal/header-pre.hxx." +#endif + +#define PQXX_HEADER_PRE + + +// Workarounds & definitions that need to be included even in library's headers +#include "pqxx/config-public-compiler.h" + +// Enable ISO-646 alternative operaotr representations: "and" instead of "&&" +// etc. on older compilers. C++20 removes this header. +#if __has_include() +# include +#endif + + +#if defined(PQXX_HAVE_GCC_PURE) +/// Declare function "pure": no side effects, only reads globals and its args. +# define PQXX_PURE __attribute__((pure)) +#else +# define PQXX_PURE /* pure */ +#endif + + +#if defined(__GNUC__) +/// Tell the compiler to optimise a function for size, not speed. +# define PQXX_COLD __attribute__((cold)) +#else +# define PQXX_COLD /* cold */ +#endif + + +// Workarounds for Windows +#ifdef _WIN32 + +/* For now, export DLL symbols if _DLL is defined. This is done automatically + * by the compiler when linking to the dynamic version of the runtime library, + * according to "gzh" + */ +# if defined(PQXX_SHARED) && !defined(PQXX_LIBEXPORT) +# define PQXX_LIBEXPORT __declspec(dllimport) +# endif // PQXX_SHARED && !PQXX_LIBEXPORT + + +// Workarounds for Microsoft Visual C++ +# ifdef _MSC_VER + +// Suppress vtables on abstract classes. +# define PQXX_NOVTABLE __declspec(novtable) + +// Automatically link with the appropriate libpq (static or dynamic, debug or +// release). The default is to use the release DLL. Define PQXX_PQ_STATIC to +// link to a static version of libpq, and _DEBUG to link to a debug version. +// The two may be combined. +# if defined(PQXX_AUTOLINK) +# if defined(PQXX_PQ_STATIC) +# ifdef _DEBUG +# pragma comment(lib, "libpqd") +# else +# pragma comment(lib, "libpq") +# endif +# else +# ifdef _DEBUG +# pragma comment(lib, "libpqddll") +# else +# pragma comment(lib, "libpqdll") +# endif +# endif +# endif + +// If we're not compiling libpqxx itself, automatically link with the +// appropriate libpqxx library. To link with the libpqxx DLL, define +// PQXX_SHARED; the default is to link with the static library. A static link +// is the recommended practice. +// +// The preprocessor macro PQXX_INTERNAL is used to detect whether we +// are compiling the libpqxx library itself. When you compile the library +// yourself using your own project file, make sure to include this macro. +# if defined(PQXX_AUTOLINK) && !defined(PQXX_INTERNAL) +# ifdef PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxxD") +# else +# pragma comment(lib, "libpqxx") +# endif +# else // !PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxx_staticD") +# else +# pragma comment(lib, "libpqxx_static") +# endif +# endif +# endif + +# endif // _MSC_VER + +#elif defined(PQXX_HAVE_GCC_VISIBILITY) // !_WIN32 + +# define PQXX_LIBEXPORT __attribute__((visibility("default"))) +# define PQXX_PRIVATE __attribute__((visibility("hidden"))) + +#endif // PQXX_HAVE_GCC_VISIBILITY + + +#ifndef PQXX_LIBEXPORT +# define PQXX_LIBEXPORT /* libexport */ +#endif + +#ifndef PQXX_PRIVATE +# define PQXX_PRIVATE /* private */ +#endif + +#ifndef PQXX_NOVTABLE +# define PQXX_NOVTABLE /* novtable */ +#endif + +// C++20: Assume support. +#if defined(PQXX_HAVE_LIKELY) +# define PQXX_LIKELY [[likely]] +# define PQXX_UNLIKELY [[unlikely]] +#else +# define PQXX_LIKELY /* [[likely]] */ +# define PQXX_UNLIKELY /* [[unlikely]] */ +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx new file mode 100644 index 0000000..cebcf05 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-post.hxx @@ -0,0 +1,15 @@ +/// End a code block started by "ignore-deprecated-pre.hxx". + +#if !defined(PQXX_IGNORING_DEPRECATED) +# error "Ended an 'ignore-deprecated' block while none was active." +#endif + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#undef PQXX_IGNORING_DEPRECATED diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx new file mode 100644 index 0000000..8ac57af --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/ignore-deprecated-pre.hxx @@ -0,0 +1,28 @@ +/** Start a block of deprecated code which may call other deprecated code. + * + * Most compilers will emit warnings when deprecated code is invoked from + * non-deprecated code. But some compilers (notably gcc) will always emit the + * warning even when the calling code is also deprecated. + * + * This header starts a block where those warnings are suppressed. It can be + * included inside a code block. + * + * Always match the #include with a closing #include of + * "ignore-deprecated-post.hxx". To avoid mistakes, keep the enclosed area as + * small as possible. + */ +#if defined(PQXX_IGNORING_DEPRECATED) +# error "Started an 'ignore-deprecated' block inside another." +#endif + +#define PQXX_IGNORING_DEPRECATED + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4996) +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx new file mode 100644 index 0000000..9e74f79 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/libpq-forward.hxx @@ -0,0 +1,31 @@ +/** Minimal forward declarations of libpq types needed in libpqxx headers. + * + * DO NOT INCLUDE THIS FILE when building client programs. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +extern "C" +{ + struct pg_conn; + struct pg_result; + struct pgNotify; +} + +/// Forward declarations of libpq types as needed in libpqxx headers. +namespace pqxx::internal::pq +{ +using PGconn = pg_conn; +using PGresult = pg_result; +using PGnotify = pgNotify; +using PQnoticeProcessor = void (*)(void *, char const *); +} // namespace pqxx::internal::pq + +namespace pqxx +{ +/// PostgreSQL database row identifier. +using oid = unsigned int; +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx new file mode 100644 index 0000000..1fa1f7d --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/result_iter.hxx @@ -0,0 +1,124 @@ +/** Result loops. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITER +#define PQXX_H_RESULT_ITER + +#include + +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class result; +} // namespace pqxx + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Iterator for looped unpacking of a result. +template class result_iter +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + result_iter() = default; + + explicit result_iter(result const &home) : + m_home{&home}, m_size{std::size(home)} + { + if (not std::empty(home)) + read(); + } + result_iter(result_iter const &) = default; + + result_iter &operator++() + { + m_index++; + if (m_index >= m_size) + m_home = nullptr; + else + read(); + return *this; + } + + /// Comparison only works for comparing to end(). + bool operator==(result_iter const &rhs) const + { + return m_home == rhs.m_home; + } + bool operator!=(result_iter const &rhs) const { return not(*this == rhs); } + + value_type const &operator*() const { return m_value; } + +private: + void read() { (*m_home)[m_index].convert(m_value); } + + result const *m_home{nullptr}; + result::size_type m_index{0}; + result::size_type m_size; + value_type m_value; +}; + + +template class result_iteration +{ +public: + using iterator = result_iter; + explicit result_iteration(result const &home) : m_home{home} + { + constexpr auto tup_size{sizeof...(TYPE)}; + if (home.columns() != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", to_string(tup_size), + " field(s) from a result with ", to_string(home.columns()), + " column(s).")}; + } + iterator begin() const + { + if (std::size(m_home) == 0) + return end(); + else + return iterator{m_home}; + } + iterator end() const { return {}; } + +private: + pqxx::result const &m_home; +}; +} // namespace pqxx::internal + + +template inline auto pqxx::result::iter() const +{ + return pqxx::internal::result_iteration{*this}; +} + + +template +inline void pqxx::result::for_each(CALLABLE &&func) const +{ + using args_tuple = internal::args_t; + constexpr auto sz{std::tuple_size_v}; + static_assert( + sz > 0, + "Callback for for_each must take parameters, one for each column in the " + "result."); + + auto const cols{this->columns()}; + if (sz != cols) + throw usage_error{internal::concat( + "Callback to for_each takes ", sz, "parameter", (sz == 1) ? "" : "s", + ", but result set has ", cols, "field", (cols == 1) ? "" : "s", ".")}; + + using pass_tuple = pqxx::internal::strip_types_t; + for (auto const r : *this) std::apply(func, r.as_tuple()); +} +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx new file mode 100644 index 0000000..3f27a1d --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/result_iterator.hxx @@ -0,0 +1,389 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITERATOR +#define PQXX_H_RESULT_ITERATOR + +#include "pqxx/row.hxx" + + +/* Result iterator. + * + * Don't include this header from your own application; it is included for you + * by other libpqxx headers. + */ + +namespace pqxx +{ +/// Iterator for rows in a result. Use as result::const_iterator. +/** A result, once obtained, cannot be modified. Therefore there is no + * plain iterator type for result. However its const_iterator type can be + * used to inspect its rows without changing them. + */ +class PQXX_LIBEXPORT const_result_iterator : public row +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = row const; + using pointer = row const *; + using reference = row; + using size_type = result_size_type; + using difference_type = result_difference_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create an iterator, but in an unusable state. + const_result_iterator() noexcept = default; + /// Copy an iterator. + const_result_iterator(const_result_iterator const &) noexcept = default; + /// Move an iterator. + const_result_iterator(const_result_iterator &&) noexcept = default; + + /// Begin iterating a @ref row. + const_result_iterator(row const &t) noexcept : row{t} {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /** + * @name Dereferencing operators + * + * An iterator "points to" its own row, which is also itself. This makes it + * easy to address a @ref result as a two-dimensional container, without + * going through the intermediate step of dereferencing the iterator. It + * makes the interface similar to C pointer/array semantics. + * + * IIRC Alex Stepanov, the inventor of the STL, once remarked that having + * this as standard behaviour for pointers would be useful in some + * algorithms. So even if this makes me look foolish, I would seem to be in + * distinguished company. + */ + //@{ + /// Dereference the iterator. + [[nodiscard]] pointer operator->() const { return this; } + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Dereference the iterator. + [[nodiscard]] reference operator*() const { return *this; } +#include "pqxx/internal/ignore-deprecated-post.hxx" + //@} + + /** + * @name Field access + */ + //@{ + using row::back; + using row::front; + using row::operator[]; + using row::at; + using row::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_result_iterator &operator=(const_result_iterator const &rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(rhs); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator &operator=(const_result_iterator &&rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(std::move(rhs)); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator operator++(int); + const_result_iterator &operator++() + { + ++m_index; + return *this; + } + const_result_iterator operator--(int); + const_result_iterator &operator--() + { + --m_index; + return *this; + } + + const_result_iterator &operator+=(difference_type i) + { + m_index += i; + return *this; + } + const_result_iterator &operator-=(difference_type i) + { + m_index -= i; + return *this; + } + + /// Interchange two iterators in an exception-safe manner. + void swap(const_result_iterator &other) noexcept + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::swap(other); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool operator==(const_result_iterator const &i) const + { + return m_index == i.m_index; + } + [[nodiscard]] bool operator!=(const_result_iterator const &i) const + { + return m_index != i.m_index; + } + [[nodiscard]] bool operator<(const_result_iterator const &i) const + { + return m_index < i.m_index; + } + [[nodiscard]] bool operator<=(const_result_iterator const &i) const + { + return m_index <= i.m_index; + } + [[nodiscard]] bool operator>(const_result_iterator const &i) const + { + return m_index > i.m_index; + } + [[nodiscard]] bool operator>=(const_result_iterator const &i) const + { + return m_index >= i.m_index; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_result_iterator operator+(difference_type) const; + friend const_result_iterator + operator+(difference_type, const_result_iterator const &); + [[nodiscard]] inline const_result_iterator operator-(difference_type) const; + [[nodiscard]] inline difference_type + operator-(const_result_iterator const &) const; + //@} + +private: + friend class pqxx::result; + const_result_iterator(pqxx::result const *r, result_size_type i) noexcept : + row{*r, i, r->columns()} + {} +}; + + +/// Reverse iterator for result. Use as result::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_result_iterator + : private const_result_iterator +{ +public: + using super = const_result_iterator; + using iterator_type = const_result_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + /// Create an iterator, but in an unusable state. + const_reverse_result_iterator() = default; + /// Copy an iterator. + const_reverse_result_iterator(const_reverse_result_iterator const &rhs) = + default; + /// Copy a reverse iterator from a regular iterator. + explicit const_reverse_result_iterator(const_result_iterator const &rhs) : + const_result_iterator{rhs} + { + super::operator--(); + } + + /// Move a regular iterator into a reverse iterator. + explicit const_reverse_result_iterator(const_result_iterator const &&rhs) : + const_result_iterator{std::move(rhs)} + { + super::operator--(); + } + + /// Return the underlying "regular" iterator (as per standard library). + [[nodiscard]] PQXX_PURE const_result_iterator base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + /// Dereference iterator. + using const_result_iterator::operator->; + /// Dereference iterator. + using const_result_iterator::operator*; + //@} + + /** + * @name Field access + */ + //@{ + using const_result_iterator::back; + using const_result_iterator::front; + using const_result_iterator::operator[]; + using const_result_iterator::at; + using const_result_iterator::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_result_iterator & + operator=(const_reverse_result_iterator const &r) + { + iterator_type::operator=(r); + return *this; + } + const_reverse_result_iterator &operator=(const_reverse_result_iterator &&r) + { + iterator_type::operator=(std::move(r)); + return *this; + } + const_reverse_result_iterator &operator++() + { + iterator_type::operator--(); + return *this; + } + const_reverse_result_iterator operator++(int); + const_reverse_result_iterator &operator--() + { + iterator_type::operator++(); + return *this; + } + const_reverse_result_iterator operator--(int); + const_reverse_result_iterator &operator+=(difference_type i) + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_result_iterator &operator-=(difference_type i) + { + iterator_type::operator+=(i); + return *this; + } + + void swap(const_reverse_result_iterator &other) noexcept + { + const_result_iterator::swap(other); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_result_iterator + operator+(difference_type i) const + { + return const_reverse_result_iterator(base() - i); + } + [[nodiscard]] const_reverse_result_iterator operator-(difference_type i) + { + return const_reverse_result_iterator(base() + i); + } + [[nodiscard]] difference_type + operator-(const_reverse_result_iterator const &rhs) const + { + return rhs.const_result_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_result_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_result_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + + [[nodiscard]] bool operator<(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] bool operator<=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] bool operator>(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] bool operator>=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +inline const_result_iterator +const_result_iterator::operator+(result::difference_type o) const +{ + return {&m_result, size_type(result::difference_type(m_index) + o)}; +} + +inline const_result_iterator +operator+(result::difference_type o, const_result_iterator const &i) +{ + return i + o; +} + +inline const_result_iterator +const_result_iterator::operator-(result::difference_type o) const +{ + return {&m_result, result_size_type(result::difference_type(m_index) - o)}; +} + +inline result::difference_type +const_result_iterator::operator-(const const_result_iterator &i) const +{ + return result::difference_type(num() - i.num()); +} + +inline const_result_iterator result::end() const noexcept +{ + return {this, size()}; +} + + +inline const_result_iterator result::cend() const noexcept +{ + return end(); +} + + +inline const_reverse_result_iterator +operator+(result::difference_type n, const_reverse_result_iterator const &i) +{ + return const_reverse_result_iterator{i.base() - n}; +} + +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx new file mode 100644 index 0000000..a26d063 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/sql_cursor.hxx @@ -0,0 +1,118 @@ +/** Internal wrapper for SQL cursors. Supports higher-level cursor classes. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SQL_CURSOR +#define PQXX_H_SQL_CURSOR + +namespace pqxx::internal +{ +/// Cursor with SQL positioning semantics. +/** Thin wrapper around an SQL cursor, with SQL's ideas of positioning. + * + * SQL cursors have pre-increment/pre-decrement semantics, with on either end + * of the result set a special position that does not repesent a row. This + * class models SQL cursors for the purpose of implementing more C++-like + * semantics on top. + * + * Positions of actual rows are numbered starting at 1. Position 0 exists but + * does not refer to a row. There is a similar non-row position at the end of + * the result set. + * + * Don't use this at home. You deserve better. Use the stateles_cursor + * instead. + */ +class PQXX_LIBEXPORT sql_cursor : public cursor_base +{ +public: + sql_cursor( + transaction_base &t, std::string_view query, std::string_view cname, + cursor_base::access_policy ap, cursor_base::update_policy up, + cursor_base::ownership_policy op, bool hold); + + sql_cursor( + transaction_base &t, std::string_view cname, + cursor_base::ownership_policy op); + + ~sql_cursor() noexcept { close(); } + + result fetch(difference_type rows, difference_type &displacement); + result fetch(difference_type rows) + { + difference_type d = 0; + return fetch(rows, d); + } + difference_type move(difference_type rows, difference_type &displacement); + difference_type move(difference_type rows) + { + difference_type d = 0; + return move(rows, d); + } + + /// Current position, or -1 for unknown + /** + * The starting position, just before the first row, counts as position zero. + * + * Position may be unknown if (and only if) this cursor was adopted, and has + * never hit its starting position (position zero). + */ + difference_type pos() const noexcept { return m_pos; } + + /// End position, or -1 for unknown + /** + * Returns the final position, just after the last row in the result set. The + * starting position, just before the first row, counts as position zero. + * + * End position is unknown until it is encountered during use. + */ + difference_type endpos() const noexcept { return m_endpos; } + + /// Return zero-row result for this cursor. + result const &empty_result() const noexcept { return m_empty_result; } + + void close() noexcept; + +private: + difference_type adjust(difference_type hoped, difference_type actual); + static std::string stridestring(difference_type); + /// Initialize cached empty result. Call only at beginning or end! + void init_empty_result(transaction_base &); + + /// Connection in which this cursor lives. + connection &m_home; + + /// Zero-row result from this cursor (or plain empty one if cursor is + /// adopted) + result m_empty_result; + + result m_cached_current_row; + + /// Is this cursor adopted (as opposed to created by this cursor object)? + bool m_adopted; + + /// Will this cursor object destroy its SQL cursor when it dies? + cursor_base::ownership_policy m_ownership; + + /// At starting position (-1), somewhere in the middle (0), or past end (1) + int m_at_end; + + /// Position, or -1 for unknown + difference_type m_pos; + + /// End position, or -1 for unknown + difference_type m_endpos = -1; +}; + + +PQXX_LIBEXPORT result_size_type obtain_stateless_cursor_size(sql_cursor &); +PQXX_LIBEXPORT result stateless_cursor_retrieve( + sql_cursor &, result::difference_type size, + result::difference_type begin_pos, result::difference_type end_pos); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx new file mode 100644 index 0000000..b078bf6 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/statement_parameters.hxx @@ -0,0 +1,131 @@ +/** Common implementation for statement parameter lists. + * + * These are used for both prepared statements and parameterized statements. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STATEMENT_PARAMETER +#define PQXX_H_STATEMENT_PARAMETER + +#include +#include +#include +#include +#include + +#include "pqxx/binarystring.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/util.hxx" + + +namespace pqxx::internal +{ +template +constexpr inline auto const iterator_identity{ + [](decltype(*std::declval()) x) { return x; }}; + + +/// Marker type: pass a dynamically-determined number of statement parameters. +/** @deprecated Use @ref params instead. + * + * Normally when invoking a prepared or parameterised statement, the number + * of parameters is known at compile time. For instance, + * `t.exec_prepared("foo", 1, "x");` executes statement `foo` with two + * parameters, an `int` and a C string. + * + * But sometimes you may want to pass a number of parameters known only at run + * time. In those cases, a @ref dynamic_params encodes a dynamically + * determined number of parameters. You can mix these with regular, static + * parameter lists, and you can re-use them for multiple statement invocations. + * + * A dynamic_params object does not store copies of its parameters, so make + * sure they remain accessible until you've executed the statement. + * + * The ACCESSOR is an optional callable (such as a lambda). If you pass an + * accessor `a`, then each parameter `p` goes into your statement as `a(p)`. + */ +template)> +class dynamic_params +{ +public: + /// Wrap a sequence of pointers or iterators. + constexpr dynamic_params(IT begin, IT end) : + m_begin(begin), m_end(end), m_accessor(iterator_identity) + {} + + /// Wrap a sequence of pointers or iterators. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + constexpr dynamic_params(IT begin, IT end, ACCESSOR &acc) : + m_begin(begin), m_end(end), m_accessor(acc) + {} + + /// Wrap a container. + template + explicit constexpr dynamic_params(C &container) : + dynamic_params(std::begin(container), std::end(container)) + {} + + /// Wrap a container. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + template + explicit constexpr dynamic_params(C &container, ACCESSOR &acc) : + dynamic_params(std::begin(container), std::end(container), acc) + {} + + constexpr IT begin() const noexcept { return m_begin; } + constexpr IT end() const noexcept { return m_end; } + + constexpr auto access(decltype(*std::declval()) value) const + -> decltype(std::declval()(value)) + { + return m_accessor(value); + } + +private: + IT const m_begin, m_end; + ACCESSOR m_accessor = iterator_identity; +}; + + +/// Internal type: encode statement parameters. +/** Compiles arguments for prepared statements and parameterised queries into + * a format that can be passed into libpq. + * + * Objects of this type are meant to be short-lived: a `c_params` lives and + * dies entirely within the call to execute. So, for example, if you pass in a + * non-null pointer as a parameter, @ref params may simply use that pointer as + * a parameter value, without arranging longer-term storage for the data to + * which it points. All values referenced by parameters must remain "live" + * until the parameterised or prepared statement has been executed. + */ +struct PQXX_LIBEXPORT c_params +{ + c_params() = default; + /// Copying these objects is pointless and expensive. Don't do it. + c_params(c_params const &) = delete; + c_params(c_params &&) = default; + + /// Pre-allocate storage for `n` parameters. + void reserve(std::size_t n) &; + + /// As used by libpq: pointers to parameter values. + std::vector values; + /// As used by libpq: lengths of non-null arguments, in bytes. + std::vector lengths; + /// As used by libpq: effectively boolean "is this a binary parameter?" + std::vector formats; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx new file mode 100644 index 0000000..f240dcf --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/stream_iterator.hxx @@ -0,0 +1,105 @@ +/** Stream iterators. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_ITERATOR +#define PQXX_H_STREAM_ITERATOR + +#include + +namespace pqxx +{ +class stream_from; +} + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Input iterator for stream_from. +/** Just barely enough to support range-based "for" loops. Don't assume that + * any of the usual behaviour works beyond that. + */ +template class stream_input_iterator +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + stream_input_iterator() = default; + + explicit stream_input_iterator(stream_from &home) : m_home(&home) + { + advance(); + } + stream_input_iterator(stream_input_iterator const &) = default; + + stream_input_iterator &operator++() + { + advance(); + return *this; + } + + value_type const &operator*() const { return m_value; } + + /// Comparison only works for comparing to end(). + bool operator==(stream_input_iterator const &rhs) const + { + return m_home == rhs.m_home; + } + /// Comparison only works for comparing to end(). + bool operator!=(stream_input_iterator const &rhs) const + { + return not(*this == rhs); + } + +private: + void advance() + { + if (m_home == nullptr) + throw usage_error{"Moving stream_from iterator beyond end()."}; + if (not((*m_home) >> m_value)) + m_home = nullptr; + } + + stream_from *m_home{nullptr}; + value_type m_value; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from. +template class stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit stream_input_iteration(stream_from &home) : m_home{home} {} + iterator begin() const { return iterator{m_home}; } + iterator end() const { return {}; } + +private: + stream_from &m_home; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from, deleting it once done. +template class owning_stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit owning_stream_input_iteration(std::unique_ptr &&home) : + m_home{std::move(home)} + {} + iterator begin() const { return iterator{*m_home.get()}; } + iterator end() const { return {}; } + +private: + std::unique_ptr m_home; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx b/ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx new file mode 100644 index 0000000..7a82e65 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/internal/wait.hxx @@ -0,0 +1,18 @@ +#if !defined(PQXX_WAIT_HXX) +# define PQXX_WAIT_HXX + +namespace pqxx::internal +{ +/// Wait. +/** This is normally `std::this_thread::sleep_for()`. But MinGW's `thread` + * header doesn't work, so we must be careful about including it. + */ +void PQXX_LIBEXPORT wait_for(unsigned int microseconds); + + +/// Wait for a socket to be ready for reading/writing, or timeout. +PQXX_LIBEXPORT void wait_fd( + int fd, bool for_read, bool for_write, unsigned seconds = 1, + unsigned microseconds = 0); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/isolation b/ext/libpqxx-7.7.3/include/pqxx/isolation new file mode 100644 index 0000000..1b80132 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/isolation @@ -0,0 +1,8 @@ +/** Transaction isolation levels. + * + * Policies and traits describing SQL transaction isolation levels + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/isolation.hxx b/ext/libpqxx-7.7.3/include/pqxx/isolation.hxx new file mode 100644 index 0000000..0698c6a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/isolation.hxx @@ -0,0 +1,75 @@ +/* Definitions for transaction isolation levels, and such. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/isolation instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ISOLATION +#define PQXX_H_ISOLATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Should a transaction be read-only, or read-write? +/** No, this is not an isolation level. So it really doesn't belong here. + * But it's not really worth a separate header. + */ +enum class write_policy +{ + read_only, + read_write +}; + + +/// Transaction isolation levels. +/** These are as defined in the SQL standard. But there are a few notes + * specific to PostgreSQL. + * + * First, postgres does not support "read uncommitted." The lowest level you + * can get is "read committed," which is better. PostgreSQL is built on the + * MVCC paradigm, which guarantees "read committed" isolation without any + * additional performance overhead, so there was no point in providing the + * lower level. + * + * Second, "repeatable read" also makes more isolation guarantees than the + * standard requires. According to the standard, this level prevents "dirty + * reads" and "nonrepeatable reads," but not "phantom reads." In postgres, + * it actually prevents all three. + * + * Third, "serializable" is only properly supported starting at postgres 9.1. + * If you request "serializable" isolation on an older backend, you will get + * the same isolation as in "repeatable read." It's better than the + * "repeatable read" defined in the SQL standard, but not a complete + * implementation of the standard's "serializable" isolation level. + * + * In general, a lower isolation level will allow more surprising interactions + * between ongoing transactions, but improve performance. A higher level + * gives you more protection from subtle concurrency bugs, but sometimes it + * may not be possible to complete your transaction without avoiding paradoxes + * in the data. In that case a transaction may fail, and the application will + * have to re-do the whole thing based on the latest state of the database. + * (If you want to retry your code in that situation, have a look at the + * transactor framework.) + * + * Study the levels and design your application with the right level in mind. + */ +enum isolation_level +{ + // PostgreSQL only has the better isolation levels. + // read_uncommitted, + + read_committed, + repeatable_read, + serializable, +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/largeobject b/ext/libpqxx-7.7.3/include/pqxx/largeobject new file mode 100644 index 0000000..1f2f947 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/largeobject @@ -0,0 +1,8 @@ +/** Large Objects interface. + * + * Supports direct access to large objects, as well as through I/O streams + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx b/ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx new file mode 100644 index 0000000..ebafc51 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/largeobject.hxx @@ -0,0 +1,735 @@ +/* Large Objects interface. Deprecated; use blob instead. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_LARGEOBJECT +#define PQXX_H_LARGEOBJECT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/// Identity of a large object. +/** @deprecated Use the @ref blob class instead. + * + * Encapsulates the identity of a large object. + * + * A largeobject must be accessed only from within a backend transaction, but + * the object's identity remains valid as long as the object exists. + */ +class PQXX_LIBEXPORT largeobject +{ +public: + using size_type = large_object_size_type; + + /// Refer to a nonexistent large object (similar to what a null pointer + /// does). + [[deprecated("Use blob instead.")]] largeobject() noexcept = default; + + /// Create new large object. + /** @param t Backend transaction in which the object is to be created. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(dbtransaction &t); + + /// Wrap object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param o Object identifier for the given object. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(oid o) noexcept : + m_id{o} + {} + + /// Import large object from a local file. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + */ + [[deprecated("Use blob instead.")]] largeobject( + dbtransaction &t, std::string_view file); + + /// Take identity of an opened large object. + /** Copy identity of already opened large object. Note that this may be done + * as an implicit conversion. + * @param o Already opened large object to copy identity from. + */ + [[deprecated("Use blob instead.")]] largeobject( + largeobjectaccess const &o) noexcept; + + /// Object identifier. + /** The number returned by this function identifies the large object in the + * database we're connected to (or oid_none is returned if we refer to the + * null object). + */ + [[nodiscard]] oid id() const noexcept { return m_id; } + + /** + * @name Identity comparisons + * + * These operators compare the object identifiers of large objects. This has + * nothing to do with the objects' actual contents; use them only for keeping + * track of containers of references to large objects and such. + */ + //@{ + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator==(largeobject const &other) const + { + return m_id == other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator!=(largeobject const &other) const + { + return m_id != other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<=(largeobject const &other) const + { + return m_id <= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>=(largeobject const &other) const + { + return m_id >= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<(largeobject const &other) const + { + return m_id < other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>(largeobject const &other) const + { + return m_id > other.m_id; + } + //@} + + /// Export large object's contents to a local file + /** Writes the data stored in the large object to the given file. + * @param t Transaction in which the object is to be accessed + * @param file A filename on the client's filesystem + */ + void to_file(dbtransaction &t, std::string_view file) const; + + /// Delete large object from database + /** Unlike its low-level equivalent cunlink, this will throw an exception if + * deletion fails. + * @param t Transaction in which the object is to be deleted + */ + void remove(dbtransaction &t) const; + +protected: + PQXX_PURE static internal::pq::PGconn * + raw_connection(dbtransaction const &T); + + PQXX_PRIVATE std::string reason(connection const &, int err) const; + +private: + oid m_id = oid_none; +}; + + +/// Accessor for large object's contents. +/** @deprecated Use the `blob` class instead. + */ +class PQXX_LIBEXPORT largeobjectaccess : private largeobject +{ +public: + using largeobject::size_type; + using off_type = size_type; + using pos_type = size_type; + + /// Open mode: `in`, `out` (can be combined using "bitwise or"). + /** According to the C++ standard, these should be in `std::ios_base`. We + * take them from derived class `std::ios` instead, which is easier on the + * eyes. + * + * Historical note: taking it from std::ios was originally a workaround for a + * problem with gcc 2.95. + */ + using openmode = std::ios::openmode; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + + /// Seek direction: `beg`, `cur`, `end`. + using seekdir = std::ios::seekdir; + + /// Create new large object and open it. + /** + * @param t Backend transaction in which the object is to be created. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] explicit largeobjectaccess( + dbtransaction &t, openmode mode = default_mode); + + /// Open large object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param t Transaction in which the object is to be accessed. + * @param o Object identifier for the given object. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, oid o, openmode mode = default_mode); + + /// Open given large object. + /** Open a large object with the given identity for reading and/or writing. + * @param t Transaction in which the object is to be accessed. + * @param o Identity for the large object to be accessed. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, largeobject o, openmode mode = default_mode); + + /// Import large object from a local file and open it. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + * @param mode Access mode, defaults to ios_base::in | ios_base::out. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, std::string_view file, openmode mode = default_mode); + + ~largeobjectaccess() noexcept { close(); } + + /// Object identifier. + /** The number returned by this function uniquely identifies the large object + * in the context of the database we're connected to. + */ + using largeobject::id; + + /// Export large object's contents to a local file. + /** Writes the data stored in the large object to the given file. + * @param file A filename on the client's filesystem. + */ + void to_file(std::string_view file) const + { + largeobject::to_file(m_trans, file); + } + + using largeobject::to_file; + + /** + * @name High-level access to object contents. + */ + //@{ + /// Write data to large object. + /** @warning The size of a write is currently limited to 2GB. + * + * @param buf Data to write. + * @param len Number of bytes from Buf to write. + */ + void write(char const buf[], std::size_t len); + + /// Write string to large object. + /** If not all bytes could be written, an exception is thrown. + * @param buf Data to write; no terminating zero is written. + */ + void write(std::string_view buf) { write(std::data(buf), std::size(buf)); } + + /// Read data from large object. + /** Throws an exception if an error occurs while reading. + * @param buf Location to store the read data in. + * @param len Number of bytes to try and read. + * @return Number of bytes read, which may be less than the number requested + * if the end of the large object is reached. + */ + size_type read(char buf[], std::size_t len); + + /// Seek in large object's data stream. + /** Throws an exception if an error occurs. + * @return The new position in the large object + */ + size_type seek(size_type dest, seekdir dir); + + /// Report current position in large object's data stream. + /** Throws an exception if an error occurs. + * @return The current position in the large object. + */ + [[nodiscard]] size_type tell() const; + //@} + + /** + * @name Low-level access to object contents. + * + * These functions provide a more "C-like" access interface, returning + * special values instead of throwing exceptions on error. These functions + * are generally best avoided in favour of the high-level access functions, + * which behave more like C++ functions should. + * + * Due to libpq's underlying API, some operations are limited to "int" + * sizes, typically 2 GB, even though a large object can grow much larger. + */ + //@{ + /// Seek in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param dest Offset to go to. + * @param dir Origin to which dest is relative: ios_base::beg (from beginning + * of the object), ios_base::cur (from current access position), or + * ios_base;:end (from end of object). + * @return New position in large object, or -1 if an error occurred. + */ + pos_type cseek(off_type dest, seekdir dir) noexcept; + + /// Write to large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Data to write. + * @param len Number of bytes to write. + * @return Number of bytes actually written, or -1 if an error occurred. + */ + off_type cwrite(char const buf[], std::size_t len) noexcept; + + /// Read from large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Area where incoming bytes should be stored. + * @param len Number of bytes to read. + * @return Number of bytes actually read, or -1 if an error occurred.. + */ + off_type cread(char buf[], std::size_t len) noexcept; + + /// Report current position in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @return Current position in large object, of -1 if an error occurred. + */ + [[nodiscard]] pos_type ctell() const noexcept; + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Issue message to transaction's notice processor. + void process_notice(zview) noexcept; + //@} + + using largeobject::remove; + + using largeobject::operator==; + using largeobject::operator!=; + using largeobject::operator<; + using largeobject::operator<=; + using largeobject::operator>; + using largeobject::operator>=; + + largeobjectaccess() = delete; + largeobjectaccess(largeobjectaccess const &) = delete; + largeobjectaccess operator=(largeobjectaccess const &) = delete; + +private: + PQXX_PRIVATE std::string reason(int err) const; + internal::pq::PGconn *raw_connection() const + { + return largeobject::raw_connection(m_trans); + } + + PQXX_PRIVATE void open(openmode mode); + void close() noexcept; + + dbtransaction &m_trans; + int m_fd = -1; +}; + + +/// Streambuf to use large objects in standard I/O streams. +/** @deprecated Access large objects directly using the @ref blob class. + * + * The standard streambuf classes provide uniform access to data storage such + * as files or string buffers, so they can be accessed using standard input or + * output streams. This streambuf implementation provided similar access to + * large objects, so they could be read and written using the same stream + * classes. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class largeobject_streambuf : public std::basic_streambuf +{ + using size_type = largeobject::size_type; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = largeobjectaccess::openmode; + using seekdir = largeobjectaccess::seekdir; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, largeobject o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, oid o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } + + virtual ~largeobject_streambuf() noexcept + { + delete[] m_p; + delete[] m_g; + } + + /// For use by large object stream classes. + void process_notice(zview const &s) { m_obj.process_notice(s); } + +protected: + virtual int sync() override + { + // setg() sets eback, gptr, egptr. + this->setg(this->eback(), this->eback(), this->egptr()); + return overflow(eof()); + } + + virtual pos_type seekoff(off_type offset, seekdir dir, openmode) override + { + return adjust_eof(m_obj.cseek(largeobjectaccess::off_type(offset), dir)); + } + + virtual pos_type seekpos(pos_type pos, openmode) override + { + largeobjectaccess::pos_type const newpos{ + m_obj.cseek(largeobjectaccess::off_type(pos), std::ios::beg)}; + return adjust_eof(newpos); + } + + virtual int_type overflow(int_type ch) override + { + auto *const pp{this->pptr()}; + if (pp == nullptr) + return eof(); + auto *const pb{this->pbase()}; + int_type res{0}; + + if (pp > pb) + { + auto const write_sz{pp - pb}; + auto const written_sz{ + m_obj.cwrite(pb, static_cast(pp - pb))}; + if (internal::cmp_less_equal(written_sz, 0)) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + "libpq reports error"}; + else if (write_sz != written_sz) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + + std::to_string(written_sz) + "/" + std::to_string(write_sz) + + " bytes written"}; + auto const out{adjust_eof(written_sz)}; + + if constexpr (std::is_arithmetic_v) + res = check_cast(out, "largeobject position"sv); + else + res = int_type(out); + } + this->setp(m_p, m_p + m_bufsize); + + // Write that one more character, if it's there. + if (ch != eof()) + { + *this->pptr() = static_cast(ch); + this->pbump(1); + } + return res; + } + + virtual int_type overflow() { return overflow(eof()); } + + virtual int_type underflow() override + { + if (this->gptr() == nullptr) + return eof(); + auto *const eb{this->eback()}; + auto const res{adjust_eof( + m_obj.cread(this->eback(), static_cast(m_bufsize)))}; + this->setg( + eb, eb, eb + (res == eof() ? 0 : static_cast(res))); + return (res == eof() or res == 0) ? eof() : traits_type::to_int_type(*eb); + } + +private: + /// Shortcut for traits_type::eof(). + static int_type eof() { return traits_type::eof(); } + + /// Helper: change error position of -1 to EOF (probably a no-op). + template static std::streampos adjust_eof(INTYPE pos) + { + bool const at_eof{pos == -1}; + if constexpr (std::is_arithmetic_v) + { + return check_cast( + (at_eof ? eof() : pos), "large object seek"sv); + } + else + { + return std::streampos(at_eof ? eof() : pos); + } + } + + void initialize(openmode mode) + { + if ((mode & std::ios::in) != 0) + { + m_g = new char_type[unsigned(m_bufsize)]; + this->setg(m_g, m_g, m_g); + } + if ((mode & std::ios::out) != 0) + { + m_p = new char_type[unsigned(m_bufsize)]; + this->setp(m_p, m_p + m_bufsize); + } + } + + size_type const m_bufsize; + largeobjectaccess m_obj; + + /// Get & put buffers. + char_type *m_g, *m_p; +}; + + +/// Input stream that gets its data from a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This class worked like any other istream, but to read data from a large + * object. It supported all formatting and streaming operations of + * `std::istream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_ilostream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Identifier of a large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + +private: + largeobject_streambuf m_buf; +}; + +using ilostream = basic_ilostream; + + +/// Output stream that writes data back to a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like any other ostream, but to write data to a large object. + * It supported all formatting and streaming operations of `std::ostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_olostream : public std::basic_ostream +{ + using super = std::basic_ostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_olostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using olostream = basic_olostream; + + +/// Stream that reads and writes a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like a std::iostream, but to read data from, or write data to, a + * large object. It supported all formatting and streaming operations of + * `std::iostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_lostream : public std::basic_iostream +{ + using super = std::basic_iostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_lostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using lostream = basic_lostream; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/nontransaction b/ext/libpqxx-7.7.3/include/pqxx/nontransaction new file mode 100644 index 0000000..bb5b797 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/nontransaction @@ -0,0 +1,8 @@ +/** pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx new file mode 100644 index 0000000..c507155 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/nontransaction.hxx @@ -0,0 +1,76 @@ +/* Definition of the pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/nontransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NONTRANSACTION +#define PQXX_H_NONTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/connection.hxx" +#include "pqxx/result.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +using namespace std::literals; + +/// Simple "transaction" class offering no transactional integrity. +/** + * @ingroup transactions + * + * nontransaction, like transaction or any other transaction_base-derived + * class, provides access to a database through a connection. Unlike its + * siblings, however, nontransaction does not maintain any kind of + * transactional integrity. This may be useful eg. for read-only access to the + * database that does not require a consistent, atomic view on its data; or for + * operations that are not allowed within a backend transaction, such as + * creating tables. + * + * For queries that update the database, however, a real transaction is likely + * to be faster unless the transaction consists of only a single record update. + * + * Also, you can keep a nontransaction open for as long as you like. Actual + * back-end transactions are limited in lifespan, and will sometimes fail just + * because they took too long to execute or were left idle for too long. This + * will not happen with a nontransaction (although the connection may still + * time out, e.g. when the network is unavailable for a very long time). + * + * Any query executed in a nontransaction is committed immediately, and neither + * commit() nor abort() has any effect. + * + * Database features that require a backend transaction, such as cursors or + * large objects, will not work in a nontransaction. + */ +class PQXX_LIBEXPORT nontransaction final : public transaction_base +{ +public: + /// Constructor. + /** Create a "dummy" transaction. + * @param c Connection in which this "transaction" will operate. + * @param tname Optional tname for the transaction, beginning with a letter + * and containing only letters and digits. + */ + nontransaction(connection &c, std::string_view tname = ""sv) : + transaction_base{c, tname, std::shared_ptr{}} + { + register_transaction(); + } + + virtual ~nontransaction() override { close(); } + +private: + virtual void do_commit() override {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/notification b/ext/libpqxx-7.7.3/include/pqxx/notification new file mode 100644 index 0000000..a0bd1c7 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/notification @@ -0,0 +1,8 @@ +/** pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/notification.hxx b/ext/libpqxx-7.7.3/include/pqxx/notification.hxx new file mode 100644 index 0000000..b59b856 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/notification.hxx @@ -0,0 +1,94 @@ +/* Definition of the pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/notification instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NOTIFICATION +#define PQXX_H_NOTIFICATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// "Observer" base class for notifications. +/** @addtogroup notification Notifications and Receivers + * + * To listen on a notification issued using the NOTIFY command, derive your own + * class from notification_receiver and define its function-call operator to + * perform whatever action you wish to take when the given notification + * arrives. Then create an object of that class and pass it to your connection. + * DO NOT use raw SQL to listen for notifications, or your attempts to listen + * won't be resumed when a connection fails--and you'll have no way to notice. + * + * Notifications never arrive inside a transaction, not even in a + * nontransaction. Therefore, you are free to open a transaction of your own + * inside your receiver's function invocation operator. + * + * Notifications you are listening for may arrive anywhere within libpqxx code, + * but be aware that **PostgreSQL defers notifications occurring inside + * transactions.** (This was done for excellent reasons; just think about what + * happens if the transaction where you happen to handle an incoming + * notification is later rolled back for other reasons). So if you're keeping + * a transaction open, don't expect any of your receivers on the same + * connection to be notified. + * + * (For very similar reasons, outgoing notifications are also not sent until + * the transaction that sends them commits.) + * + * Multiple receivers on the same connection may listen on a notification of + * the same name. An incoming notification is processed by invoking all + * receivers (zero or more) of the same name. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE notification_receiver +{ +public: + /// Register the receiver with a connection. + /** + * @param c Connnection to operate on. + * @param channel Name of the notification to listen for. + */ + notification_receiver(connection &c, std::string_view channel); + /// Register the receiver with a connection. + notification_receiver(notification_receiver const &) = delete; + /// Register the receiver with a connection. + notification_receiver &operator=(notification_receiver const &) = delete; + /// Deregister the receiver. + virtual ~notification_receiver(); + + /// The channel that this receiver listens on. + [[nodiscard]] std::string const &channel() const & { return m_channel; } + + // TODO: Change API to take payload as zview instead of string ref. + /// Overridable: action to invoke when notification arrives. + /** + * @param payload An optional string that may have been passed to the NOTIFY + * command. + * @param backend_pid Process ID of the database backend process that served + * our connection when the notification arrived. The actual process ID + * behind the connection may have changed by the time this method is called. + */ + virtual void operator()(std::string const &payload, int backend_pid) = 0; + +protected: + connection &conn() const noexcept { return m_conn; } + +private: + connection &m_conn; + std::string m_channel; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/params b/ext/libpqxx-7.7.3/include/pqxx/params new file mode 100644 index 0000000..4098782 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/params @@ -0,0 +1,8 @@ +/** Helper classes for passing statement parameters. + * + * Use these for prepared statements and parameterised statements. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/params.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/params.hxx b/ext/libpqxx-7.7.3/include/pqxx/params.hxx new file mode 100644 index 0000000..2d29cdf --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/params.hxx @@ -0,0 +1,383 @@ +/* Helpers for prepared statements and parameterised statements. + * + * See the connection class for more about such statements. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PARAMS +#define PQXX_H_PARAMS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/statement_parameters.hxx" +#include "pqxx/types.hxx" + + +/// @deprecated The new @ref params class replaces all of this. +namespace pqxx::prepare +{ +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * sequence ranging from `begin` to `end` exclusively. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic sequences. + * + * @param begin A pointer or iterator for iterating parameters. + * @param end A pointer or iterator for iterating parameters. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(IT begin, IT end) +{ + return pqxx::internal::dynamic_params(begin, end); +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C const &container) +{ + using IT = typename C::const_iterator; +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @param accessor For each parameter `p`, pass `accessor(p)`. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C &container, ACCESSOR accessor) +{ + using IT = decltype(std::begin(container)); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container, accessor}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} +} // namespace pqxx::prepare + + +namespace pqxx +{ +/// Generate parameter placeholders for use in an SQL statement. +/** When you want to pass parameters to a prepared statement or a parameterised + * statement, you insert placeholders into the SQL. During invocation, the + * database replaces those with the respective parameter values you passed. + * + * The placeholders look like `$1` (for the first parameter value), `$2` (for + * the second), and so on. You can just write those directly in your + * statement. But for those rare cases where it becomes difficult to track + * which number a placeholder should have, you can use a `placeholders` object + * to count and generate them in order. + */ +template class placeholders +{ +public: + /// Maximum number of parameters we support. + static inline constexpr unsigned int max_params{ + (std::numeric_limits::max)()}; + + placeholders() + { + static constexpr auto initial{"$1\0"sv}; + initial.copy(std::data(m_buf), std::size(initial)); + } + + /// Read an ephemeral version of the current placeholder text. + /** @warning Changing the current placeholder number will overwrite this. + * Use the view immediately, or lose it. + */ + constexpr zview view() const &noexcept + { + return zview{std::data(m_buf), m_len}; + } + + /// Read the current placeholder text, as a `std::string`. + /** This will be slightly slower than converting to a `zview`. With most + * C++ implementations however, until you get into ridiculous numbers of + * parameters, the string will benefit from the Short String Optimization, or + * SSO. + */ + std::string get() const { return std::string(std::data(m_buf), m_len); } + + /// Move on to the next parameter. + void next() & + { + if (m_current >= max_params) + throw range_error{pqxx::internal::concat( + "Too many parameters in one statement: limit is ", max_params, ".")}; + ++m_current; + if (m_current % 10 == 0) + { + // Carry the 1. Don't get too clever for this relatively rare + // case, just rewrite the entire number. Leave the $ in place + // though. + char *const data{std::data(m_buf)}; + char *const end{string_traits::into_buf( + data + 1, data + std::size(m_buf), m_current)}; + // (Subtract because we don't include the trailing zero.) + m_len = check_cast(end - data, "placeholders counter") - 1; + } + else + { + PQXX_LIKELY + // Shortcut for the common case: just increment that last digit. + ++m_buf[m_len - 1]; + } + } + + /// Return the current placeholder number. The initial placeholder is 1. + COUNTER count() const noexcept { return m_current; } + +private: + /// Current placeholder number. Starts at 1. + COUNTER m_current = 1; + + /// Length of the current placeholder string, not including trailing zero. + COUNTER m_len = 2; + + /// Text buffer where we render the placeholders, with a trailing zero. + /** We keep reusing this for every subsequent placeholder, just because we + * don't like string allocations. + * + * Maximum length is the maximum base-10 digits that COUNTER can fully + * represent, plus 1 more for the extra digit that it can only partially + * fill up, plus room for the dollar sign and the trailing zero. + */ + std::array::digits10 + 3> m_buf; +}; + + +/// Build a parameter list for a parameterised or prepared statement. +/** When calling a parameterised statement or a prepared statement, you can + * pass parameters into the statement directly in the invocation, as + * additional arguments to `exec_prepared` or `exec_params`. But in + * complex cases, sometimes that's just not convenient. + * + * In those situations, you can create a `params` and append your parameters + * into that, one by one. Then you pass the `params` to `exec_prepared` or + * `exec_params`. + * + * Combinations also work: if you have a `params` containing a string + * parameter, and you call `exec_params` with an `int` argument followed by + * your `params`, you'll be passing the `int` as the first parameter and + * the string as the second. You can even insert a `params` in a `params`, + * or pass two `params` objects to a statement. + */ +class PQXX_LIBEXPORT params +{ +public: + params() = default; + + /// Pre-populate a `params` with `args`. Feel free to add more later. + template constexpr params(Args &&...args) + { + reserve(sizeof...(args)); + append_pack(std::forward(args)...); + } + + /// Pre-allocate room for at least `n` parameters. + /** This is not needed, but it may improve efficiency. + * + * Reserve space if you're going to add parameters individually, and you've + * got some idea of how many there are going to be. It may save some + * memory re-allocations. + */ + void reserve(std::size_t n) &; + + // C++20: constexpr. + /// Get the number of parameters currently in this `params`. + [[nodiscard]] auto size() const noexcept { return m_params.size(); } + + // C++20: Use the vector's ssize() directly and go noexcept+constexpr. + /// Get the number of parameters (signed). + /** Unlike `size()`, this is not yet `noexcept`. That's because C++17's + * `std::vector` does not have a `ssize()` member function. These member + * functions are `noexcept`, but `std::size()` and `std::ssize()` are + * not. + */ + [[nodiscard]] auto ssize() const { return pqxx::internal::ssize(m_params); } + + /// Append a null value. + void append() &; + + /// Append a non-null zview parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(zview) &; + + /// Append a non-null string parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the @ref zview variant if you can, or `std::move()` + */ + void append(std::string const &) &; + + /// Append a non-null string parameter. + void append(std::string &&) &; + + /// Append a non-null binary parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(std::basic_string_view) &; + + /// Append a non-null binary parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the `std::basic_string_view` variant if you can, or + * `std::move()`. + */ + void append(std::basic_string const &) &; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Append a non-null binary parameter. + /** The `data` object must stay in place and unchanged, for as long as the + * `params` remains active. + */ + template void append(DATA const &data) & + { + append( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Append a non-null binary parameter. + void append(std::basic_string &&) &; + + /// @deprecated Append binarystring parameter. + /** The binarystring must stay valid for as long as the `params` remains + * active. + */ + void append(binarystring const &value) &; + + /// Append all parameters from value. + template + void append(pqxx::internal::dynamic_params const &value) & + { + for (auto ¶m : value) append(value.access(param)); + } + + void append(params const &value) &; + + void append(params &&value) &; + + /// Append a non-null parameter, converting it to its string + /// representation. + template void append(TYPE const &value) & + { + // TODO: Pool storage for multiple string conversions in one buffer? + if constexpr (nullness>::always_null) + { + ignore_unused(value); + m_params.emplace_back(); + } + else if (is_null(value)) + { + m_params.emplace_back(); + } + else + { + m_params.emplace_back(entry{to_string(value)}); + } + } + + /// Append all elements of `range` as parameters. + template void append_multi(RANGE const &range) & + { +#if defined(PQXX_HAVE_CONCEPTS) + if constexpr (std::ranges::sized_range) + reserve(std::size(*this) + std::size(range)); +#endif + for (auto &value : range) append(value); + } + + /// For internal use: Generate a `params` object for use in calls. + /** The params object encapsulates the pointers which we will need to pass + * to libpq when calling a parameterised or prepared statement. + * + * The pointers in the params will refer to storage owned by either the + * params object, or the caller. This is not a problem because a + * `c_params` object is guaranteed to live only while the call is going on. + * As soon as we climb back out of that call tree, we're done with that + * data. + */ + pqxx::internal::c_params make_c_params() const; + +private: + /// Recursively append a pack of params. + template + void append_pack(Arg &&arg, More &&...args) + { + this->append(std::forward(arg)); + // Recurse for remaining args. + append_pack(std::forward(args)...); + } + + /// Terminating case: append an empty parameter pack. It's not hard BTW. + constexpr void append_pack() noexcept {} + + // The way we store a parameter depends on whether it's binary or text + // (most types are text), and whether we're responsible for storing the + // contents. + using entry = std::variant< + std::nullptr_t, zview, std::string, std::basic_string_view, + std::basic_string>; + std::vector m_params; + + static constexpr std::string_view s_overflow{ + "Statement parameter length overflow."sv}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/pipeline b/ext/libpqxx-7.7.3/include/pqxx/pipeline new file mode 100644 index 0000000..bf82884 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/pipeline @@ -0,0 +1,8 @@ +/** pqxx::pipeline class. + * + * Throughput-optimized query interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx b/ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx new file mode 100644 index 0000000..049dcdd --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/pipeline.hxx @@ -0,0 +1,237 @@ +/* Definition of the pqxx::pipeline class. + * + * Throughput-optimized mechanism for executing queries. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PIPELINE +#define PQXX_H_PIPELINE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +// TODO: libpq 14 introduced a similar "pipeline mode." Can we use that? + +/// Processes several queries in FIFO manner, optimized for high throughput. +/** Use a pipeline if you want to keep doing useful work while your queries are + * executing. Result retrieval is decoupled from execution request; queries + * "go in at the front" and results "come out the back." + * + * Actually, you can retrieve the results in any order if you want, but it may + * lead to surprising "time travel" effects if any of the queries fails. In + * particular, syntax errors in the queries can confuse things and show up too + * early in the stream of results. + * + * Generally, if any of the queries fails, it will throw an exception at the + * point where you request its result. But it may happen earlier, especially + * if you request results out of chronological order. + * + * @warning While a pipeline is active, you cannot execute queries, open + * streams, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT pipeline : public transaction_focus +{ +public: + /// Identifying numbers for queries. + using query_id = long; + + pipeline(pipeline const &) = delete; + pipeline &operator=(pipeline const &) = delete; + + /// Start a pipeline. + explicit pipeline(transaction_base &t) : transaction_focus{t, s_classname} + { + init(); + } + /// Start a pipeline. Assign it a name, for more helpful error messages. + pipeline(transaction_base &t, std::string_view tname) : + transaction_focus{t, s_classname, tname} + { + init(); + } + + /// Close the pipeline. + ~pipeline() noexcept; + + /// Add query to the pipeline. + /** Queries accumulate in the pipeline, which sends them to the backend in a + * batch separated by semicolons. The queries you insert must not use this + * trick themselves, or the pipeline will get hopelessly confused! + * + * @return Identifier for this query, unique only within this pipeline. + */ + query_id insert(std::string_view) &; + + /// Wait for all ongoing or pending operations to complete, and detach. + /** Detaches from the transaction when done. + * + * This does not produce the queries' results, so it may not report any + * errors which may have occurred in their execution. To be sure that your + * statements succeeded, call @ref retrieve until the pipeline is empty. + */ + void complete(); + + /// Forget all ongoing or pending operations and retrieved results. + /** Queries already sent to the backend may still be completed, depending + * on implementation and timing. + * + * Any error state (unless caused by an internal error) will also be cleared. + * This is mostly useful in a nontransaction, since a backend transaction is + * aborted automatically when an error occurs. + * + * Detaches from the transaction when done. + */ + void flush(); + + /// Cancel ongoing query, if any. + /** May cancel any or all of the queries that have been inserted at this + * point whose results have not yet been retrieved. If the pipeline lives in + * a backend transaction, that transaction may be left in a nonfunctional + * state in which it can only be aborted. + * + * Therefore, either use this function in a nontransaction, or abort the + * transaction after calling it. + */ + void cancel(); + + /// Is result for given query available? + [[nodiscard]] bool is_finished(query_id) const; + + /// Retrieve result for given query. + /** If the query failed for whatever reason, this will throw an exception. + * The function will block if the query has not finished yet. + * @warning If results are retrieved out-of-order, i.e. in a different order + * than the one in which their queries were inserted, errors may "propagate" + * to subsequent queries. + */ + result retrieve(query_id qid) + { + return retrieve(m_queries.find(qid)).second; + } + + /// Retrieve oldest unretrieved result (possibly wait for one). + /** @return The query's identifier and its result set. */ + std::pair retrieve(); + + [[nodiscard]] bool empty() const noexcept { return std::empty(m_queries); } + + /// Set maximum number of queries to retain before issuing them to the + /// backend. + /** The pipeline will perform better if multiple queries are issued at once, + * but retaining queries until the results are needed (as opposed to issuing + * them to the backend immediately) may negate any performance benefits the + * pipeline can offer. + * + * Recommended practice is to set this value no higher than the number of + * queries you intend to insert at a time. + * @param retain_max A nonnegative "retention capacity;" passing zero will + * cause queries to be issued immediately + * @return Old retention capacity + */ + int retain(int retain_max = 2) &; + + + /// Resume retained query emission. Harmless when not needed. + void resume() &; + +private: + struct PQXX_PRIVATE Query + { + explicit Query(std::string_view q) : + query{std::make_shared(q)} + {} + + std::shared_ptr query; + result res; + }; + + using QueryMap = std::map; + + void init(); + void attach(); + void detach(); + + /// Upper bound to query id's. + static constexpr query_id qid_limit() noexcept + { + // Parenthesise this to work around an eternal Visual C++ problem: + // Without the extra parentheses, unless NOMINMAX is defined, the + // preprocessor will mistake this "max" for its annoying built-in macro + // of the same name. + return (std::numeric_limits::max)(); + } + + /// Create new query_id. + PQXX_PRIVATE query_id generate_id(); + + bool have_pending() const noexcept + { + return m_issuedrange.second != m_issuedrange.first; + } + + PQXX_PRIVATE void issue(); + + /// The given query failed; never issue anything beyond that. + void set_error_at(query_id qid) noexcept + { + PQXX_UNLIKELY + if (qid < m_error) + m_error = qid; + } + + /// Throw pqxx::internal_error. + [[noreturn]] PQXX_PRIVATE void internal_error(std::string const &err); + + PQXX_PRIVATE bool obtain_result(bool expect_none = false); + + PQXX_PRIVATE void obtain_dummy(); + PQXX_PRIVATE void get_further_available_results(); + PQXX_PRIVATE void check_end_results(); + + /// Receive any results that happen to be available; it's not urgent. + PQXX_PRIVATE void receive_if_available(); + + /// Receive results, up to stop if possible. + PQXX_PRIVATE void receive(pipeline::QueryMap::const_iterator stop); + std::pair retrieve(pipeline::QueryMap::iterator); + + QueryMap m_queries; + std::pair m_issuedrange; + int m_retain = 0; + int m_num_waiting = 0; + query_id m_q_id = 0; + + /// Is there a "dummy query" pending? + bool m_dummy_pending = false; + + /// Point at which an error occurred; no results beyond it will be available + query_id m_error = qid_limit(); + + /// Encoding. + /** We store this in the object to avoid the risk of exceptions at awkward + * moments. + */ + internal::encoding_group m_encoding; + + static constexpr std::string_view s_classname{"pipeline"}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/pqxx b/ext/libpqxx-7.7.3/include/pqxx/pqxx new file mode 100644 index 0000000..17a8eaa --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/pqxx @@ -0,0 +1,28 @@ +/// Convenience header: include all libpqxx definitions. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/array.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/params.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/prepared_statement.hxx" +#include "pqxx/result.hxx" +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/internal/result_iter.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/transactor.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/prepared_statement b/ext/libpqxx-7.7.3/include/pqxx/prepared_statement new file mode 100644 index 0000000..674be70 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/prepared_statement @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx b/ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx new file mode 100644 index 0000000..674be70 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/prepared_statement.hxx @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/range b/ext/libpqxx-7.7.3/include/pqxx/range new file mode 100644 index 0000000..11985ec --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/range @@ -0,0 +1,6 @@ +/** Client-side support for SQL range types. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/range.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/range.hxx b/ext/libpqxx-7.7.3/include/pqxx/range.hxx new file mode 100644 index 0000000..dc480e4 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/range.hxx @@ -0,0 +1,515 @@ +#ifndef PQXX_H_RANGE +#define PQXX_H_RANGE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" + +namespace pqxx +{ +/// An _unlimited_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should extend + * to infinity on that side. + * + * An unlimited boundary is always inclusive of "infinity" values, if the + * range's value type supports them. + */ +struct no_bound +{ + template constexpr bool extends_down_to(TYPE const &) const + { + return true; + } + template constexpr bool extends_up_to(TYPE const &) const + { + return true; + } +}; + + +/// An _inclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should include + * the value. + */ +template class inclusive_bound +{ +public: + inclusive_bound() = delete; + explicit inclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an inclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return not(value < m_value); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return not(m_value < value); + } + +private: + TYPE m_value; +}; + + +/// An _exclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should _not_ + * include the value. + */ +template class exclusive_bound +{ +public: + exclusive_bound() = delete; + explicit exclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an exclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return m_value < value; + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return value < m_value; + } + +private: + TYPE m_value; +}; + + +/// A range boundary value. +/** A range bound is either no bound at all; or an inclusive bound; or an + * exclusive bound. Pass one of the three to the constructor. + */ +template class range_bound +{ +public: + range_bound() = delete; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(no_bound) : m_bound{} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(inclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(exclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound const &) = default; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound &&) = default; + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range_bound const &rhs) const + { + if (this->is_limited()) + return ( + rhs.is_limited() and (this->is_inclusive() == rhs.is_inclusive()) and + (*this->value() == *rhs.value())); + else + return not rhs.is_limited(); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range_bound const &rhs) const { return not(*this == rhs); } + range_bound &operator=(range_bound const &) = default; + range_bound &operator=(range_bound &&) = default; + + /// Is this a finite bound? + constexpr bool is_limited() const noexcept + { + return not std::holds_alternative(m_bound); + } + + /// Is this boundary an inclusive one? + constexpr bool is_inclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + /// Is this boundary an exclusive one? + constexpr bool is_exclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as a lower bound, include `value`? + bool extends_down_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_down_to(value); }, + m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as an upper bound, include `value`? + bool extends_up_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_up_to(value); }, + m_bound); + } + + /// Return bound value, or `nullptr` if it's not limited. + [[nodiscard]] constexpr TYPE const *value() const &noexcept + { + return std::visit( + [](auto const &bound) noexcept { + using bound_t = std::decay_t; + if constexpr (std::is_same_v) + return static_cast(nullptr); + else + return &bound.get(); + }, + m_bound); + } + +private: + std::variant, exclusive_bound> m_bound; +}; + + +// C++20: Concepts for comparisons, construction, etc. +/// A C++ equivalent to PostgreSQL's range types. +/** You can use this as a client-side representation of a "range" in SQL. + * + * PostgreSQL defines several range types, differing in the data type over + * which they range. You can also define your own range types. + * + * Usually you'll want the server to deal with ranges. But on occasions where + * you need to work with them client-side, you may want to use @ref + * pqxx::range. (In cases where all you do is pass them along to the server + * though, it's not worth the complexity. In that case you might as well treat + * ranges as just strings.) + * + * For documentation on PostgreSQL's range types, see: + * https://www.postgresql.org/docs/current/rangetypes.html + * + * The value type must be copyable and default-constructible, and support the + * less-than (`<`) and equals (`==`) comparisons. Value initialisation must + * produce a consistent value. + */ +template class range +{ +public: + /// Create a range. + /** For each of the two bounds, pass a @ref no_bound, @ref inclusive_bound, + * or + * @ref exclusive_bound. + */ + range(range_bound lower, range_bound upper) : + m_lower{lower}, m_upper{upper} + { + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + throw range_error{internal::concat( + "Range's lower bound (", *lower.value(), + ") is greater than its upper bound (", *upper.value(), ").")}; + } + + // TODO: constexpr and/or noexcept if underlying constructor supports it. + /// Create an empty range. + /** SQL has a separate literal to denote an empty range, but any range which + * encompasses no values is an empty range. + */ + range() : + m_lower{exclusive_bound{TYPE{}}}, + m_upper{exclusive_bound{TYPE{}}} + {} + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range const &rhs) const + { + return (this->lower_bound() == rhs.lower_bound() and + this->upper_bound() == rhs.upper_bound()) or + (this->empty() and rhs.empty()); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range const &rhs) const { return !(*this == rhs); } + + range(range const &) = default; + range(range &&) = default; + range &operator=(range const &) = default; + range &operator=(range &&) = default; + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Is this range clearly empty? + /** An empty range encompasses no values. + * + * It is possible to "fool" this. For example, if your range is of an + * integer type and has exclusive bounds of 0 and 1, it encompasses no values + * but its `empty()` will return false. The PostgreSQL implementation, by + * contrast, will notice that it is empty. Similar things can happen for + * floating-point types, but with more subtleties and edge cases. + */ + bool empty() const + { + return (m_lower.is_exclusive() or m_upper.is_exclusive()) and + m_lower.is_limited() and m_upper.is_limited() and + not(*m_lower.value() < *m_upper.value()); + } + + // TODO: constexpr and/or noexcept if underlying functions support it. + /// Does this range encompass `value`? + bool contains(TYPE value) const + { + return m_lower.extends_down_to(value) and m_upper.extends_up_to(value); + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Does this range encompass all of `other`? + /** This function is not particularly smart. It does not know, for example, + * that integer ranges `[0,9]` and `[0,10)` contain the same values. + */ + bool contains(range const &other) const + { + return (*this & other) == other; + } + + [[nodiscard]] constexpr range_bound const & + lower_bound() const &noexcept + { + return m_lower; + } + [[nodiscard]] constexpr range_bound const & + upper_bound() const &noexcept + { + return m_upper; + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Intersection of two ranges. + /** Returns a range describing those values which are in both ranges. + */ + range operator&(range const &other) const + { + range_bound lower{no_bound{}}; + if (not this->lower_bound().is_limited()) + lower = other.lower_bound(); + else if (not other.lower_bound().is_limited()) + lower = this->lower_bound(); + else if (*this->lower_bound().value() < *other.lower_bound().value()) + lower = other.lower_bound(); + else if (*other.lower_bound().value() < *this->lower_bound().value()) + lower = this->lower_bound(); + else if (this->lower_bound().is_exclusive()) + lower = this->lower_bound(); + else + lower = other.lower_bound(); + + range_bound upper{no_bound{}}; + if (not this->upper_bound().is_limited()) + upper = other.upper_bound(); + else if (not other.upper_bound().is_limited()) + upper = this->upper_bound(); + else if (*other.upper_bound().value() < *this->upper_bound().value()) + upper = other.upper_bound(); + else if (*this->upper_bound().value() < *other.upper_bound().value()) + upper = this->upper_bound(); + else if (this->upper_bound().is_exclusive()) + upper = this->upper_bound(); + else + upper = other.upper_bound(); + + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + return {}; + else + return {lower, upper}; + } + + /// Convert to another base type. + template operator range() const + { + range_bound lower{no_bound{}}, upper{no_bound{}}; + if (lower_bound().is_inclusive()) + lower = inclusive_bound{*lower_bound().value()}; + else if (lower_bound().is_exclusive()) + lower = exclusive_bound{*lower_bound().value()}; + + if (upper_bound().is_inclusive()) + upper = inclusive_bound{*upper_bound().value()}; + else if (upper_bound().is_exclusive()) + upper = exclusive_bound{*upper_bound().value()}; + + return {lower, upper}; + } + +private: + range_bound m_lower, m_upper; +}; + + +/// String conversions for a @ref range type. +/** Conversion assumes that either your client encoding is UTF-8, or the values + * are pure ASCII. + */ +template struct string_traits> +{ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, range const &value) + { + return generic_to_buf(begin, end, value); + } + + static inline char * + into_buf(char *begin, char *end, range const &value) + { + if (value.empty()) + { + if ((end - begin) <= internal::ssize(s_empty)) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin + s_empty.copy(begin, std::size(s_empty)); + *here++ = '\0'; + return here; + } + else + { + if (end - begin < 4) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin; + *here++ = + (static_cast(value.lower_bound().is_inclusive() ? '[' : '(')); + TYPE const *lower{value.lower_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (lower != nullptr) + here = string_traits::into_buf(here, end, *lower) - 1; + *here++ = ','; + TYPE const *upper{value.upper_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (upper != nullptr) + here = string_traits::into_buf(here, end, *upper) - 1; + if ((end - here) < 2) + throw conversion_overrun{s_overrun.c_str()}; + *here++ = + static_cast(value.upper_bound().is_inclusive() ? ']' : ')'); + *here++ = '\0'; + return here; + } + } + + [[nodiscard]] static inline range from_string(std::string_view text) + { + if (std::size(text) < 3) + throw pqxx::conversion_error{err_bad_input(text)}; + bool left_inc{false}; + switch (text[0]) + { + case '[': left_inc = true; break; + + case '(': break; + + case 'e': + case 'E': + if ( + (std::size(text) != std::size(s_empty)) or + (text[1] != 'm' and text[1] != 'M') or + (text[2] != 'p' and text[2] != 'P') or + (text[3] != 't' and text[3] != 'T') or + (text[4] != 'y' and text[4] != 'Y')) + throw pqxx::conversion_error{err_bad_input(text)}; + return {}; + break; + + default: throw pqxx::conversion_error{err_bad_input(text)}; + } + + auto scan{internal::get_glyph_scanner(internal::encoding_group::UTF8)}; + // The field parser uses this to track which field it's parsing, and + // when not to expect a field separator. + std::size_t index{0}; + // The last field we expect to see. + static constexpr std::size_t last{1}; + // Current parsing position. We skip the opening parenthesis or bracket. + std::size_t pos{1}; + // The string may leave out either bound to indicate that it's unlimited. + std::optional lower, upper; + // We reuse the same field parser we use for composite values and arrays. + internal::parse_composite_field(index, text, pos, lower, scan, last); + internal::parse_composite_field(index, text, pos, upper, scan, last); + + // We need one more character: the closing parenthesis or bracket. + if (pos != std::size(text)) + throw pqxx::conversion_error{err_bad_input(text)}; + char const closing{text[pos - 1]}; + if (closing != ')' and closing != ']') + throw pqxx::conversion_error{err_bad_input(text)}; + bool const right_inc{closing == ']'}; + + range_bound lower_bound{no_bound{}}, upper_bound{no_bound{}}; + if (lower) + { + if (left_inc) + lower_bound = inclusive_bound{*lower}; + else + lower_bound = exclusive_bound{*lower}; + } + if (upper) + { + if (right_inc) + upper_bound = inclusive_bound{*upper}; + else + upper_bound = exclusive_bound{*upper}; + } + + return {lower_bound, upper_bound}; + } + + [[nodiscard]] static inline constexpr std::size_t + size_buffer(range const &value) noexcept + { + TYPE const *lower{value.lower_bound().value()}, + *upper{value.upper_bound().value()}; + std::size_t const lsz{ + lower == nullptr ? 0 : string_traits::size_buffer(*lower) - 1}, + usz{upper == nullptr ? 0 : string_traits::size_buffer(*upper) - 1}; + + if (value.empty()) + return std::size(s_empty) + 1; + else + return 1 + lsz + 1 + usz + 2; + } + +private: + static constexpr zview s_empty{"empty"_zv}; + static constexpr auto s_overrun{"Not enough space in buffer for range."_zv}; + + /// Compose error message for invalid range input. + static std::string err_bad_input(std::string_view text) + { + return internal::concat("Invalid range input: '", text, "'"); + } +}; + + +/// A range type does not have an innate null value. +template struct nullness> : no_null> +{}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/result b/ext/libpqxx-7.7.3/include/pqxx/result new file mode 100644 index 0000000..523394b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/result @@ -0,0 +1,16 @@ +/** pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" + +// Now include some types which depend on result, but which the user will +// expect to see defined after including this header. +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/result_iter.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/result.hxx b/ext/libpqxx-7.7.3/include/pqxx/result.hxx new file mode 100644 index 0000000..6c41cc0 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/result.hxx @@ -0,0 +1,335 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT +#define PQXX_H_RESULT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include + +#include "pqxx/except.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx::internal +{ +// TODO: Make noexcept (but breaks ABI). +PQXX_LIBEXPORT void clear_result(pq::PGresult const *); +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class result_connection; +class result_creation; +class result_pipeline; +class result_row; +class result_sql_cursor; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Result set containing data returned by a query or command. +/** This behaves as a container (as defined by the C++ standard library) and + * provides random access const iterators to iterate over its rows. You can + * also access a row by indexing a `result R` by the row's zero-based + * number: + * + * + * for (result::size_type i=0; i < std::size(R); ++i) Process(R[i]); + * + * + * Result sets in libpqxx are lightweight, reference-counted wrapper objects + * which are relatively small and cheap to copy. Think of a result object as + * a "smart pointer" to an underlying result set. + * + * @warning The result set that a result object points to is not thread-safe. + * If you copy a result object, it still refers to the same underlying result + * set. So never copy, destroy, query, or otherwise access a result while + * another thread may be copying, destroying, querying, or otherwise accessing + * the same result set--even if it is doing so through a different result + * object! + */ +class PQXX_LIBEXPORT result +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + using reference = row; + using const_iterator = const_result_iterator; + using pointer = const_iterator; + using iterator = const_iterator; + using const_reverse_iterator = const_reverse_result_iterator; + using reverse_iterator = const_reverse_iterator; + + result() noexcept : + m_data{make_data_pointer()}, + m_query{}, + m_encoding{internal::encoding_group::MONOBYTE} + {} + + result(result const &rhs) noexcept = default; + result(result &&rhs) noexcept = default; + + /// Assign one result to another. + /** Copying results is cheap: it copies only smart pointers, but the actual + * data stays in the same place. + */ + result &operator=(result const &rhs) noexcept = default; + + /// Assign one result to another, invaliding the old one. + result &operator=(result &&rhs) noexcept = default; + + /** + * @name Comparisons + * + * You can compare results for equality. Beware: this is a very strict, + * dumb comparison. The smallest difference between two results (such as a + * string "Foo" versus a string "foo") will make them unequal. + */ + //@{ + /// Compare two results for equality. + [[nodiscard]] bool operator==(result const &) const noexcept; + /// Compare two results for inequality. + [[nodiscard]] bool operator!=(result const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /// Iterate rows, reading them directly into a tuple of "TYPE...". + /** Converts the fields to values of the given respective types. + * + * Use this only with a ranged "for" loop. The iteration produces + * std::tuple which you can "unpack" to a series of `auto` + * variables. + */ + template auto iter() const; + + [[nodiscard]] const_reverse_iterator rbegin() const; + [[nodiscard]] const_reverse_iterator crbegin() const; + [[nodiscard]] const_reverse_iterator rend() const; + [[nodiscard]] const_reverse_iterator crend() const; + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] inline const_iterator end() const noexcept; + [[nodiscard]] inline const_iterator cend() const noexcept; + + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + [[nodiscard]] PQXX_PURE bool empty() const noexcept; + [[nodiscard]] size_type capacity() const noexcept { return size(); } + + /// Exchange two `result` values in an exception-safe manner. + /** If the swap fails, the two values will be exactly as they were before. + * + * The swap is not necessarily thread-safe. + */ + void swap(result &) noexcept; + + /// Index a row by number. + /** This returns a @ref row object. Generally you should not keep the row + * around as a variable, but if you do, make sure that your variable is a + * `row`, not a `row&`. + */ + [[nodiscard]] row operator[](size_type i) const noexcept; + +#if defined(PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT) + // TODO: If C++23 will let us, also accept string for the column. + [[nodiscard]] field + operator[](size_type row_num, row_size_type col_num) const noexcept; +#endif + + /// Index a row by number, but check that the row number is valid. + row at(size_type) const; + + /// Index a field by row number and column number. + field at(size_type, row_size_type) const; + + /// Let go of the result's data. + /** Use this if you need to deallocate the result data earlier than you can + * destroy the `result` object itself. + * + * Multiple `result` objects can refer to the same set of underlying data. + * The underlying data will be deallocated once all `result` objects that + * refer to it are cleared or destroyed. + */ + void clear() noexcept + { + m_data.reset(); + m_query = nullptr; + } + + /** + * @name Column information + */ + //@{ + /// Number of columns in result. + [[nodiscard]] PQXX_PURE row_size_type columns() const noexcept; + + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] row_size_type column_number(zview name) const; + + /// Name of column with this number (throws exception if it doesn't exist) + [[nodiscard]] char const *column_name(row_size_type number) const &; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(row_size_type col_num) const; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(row_size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(row_size_type col_num) const; + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + /// Query that produced this result, if available (empty string otherwise) + [[nodiscard]] PQXX_PURE std::string const &query() const &noexcept; + + /// If command was an `INSERT` of 1 row, return oid of the inserted row. + /** @return Identifier of inserted row if exactly one row was inserted, or + * @ref oid_none otherwise. + */ + [[nodiscard]] PQXX_PURE oid inserted_oid() const; + + /// If command was `INSERT`, `UPDATE`, or `DELETE`: number of affected rows. + /** @return Number of affected rows if last command was `INSERT`, `UPDATE`, + * or `DELETE`; zero for all other commands. + */ + [[nodiscard]] PQXX_PURE size_type affected_rows() const; + + // C++20: Concept like std::invocable, but without specifying param types. + /// Run `func` on each row, passing the row's fields as parameters. + /** Goes through the rows from first to last. You provide a callable `func`. + * + * For each row in the `result`, `for_each` will call `func`. It converts + * the row's fields to the types of `func`'s parameters, and pass them to + * `func`. + * + * (Therefore `func` must have a _single_ signature. It can't be a generic + * lambda, or an object of a class with multiple overloaded function call + * operators. Otherwise, `for_each` will have no way to detect a parameter + * list without ambiguity.) + * + * If any of your parameter types is `std::string_view`, it refers to the + * underlying storage of this `result`. + * + * If any of your parameter types is a reference type, its argument will + * refer to a temporary value which only lives for the duration of that + * single invocation to `func`. If the reference is an lvalue reference, it + * must be `const`. + * + * For example, this queries employee names and salaries from the database + * and prints how much each would like to earn instead: + * ```cxx + * tx.exec("SELECT name, salary FROM employee").for_each( + * [](std::string_view name, float salary){ + * std::cout << name << " would like " << salary * 2 << ".\n"; + * }) + * ``` + * + * If `func` throws an exception, processing stops at that point and + * propagates the exception. + * + * @throws usage_error if `func`'s number of parameters does not match the + * number of columns in this result. + */ + template inline void for_each(CALLABLE &&func) const; + +private: + using data_pointer = std::shared_ptr; + + /// Underlying libpq result set. + data_pointer m_data; + + /// Factory for data_pointer. + static data_pointer + make_data_pointer(internal::pq::PGresult const *res = nullptr) noexcept + { + return {res, internal::clear_result}; + } + + friend class pqxx::internal::gate::result_pipeline; + PQXX_PURE std::shared_ptr query_ptr() const noexcept + { + return m_query; + } + + /// Query string. + std::shared_ptr m_query; + + internal::encoding_group m_encoding; + + static std::string const s_empty_string; + + friend class pqxx::field; + // TODO: noexcept. Breaks ABI. + PQXX_PURE char const *get_value(size_type row, row_size_type col) const; + // TODO: noexcept. Breaks ABI. + PQXX_PURE bool get_is_null(size_type row, row_size_type col) const; + PQXX_PURE + field_size_type get_length(size_type, row_size_type) const noexcept; + + friend class pqxx::internal::gate::result_creation; + result( + internal::pq::PGresult *rhs, std::shared_ptr query, + internal::encoding_group enc); + + PQXX_PRIVATE void check_status(std::string_view desc = ""sv) const; + + friend class pqxx::internal::gate::result_connection; + friend class pqxx::internal::gate::result_row; + bool operator!() const noexcept { return m_data.get() == nullptr; } + operator bool() const noexcept { return m_data.get() != nullptr; } + + [[noreturn]] PQXX_PRIVATE void + throw_sql_error(std::string const &Err, std::string const &Query) const; + PQXX_PRIVATE PQXX_PURE int errorposition() const; + PQXX_PRIVATE std::string status_error() const; + + friend class pqxx::internal::gate::result_sql_cursor; + PQXX_PURE char const *cmd_status() const noexcept; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/robusttransaction b/ext/libpqxx-7.7.3/include/pqxx/robusttransaction new file mode 100644 index 0000000..04b71d7 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/robusttransaction @@ -0,0 +1,8 @@ +/** pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx new file mode 100644 index 0000000..faf6dbf --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/robusttransaction.hxx @@ -0,0 +1,120 @@ +/* Definition of the pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/robusttransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROBUSTTRANSACTION +#define PQXX_H_ROBUSTTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref robusttransaction class template. +class PQXX_LIBEXPORT PQXX_NOVTABLE basic_robusttransaction + : public dbtransaction +{ +public: + virtual ~basic_robusttransaction() override = 0; + +protected: + basic_robusttransaction( + connection &c, zview begin_command, std::string_view tname); + basic_robusttransaction(connection &c, zview begin_command); + +private: + using IDType = unsigned long; + + std::string m_conn_string; + std::string m_xid; + int m_backendpid = -1; + + void init(zview begin_command); + + // @warning This function will become `final`. + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + * + * @{ + */ + +/// Slightly slower, better-fortified version of transaction. +/** Requires PostgreSQL 10 or better. + * + * robusttransaction is similar to transaction, but spends more time and effort + * to deal with the hopefully rare case that the connection to the backend is + * lost just while it's trying to commit. In such cases, the client does not + * know whether the backend (on the other side of the broken connection) + * managed to commit the transaction. + * + * When this happens, robusttransaction tries to reconnect to the database and + * figure out what happened. + * + * This service level was made optional since you may not want to pay the + * overhead where it is not necessary. Certainly the use of this class makes + * no sense for local connections, or for transactions that read the database + * but never modify it, or for noncritical database manipulations. + * + * Besides being slower, it's also more complex. Which means that in practice + * a robusttransaction could actually fail more instead of less often than a + * normal transaction. What robusttransaction tries to achieve is to give you + * certainty, not just be more successful per se. + */ +template +class robusttransaction final : public internal::basic_robusttransaction +{ +public: + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string_view tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + tname} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string &&tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + std::move(tname)} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + */ + explicit robusttransaction(connection &c) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd} + {} + + virtual ~robusttransaction() noexcept override { close(); } +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/row b/ext/libpqxx-7.7.3/include/pqxx/row new file mode 100644 index 0000000..62a950a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/row @@ -0,0 +1,11 @@ +/** pqxx::row class. + * + * pqxx::row refers to a row in a result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/row.hxx b/ext/libpqxx-7.7.3/include/pqxx/row.hxx new file mode 100644 index 0000000..5be5132 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/row.hxx @@ -0,0 +1,561 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROW +#define PQXX_H_ROW + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/except.hxx" +#include "pqxx/field.hxx" +#include "pqxx/result.hxx" + +#include "pqxx/internal/concat.hxx" + +namespace pqxx::internal +{ +template class result_iter; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Reference to one row in a result. +/** A row represents one row (also called a row) in a query result set. + * It also acts as a container mapping column numbers or names to field + * values (see below): + * + * ```cxx + * cout << row["date"].c_str() << ": " << row["name"].c_str() << endl; + * ``` + * + * The row itself acts like a (non-modifyable) container, complete with its + * own const_iterator and const_reverse_iterator. + */ +class PQXX_LIBEXPORT row +{ +public: + using size_type = row_size_type; + using difference_type = row_difference_type; + using const_iterator = const_row_iterator; + using iterator = const_iterator; + using reference = field; + using pointer = const_row_iterator; + using const_reverse_iterator = const_reverse_row_iterator; + using reverse_iterator = const_reverse_iterator; + + row() noexcept = default; + row(row &&) noexcept = default; + row(row const &) noexcept = default; + row &operator=(row const &) noexcept = default; + row &operator=(row &&) noexcept = default; + + /** + * @name Comparison + */ + //@{ + [[nodiscard]] PQXX_PURE bool operator==(row const &) const noexcept; + [[nodiscard]] bool operator!=(row const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] const_iterator end() const noexcept; + [[nodiscard]] const_iterator cend() const noexcept; + + /** + * @name Field access + */ + //@{ + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rend() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crend() const; + + [[nodiscard]] reference operator[](size_type) const noexcept; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + [[nodiscard]] reference operator[](zview col_name) const; + + reference at(size_type) const; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + reference at(zview col_name) const; + + [[nodiscard]] constexpr size_type size() const noexcept + { + return m_end - m_begin; + } + + [[deprecated("Swap iterators, not rows.")]] void swap(row &) noexcept; + + /// Row number, assuming this is a real row and not end()/rend(). + [[nodiscard]] constexpr result::size_type rownumber() const noexcept + { + return m_index; + } + + /** + * @name Column information + */ + //@{ + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] size_type column_number(zview col_name) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(size_type) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column number in its table did this result column come from? + /** A meaningful answer can be given only if the column in question comes + * directly from a column in a table. If the column is computed in any + * other way, a logic_error will be thrown. + * + * @param col_num a zero-based column number in this result set + * @return a zero-based column number in originating table + */ + [[nodiscard]] size_type table_column(size_type) const; + + /// What column number in its table did this result column come from? + [[nodiscard]] size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + [[nodiscard]] constexpr result::size_type num() const noexcept + { + return rownumber(); + } + + /** Produce a slice of this row, containing the given range of columns. + * + * @deprecated I haven't heard of anyone caring about row slicing at all in + * at least the last 15 years. Yet it adds complexity, so unless anyone + * files a bug explaining why they really need this feature, I'm going to + * remove it. Even if they do, the feature may need an update. + * + * The slice runs from the range's starting column to the range's end + * column, exclusive. It looks just like a normal result row, except + * slices can be empty. + */ + [[deprecated("Row slicing is going away. File a bug if you need it.")]] row + slice(size_type sbegin, size_type send) const; + + /// Is this a row without fields? Can only happen to a slice. + [[nodiscard, deprecated("Row slicing is going away.")]] PQXX_PURE bool + empty() const noexcept; + + /// Extract entire row's values into a tuple. + /** Converts to the types of the tuple's respective fields. + */ + template void to(Tuple &t) const + { + check_size(std::tuple_size_v); + convert(t); + } + + template std::tuple as() const + { + check_size(sizeof...(TYPE)); + using seq = std::make_index_sequence; + return get_tuple>(seq{}); + } + +protected: + friend class const_row_iterator; + friend class result; + row(result const &r, result_size_type index, size_type cols) noexcept; + + /// Throw @ref usage_error if row size is not `expected`. + void check_size(size_type expected) const + { + if (size() != expected) + throw usage_error{internal::concat( + "Tried to extract ", expected, " field(s) from a row of ", size(), + ".")}; + } + + /// Convert to a given tuple of values, don't check sizes. + /** We need this for cases where we have a full tuple of field types, but + * not a parameter pack. + */ + template TUPLE as_tuple() const + { + using seq = std::make_index_sequence>; + return get_tuple(seq{}); + } + + template friend class pqxx::internal::result_iter; + /// Convert entire row to tuple fields, without checking row size. + template void convert(Tuple &t) const + { + extract_fields(t, std::make_index_sequence>{}); + } + + friend class field; + + /// Result set of which this is one row. + result m_result; + + /// Row number. + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + result::size_type m_index = 0; + + // TODO: Remove m_begin and (if possible) m_end when we remove slice(). + /// First column in slice. This row ignores lower-numbered columns. + size_type m_begin = 0; + /// End column in slice. This row only sees lower-numbered columns. + size_type m_end = 0; + +private: + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + template + void extract_value(Tuple &t) const; + + /// Convert row's values as a new tuple. + template + auto get_tuple(std::index_sequence) const + { + return std::make_tuple(get_field()...); + } + + /// Extract and convert a field. + template auto get_field() const + { + return (*this)[index].as>(); + } +}; + + +/// Iterator for fields in a row. Use as row::const_iterator. +class PQXX_LIBEXPORT const_row_iterator : public field +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = field const; + using pointer = field const *; + using size_type = row_size_type; + using difference_type = row_difference_type; + using reference = field; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + const_row_iterator() = default; +#include "pqxx/internal/ignore-deprecated-post.hxx" + const_row_iterator(row const &t, row_size_type c) noexcept : + field{t.m_result, t.m_index, c} + {} + const_row_iterator(field const &F) noexcept : field{F} {} + const_row_iterator(const_row_iterator const &) noexcept = default; + const_row_iterator(const_row_iterator &&) noexcept = default; + + /** + * @name Dereferencing operators + */ + //@{ + [[nodiscard]] constexpr pointer operator->() const noexcept { return this; } + [[nodiscard]] reference operator*() const noexcept { return {*this}; } + //@} + + /** + * @name Manipulations + */ + //@{ + const_row_iterator &operator=(const_row_iterator const &) noexcept = default; + const_row_iterator &operator=(const_row_iterator &&) noexcept = default; + + // TODO: noexcept. Breaks ABI. + const_row_iterator operator++(int); + const_row_iterator &operator++() noexcept + { + ++m_col; + return *this; + } + // TODO: noexcept. Breaks ABI. + const_row_iterator operator--(int); + const_row_iterator &operator--() noexcept + { + --m_col; + return *this; + } + + const_row_iterator &operator+=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) + i); + return *this; + } + const_row_iterator &operator-=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) - i); + return *this; + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] constexpr bool + operator==(const_row_iterator const &i) const noexcept + { + return col() == i.col(); + } + [[nodiscard]] constexpr bool + operator!=(const_row_iterator const &i) const noexcept + { + return col() != i.col(); + } + [[nodiscard]] constexpr bool + operator<(const_row_iterator const &i) const noexcept + { + return col() < i.col(); + } + [[nodiscard]] constexpr bool + operator<=(const_row_iterator const &i) const noexcept + { + return col() <= i.col(); + } + [[nodiscard]] constexpr bool + operator>(const_row_iterator const &i) const noexcept + { + return col() > i.col(); + } + [[nodiscard]] constexpr bool + operator>=(const_row_iterator const &i) const noexcept + { + return col() >= i.col(); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_row_iterator + operator+(difference_type) const noexcept; + + friend const_row_iterator + operator+(difference_type, const_row_iterator const &) noexcept; + + [[nodiscard]] inline const_row_iterator + operator-(difference_type) const noexcept; + [[nodiscard]] inline difference_type + operator-(const_row_iterator const &) const noexcept; + //@} +}; + + +/// Reverse iterator for a row. Use as row::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator +{ +public: + using super = const_row_iterator; + using iterator_type = const_row_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + const_reverse_row_iterator() noexcept = default; + const_reverse_row_iterator(const_reverse_row_iterator const &) noexcept = + default; + const_reverse_row_iterator(const_reverse_row_iterator &&) noexcept = default; + + explicit const_reverse_row_iterator(super const &rhs) noexcept : + const_row_iterator{rhs} + { + super::operator--(); + } + + [[nodiscard]] PQXX_PURE iterator_type base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + using iterator_type::operator->; + using iterator_type::operator*; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_row_iterator & + operator=(const_reverse_row_iterator const &r) noexcept + { + iterator_type::operator=(r); + return *this; + } + const_reverse_row_iterator operator++() noexcept + { + iterator_type::operator--(); + return *this; + } + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator operator++(int); + const_reverse_row_iterator &operator--() noexcept + { + iterator_type::operator++(); + return *this; + } + const_reverse_row_iterator operator--(int); + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator &operator+=(difference_type i) noexcept + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_row_iterator &operator-=(difference_type i) noexcept + { + iterator_type::operator+=(i); + return *this; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_row_iterator + operator+(difference_type i) const noexcept + { + return const_reverse_row_iterator{base() - i}; + } + [[nodiscard]] const_reverse_row_iterator + operator-(difference_type i) noexcept + { + return const_reverse_row_iterator{base() + i}; + } + [[nodiscard]] difference_type + operator-(const_reverse_row_iterator const &rhs) const noexcept + { + return rhs.const_row_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_row_iterator const &rhs) const noexcept + { + return !operator==(rhs); + } + + [[nodiscard]] constexpr bool + operator<(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] constexpr bool + operator<=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] constexpr bool + operator>(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] constexpr bool + operator>=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +const_row_iterator +const_row_iterator::operator+(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) + o)}; +} + +inline const_row_iterator operator+( + const_row_iterator::difference_type o, const_row_iterator const &i) noexcept +{ + return i + o; +} + +inline const_row_iterator +const_row_iterator::operator-(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) - o)}; +} + +inline const_row_iterator::difference_type +const_row_iterator::operator-(const_row_iterator const &i) const noexcept +{ + return difference_type(num() - i.num()); +} + + +template +inline void row::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + field const f{m_result, m_index, index}; + std::get(t) = from_string(f); +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/separated_list b/ext/libpqxx-7.7.3/include/pqxx/separated_list new file mode 100644 index 0000000..1bdf51c --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/separated_list @@ -0,0 +1,6 @@ +/** Helper similar to Python's @c str.join(). + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx b/ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx new file mode 100644 index 0000000..d4230ea --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/separated_list.hxx @@ -0,0 +1,142 @@ +/* Helper similar to Python's `str.join()`. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/separated_list instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SEPARATED_LIST +#define PQXX_H_SEPARATED_LIST + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/strconv.hxx" + +// C++20: Simplify using std::ranges::range. +// C++20: Optimise buffer allocation using random_access_range/iterator. +namespace pqxx +{ +/** + * @defgroup utility Utility functions + */ +//@{ + +/// Represent sequence of values as a string, joined by a given separator. +/** + * Use this to turn e.g. the numbers 1, 2, and 3 into a string "1, 2, 3". + * + * @param sep separator string (to be placed between items) + * @param begin beginning of items sequence + * @param end end of items sequence + * @param access functor defining how to dereference sequence elements + */ +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access) +{ + if (end == begin) + return {}; + auto next{begin}; + ++next; + if (next == end) + return to_string(access(begin)); + + // From here on, we've got at least 2 elements -- meaning that we need sep. + using elt_type = strip_t; + using traits = string_traits; + + std::size_t budget{0}; + for (ITER cnt{begin}; cnt != end; ++cnt) + budget += traits::size_buffer(access(cnt)); + budget += + static_cast(std::distance(begin, end)) * std::size(sep); + + std::string result; + result.resize(budget); + + char *const data{result.data()}; + char *here{data}; + char *stop{data + budget}; + here = traits::into_buf(here, stop, access(begin)) - 1; + for (++begin; begin != end; ++begin) + { + here += sep.copy(here, std::size(sep)); + here = traits::into_buf(here, stop, access(begin)) - 1; + } + result.resize(static_cast(here - data)); + return result; +} + + +/// Render sequence as a string, using given separator between items. +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end) +{ + return separated_list(sep, begin, end, [](ITER i) { return *i; }); +} + + +/// Render items in a container as a string, using given separator. +template +[[nodiscard]] inline auto +separated_list(std::string_view sep, CONTAINER const &c) + /* + Always std::string; necessary because SFINAE doesn't work with the + contents of function bodies, so the check for iterability has to be in + the signature. + */ + -> typename std::enable_if< + (not std::is_void::value and + not std::is_void::value), + std::string>::type +{ + return separated_list(sep, std::begin(c), std::end(c)); +} + + +/// Render items in a tuple as a string, using given separator. +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX == std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string separated_list( + std::string_view /* sep */, TUPLE const &t, ACCESS const &access) +{ + return to_string(access(&std::get(t))); +} + +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX < std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t, ACCESS const &access) +{ + std::string out{to_string(access(&std::get(t)))}; + out.append(sep); + out.append(separated_list(sep, t, access)); + return out; +} + +template< + typename TUPLE, std::size_t INDEX = 0, + typename std::enable_if< + (INDEX <= std::tuple_size::value), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t) +{ + // TODO: Optimise allocation. + return separated_list(sep, t, [](TUPLE const &tup) { return *tup; }); +} +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/strconv b/ext/libpqxx-7.7.3/include/pqxx/strconv new file mode 100644 index 0000000..aa2c40e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/strconv @@ -0,0 +1,6 @@ +/** String conversion definitions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/strconv.hxx b/ext/libpqxx-7.7.3/include/pqxx/strconv.hxx new file mode 100644 index 0000000..8637112 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/strconv.hxx @@ -0,0 +1,468 @@ +/* String conversion definitions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STRCONV +#define PQXX_H_STRCONV + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +namespace pqxx::internal +{ +/// Attempt to demangle @c std::type_info::name() to something human-readable. +PQXX_LIBEXPORT std::string demangle_type_name(char const[]); +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @defgroup stringconversion String conversion + * + * The PostgreSQL server accepts and represents data in string form. It has + * its own formats for various data types. The string conversions define how + * various C++ types translate to and from their respective PostgreSQL text + * representations. + * + * Each conversion is defined by a specialisations of @c string_traits. It + * gets complicated if you want top performance, but until you do, all you + * really need to care about when converting values between C++ in-memory + * representations such as @c int and the postgres string representations is + * the @c pqxx::to_string and @c pqxx::from_string functions. + * + * If you need to convert a type which is not supported out of the box, you'll + * need to define your own specialisations for these templates, similar to the + * ones defined here and in `pqxx/conversions.hxx`. Any conversion code which + * "sees" your specialisation will now support your conversion. In particular, + * you'll be able to read result fields into a variable of the new type. + * + * There is a macro to help you define conversions for individual enumeration + * types. The conversion will represent enumeration values as numeric strings. + */ +//@{ + +/// A human-readable name for a type, used in error messages and such. +/** Actually this may not always be very user-friendly. It uses + * @c std::type_info::name(). On gcc-like compilers we try to demangle its + * output. Visual Studio produces human-friendly names out of the box. + * + * This variable is not inline. Inlining it gives rise to "memory leak" + * warnings from asan, the address sanitizer, possibly from use of + * @c std::type_info::name. + */ +template +std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())}; + + +/// Traits describing a type's "null value," if any. +/** Some C++ types have a special value or state which correspond directly to + * SQL's NULL. + * + * The @c nullness traits describe whether it exists, and whether a particular + * value is null. + */ +template struct nullness +{ + /// Does this type have a null value? + static bool has_null; + + /// Is this type always null? + static bool always_null; + + /// Is @c value a null? + static bool is_null(TYPE const &value); + + /// Return a null value. + /** Don't use this in generic code to compare a value and see whether it is + * null. Some types may have multiple null values which do not compare as + * equal, or may define a null value which is not equal to anything including + * itself, like in SQL. + */ + [[nodiscard]] static TYPE null(); +}; + + +/// Nullness traits describing a type which does not have a null value. +template struct no_null +{ + /// Does @c TYPE have a "built-in null value"? + /** For example, a pointer can equal @c nullptr, which makes a very natural + * representation of an SQL null value. For such types, the code sometimes + * needs to make special allowances. + * + * for most types, such as @c int or @c std::string, there is no built-in + * null. If you want to represent an SQL null value for such a type, you + * would have to wrap it in something that does have a null value. For + * example, you could use @c std::optional for "either an @c int or a + * null value." + */ + static constexpr bool has_null = false; + + /// Are all values of this type null? + /** There are a few special C++ types which are always null - mainly + * @c std::nullptr_t. + */ + static constexpr bool always_null = false; + + /// Does a given value correspond to an SQL null value? + /** Most C++ types, such as @c int or @c std::string, have no inherent null + * value. But some types such as C-style string pointers do have a natural + * equivalent to an SQL null. + */ + [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept + { + return false; + } +}; + + +/// Traits class for use in string conversions. +/** Specialize this template for a type for which you wish to add to_string + * and from_string support. + * + * String conversions are not meant to work for nulls. Check for null before + * converting a value of @c TYPE to a string, or vice versa. + */ +template struct string_traits +{ + /// Return a @c string_view representing value, plus terminating zero. + /** Produces a @c string_view containing the PostgreSQL string representation + * for @c value. + * + * Uses the space from @c begin to @c end as a buffer, if needed. The + * returned string may lie somewhere in that buffer, or it may be a + * compile-time constant, or it may be null if value was a null value. Even + * if the string is stored in the buffer, its @c begin() may or may not be + * the same as @c begin. + * + * The @c string_view is guaranteed to be valid as long as the buffer from + * @c begin to @c end remains accessible and unmodified. + * + * @throws pqxx::conversion_overrun if the provided buffer space may not be + * enough. For maximum performance, this is a conservative estimate. It may + * complain about a buffer which is actually large enough for your value, if + * an exact check gets too expensive. + */ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, TYPE const &value); + + /// Write value's string representation into buffer at @c begin. + /** Assumes that value is non-null. + * + * Writes value's string representation into the buffer, starting exactly at + * @c begin, and ensuring a trailing zero. Returns the address just beyond + * the trailing zero, so the caller could use it as the @c begin for another + * call to @c into_buf writing a next value. + */ + static inline char *into_buf(char *begin, char *end, TYPE const &value); + + /// Parse a string representation of a @c TYPE value. + /** Throws @c conversion_error if @c value does not meet the expected format + * for a value of this type. + */ + [[nodiscard]] static inline TYPE from_string(std::string_view text); + + // C++20: Can we make these all constexpr? + /// Estimate how much buffer space is needed to represent value. + /** The estimate may be a little pessimistic, if it saves time. + * + * The estimate includes the terminating zero. + */ + [[nodiscard]] static inline std::size_t + size_buffer(TYPE const &value) noexcept; +}; + + +/// Nullness: Enums do not have an inherent null value. +template +struct nullness>> : no_null +{}; +} // namespace pqxx + + +namespace pqxx::internal +{ +/// Helper class for defining enum conversions. +/** The conversion will convert enum values to numeric strings, and vice versa. + * + * To define a string conversion for an enum type, derive a @c string_traits + * specialisation for the enum from this struct. + * + * There's usually an easier way though: the @c PQXX_DECLARE_ENUM_CONVERSION + * macro. Use @c enum_traits manually only if you need to customise your + * traits type in more detail. + */ +template struct enum_traits +{ + using impl_type = std::underlying_type_t; + using impl_traits = string_traits; + + [[nodiscard]] static constexpr zview + to_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::to_buf(begin, end, to_underlying(value)); + } + + static constexpr char *into_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::into_buf(begin, end, to_underlying(value)); + } + + [[nodiscard]] static ENUM from_string(std::string_view text) + { + return static_cast(impl_traits::from_string(text)); + } + + [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept + { + return impl_traits::size_buffer(to_underlying(value)); + } + +private: + // C++23: Replace with std::to_underlying. + static constexpr impl_type to_underlying(ENUM const &value) noexcept + { + return static_cast(value); + } +}; +} // namespace pqxx::internal + + +/// Macro: Define a string conversion for an enum type. +/** This specialises the @c pqxx::string_traits template, so use it in the + * @c ::pqxx namespace. + * + * For example: + * + * #include + * #include + * enum X { xa, xb }; + * namespace pqxx { PQXX_DECLARE_ENUM_CONVERSION(x); } + * int main() { std::cout << pqxx::to_string(xa) << std::endl; } + */ +#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \ + template<> struct string_traits : pqxx::internal::enum_traits \ + {}; \ + template<> inline std::string const type_name { #ENUM } + + +namespace pqxx +{ +/// Parse a value in postgres' text format as a TYPE. +/** If the form of the value found in the string does not match the expected + * type, e.g. if a decimal point is found when converting to an integer type, + * the conversion fails. Overflows (e.g. converting "9999999999" to a 16-bit + * C++ type) are also treated as errors. If in some cases this behaviour + * should be inappropriate, convert to something bigger such as @c long @c int + * first and then truncate the resulting value. + * + * Only the simplest possible conversions are supported. Fancy features like + * hexadecimal or octal, spurious signs, or exponent notation won't work. + * Whitespace is not stripped away. Only the kinds of strings that come out of + * PostgreSQL and out of to_string() can be converted. + */ +template +[[nodiscard]] inline TYPE from_string(std::string_view text) +{ + return string_traits::from_string(text); +} + + +/// "Convert" a std::string_view to a std::string_view. +/** Just returns its input. + * + * @warning Of course the result is only valid for as long as the original + * string remains valid! Never access the string referenced by the return + * value after the original has been destroyed. + */ +template<> +[[nodiscard]] inline std::string_view from_string(std::string_view text) +{ + return text; +} + + +/// Attempt to convert postgres-generated string to given built-in object. +/** This is like the single-argument form of the function, except instead of + * returning the value, it sets @c value. + * + * You may find this more convenient in that it infers the type you want from + * the argument you pass. But there are disadvantages: it requires an + * assignment operator, and it may be less efficient. + */ +template inline void from_string(std::string_view text, T &value) +{ + value = from_string(text); +} + + +/// Convert a value to a readable string that PostgreSQL will understand. +/** The conversion does no special formatting, and ignores any locale settings. + * The resulting string will be human-readable and in a format suitable for use + * in SQL queries. It won't have niceties such as "thousands separators" + * though. + */ +template inline std::string to_string(TYPE const &value); + + +/// Convert multiple values to strings inside a single buffer. +/** There must be enough room for all values, or this will throw + * @c conversion_overrun. You can obtain a conservative estimate of the buffer + * space required by calling @c size_buffer() on the values. + * + * The @c std::string_view results may point into the buffer, so don't assume + * that they will remain valid after you destruct or move the buffer. + */ +template +[[nodiscard]] inline std::vector +to_buf(char *here, char const *end, TYPE... value) +{ + return {[&here, end](auto v) { + auto begin = here; + here = string_traits::into_buf(begin, end, v); + // Exclude the trailing zero out of the string_view. + auto len{static_cast(here - begin) - 1}; + return std::string_view{begin, len}; + }(value)...}; +} + +/// Convert a value to a readable string that PostgreSQL will understand. +/** This variant of to_string can sometimes save a bit of time in loops, by + * re-using a std::string for multiple conversions. + */ +template +inline void into_string(TYPE const &value, std::string &out); + + +/// Is @c value null? +template +[[nodiscard]] inline constexpr bool is_null(TYPE const &value) noexcept +{ + return nullness>::is_null(value); +} + + +/// Estimate how much buffer space is needed to represent values as a string. +/** The estimate may be a little pessimistic, if it saves time. It also + * includes room for a terminating zero after each value. + */ +template +[[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept +{ + return (string_traits>::size_buffer(value) + ...); +} + + +/// Does this type translate to an SQL array? +/** Specialisations may override this to be true for container types. + * + * This may not always be a black-and-white choice. For instance, a + * @c std::string is a container, but normally it translates to an SQL string, + * not an SQL array. + */ +template inline constexpr bool is_sql_array{false}; + + +/// Can we use this type in arrays and composite types without quoting them? +/** Define this as @c true only if values of @c TYPE can never contain any + * special characters that might need escaping or confuse the parsing of array + * or composite * types, such as commas, quotes, parentheses, braces, newlines, + * and so on. + * + * When converting a value of such a type to a string in an array or a field in + * a composite type, we do not need to add quotes, nor escape any special + * characters. + * + * This is just an optimisation, so it defaults to @c false to err on the side + * of slow correctness. + */ +template inline constexpr bool is_unquoted_safe{false}; + + +/// Element separator between SQL array elements of this type. +template inline constexpr char array_separator{','}; + + +/// What's the preferred format for passing non-null parameters of this type? +/** This affects how we pass parameters of @c TYPE when calling parameterised + * statements or prepared statements. + * + * Generally we pass parameters in text format, but binary strings are the + * exception. We also pass nulls in binary format, so this function need not + * handle null values. + */ +template inline constexpr format param_format(TYPE const &) +{ + return format::text; +} + + +/// Implement @c string_traits::to_buf by calling @c into_buf. +/** When you specialise @c string_traits for a new type, most of the time its + * @c to_buf implementation has no special optimisation tricks and just writes + * its text into the buffer it receives from the caller, starting at the + * beginning. + * + * In that common situation, you can implement @c to_buf as just a call to + * @c generic_to_buf. It will call @c into_buf and return the right result for + * @c to_buf. + */ +template +inline zview generic_to_buf(char *begin, char *end, TYPE const &value) +{ + using traits = string_traits; + // The trailing zero does not count towards the zview's size, so subtract 1 + // from the result we get from into_buf(). + if (is_null(value)) + return {}; + else + return {begin, traits::into_buf(begin, end, value) - begin - 1}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Binary string, akin to @c std::string for binary data. +/** Any type that satisfies this concept can represent an SQL BYTEA value. + * + * A @c binary has a @c begin(), @c end(), @c size(), and @data(). Each byte + * is a @c std::byte, and they must all be laid out contiguously in memory so + * we can reference them by a pointer. + */ +template +concept binary = std::ranges::contiguous_range and + std::is_same_v>, std::byte>; +#endif +//@} +} // namespace pqxx + + +#include "pqxx/internal/conversions.hxx" +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/stream_from b/ext/libpqxx-7.7.3/include/pqxx/stream_from new file mode 100644 index 0000000..9727624 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/stream_from @@ -0,0 +1,8 @@ +/** pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx b/ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx new file mode 100644 index 0000000..ff4a93d --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/stream_from.hxx @@ -0,0 +1,361 @@ +/* Definition of the pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_from instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_FROM +#define PQXX_H_STREAM_FROM + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/stream_iterator.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_focus.hxx" + + +namespace pqxx +{ +class transaction_base; + + +/// Pass this to a `stream_from` constructor to stream table contents. +/** @deprecated Use @ref stream_from::table() instead. + */ +constexpr from_table_t from_table; +/// Pass this to a `stream_from` constructor to stream query results. +/** @deprecated Use stream_from::query() instead. + */ +constexpr from_query_t from_query; + + +/// Stream data from the database. +/** For larger data sets, retrieving data this way is likely to be faster than + * executing a query and then iterating and converting the rows fields. You + * will also be able to start processing before all of the data has come in. + * + * There are also downsides. Not all kinds of query will work in a stream. + * But straightforward `SELECT` and `UPDATE ... RETURNING` queries should work. + * This function makes use of @ref pqxx::stream_from, which in turn uses + * PostgreSQL's `COPY` command, so see the documentation for those to get the + * full details. + * + * There are other downsides. If there stream encounters an error, it may + * leave the entire connection in an unusable state, so you'll have to give the + * whole thing up. Finally, opening a stream puts the connection in a special + * state, so you won't be able to do many other things with the connection or + * the transaction while the stream is open. + * + * There are two ways of starting a stream: you stream either all rows in a + * table (using one of the factories, `table()` or `raw_table()`), or the + * results of a query (using the `query()` factory). + * + * Usually you'll want the `stream` convenience wrapper in + * @ref transaction_base, * so you don't need to deal with this class directly. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_from : transaction_focus +{ +public: + using raw_line = + std::pair>, std::size_t>; + + /// Factory: Execute query, and stream the results. + /** The query can be a SELECT query or a VALUES query; or it can be an + * UPDATE, INSERT, or DELETE with a RETURNING clause. + * + * The query is executed as part of a COPY statement, so there are additional + * restrictions on what kind of query you can use here. See the PostgreSQL + * documentation for the COPY command: + * + * https://www.postgresql.org/docs/current/sql-copy.html + */ + static stream_from query(transaction_base &tx, std::string_view q) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return {tx, from_query, q}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /** + * @name Streaming data from tables + * + * You can use `stream_from` to read a table's contents. This is a quick + * and easy way to read a table, but it comes with limitations. It cannot + * stream from a view, only from a table. It does not support conditions. + * And there are no guarantees about ordering. If you need any of those + * things, consider streaming from a query instead. + */ + //@{ + + /// Factory: Stream data from a pre-quoted table and columns. + /** Use this factory if you need to create multiple streams using the same + * table path and/or columns list, and you want to save a bit of work on + * composing the internal SQL statement for starting the stream. It lets you + * compose the string representations for the table path and the columns + * list, so you can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns which the stream will read. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will read all columns in the table, in schema order. + */ + static stream_from raw_table( + transaction_base &tx, std::string_view path, + std::string_view columns = ""sv); + + /// Factory: Stream data from a given table. + /** This is the convenient way to stream from a table. + */ + static stream_from table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}); + //@} + + /// Execute query, and stream over the results. + /** @deprecated Use factory function @ref query instead. + */ + [[deprecated("Use query() factory instead.")]] stream_from( + transaction_base &, from_query_t, std::string_view query); + + /// Stream all rows in table, all columns. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table); + + /// Stream given columns from all rows in table. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end); + + /// Stream given columns from all rows in table. + /** @deprecated Use factory function @ref query instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Columns const &columns); + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// @deprecated Use factories @ref table or @ref raw_table instead. + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table) : + stream_from{tx, from_table, table} + {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table, Columns const &columns) : + stream_from{tx, from_table, table, columns} + {} + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &, std::string_view table, Iter columns_begin, + Iter columns_end); + + ~stream_from() noexcept; + + /// May this stream still produce more data? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream produced all the data it is going to produce? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Finish this stream. Call this before continuing to use the connection. + /** Consumes all remaining lines, and closes the stream. + * + * This may take a while if you're abandoning the stream before it's done, so + * skip it in error scenarios where you're not planning to use the connection + * again afterwards. + */ + void complete(); + + /// Read one row into a tuple. + /** Converts the row's fields into the fields making up the tuple. + * + * For a column which can contain nulls, be sure to give the corresponding + * tuple field a type which can be null. For example, to read a field as + * `int` when it may contain nulls, read it as `std::optional`. + * Using `std::shared_ptr` or `std::unique_ptr` will also work. + */ + template stream_from &operator>>(Tuple &); + + /// Doing this with a `std::variant` is going to be horrifically borked. + template + stream_from &operator>>(std::variant &) = delete; + + /// Iterate over this stream. Supports range-based "for" loops. + /** Produces an input iterator over the stream. + * + * Do not call this yourself. Use it like "for (auto data : stream.iter())". + */ + template [[nodiscard]] auto iter() & + { + return pqxx::internal::stream_input_iteration{*this}; + } + + /// Read a row. Return fields as views, valid until you read the next row. + /** Returns `nullptr` when there are no more rows to read. Do not attempt + * to read any further rows after that. + * + * Do not access the vector, or the storage referenced by the views, after + * closing or completing the stream, or after attempting to read a next row. + * + * A @ref pqxx::zview is like a `std::string_view`, but with the added + * guarantee that if its data pointer is non-null, the string is followed by + * a terminating zero (which falls just outside the view itself). + * + * If any of the views' data pointer is null, that means that the + * corresponding SQL field is null. + * + * @warning The return type may change in the future, to support C++20 + * coroutine-based usage. + */ + std::vector const *read_row() &; + + /// Read a raw line of text from the COPY command. + /** @warning Do not use this unless you really know what you're doing. */ + raw_line get_raw_line(); + +private: + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &tx, std::string_view table, std::string_view columns, + from_table_t); + + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &, std::string_view unquoted_table, + std::string_view columns, from_table_t, int); + + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + pqxx::internal::glyph_scanner_func *m_glyph_scanner; + + /// Current row's fields' text, combined into one reusable string. + std::string m_row; + + /// The current row's fields. + std::vector m_fields; + + bool m_finished = false; + + void close(); + + template + void extract_value(Tuple &) const; + + /// Read a line of COPY data, write `m_row` and `m_fields`. + void parse_line(); +}; + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table_name, + Columns const &columns) : + stream_from{ + tx, from_table, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end) : + stream_from{ + tx, table, separated_list(",", columns_begin, columns_end), + from_table, 1} +{} + + +template inline stream_from &stream_from::operator>>(Tuple &t) +{ + if (m_finished) + return *this; + static constexpr auto tup_size{std::tuple_size_v}; + m_fields.reserve(tup_size); + parse_line(); + if (m_finished) + return *this; + + if (std::size(m_fields) != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", tup_size, " field(s) from a stream of ", + std::size(m_fields), ".")}; + + extract_fields(t, std::make_index_sequence{}); + return *this; +} + + +template +inline void stream_from::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + using nullity = nullness; + assert(index < std::size(m_fields)); + if constexpr (nullity::always_null) + { + if (std::data(m_fields[index]) != nullptr) + throw conversion_error{"Streaming non-null value into null field."}; + } + else if (std::data(m_fields[index]) == nullptr) + { + if constexpr (nullity::has_null) + std::get(t) = nullity::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + // Don't ever try to convert a non-null value to nullptr_t! + std::get(t) = from_string(m_fields[index]); + } +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/stream_to b/ext/libpqxx-7.7.3/include/pqxx/stream_to new file mode 100644 index 0000000..8760cf1 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/stream_to @@ -0,0 +1,8 @@ +/** pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx b/ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx new file mode 100644 index 0000000..2a49d8f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/stream_to.hxx @@ -0,0 +1,455 @@ +/* Definition of the pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_to.hxx instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_TO +#define PQXX_H_STREAM_TO + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Efficiently write data directly to a database table. +/** If you wish to insert rows of data into a table, you can compose INSERT + * statements and execute them. But it's slow and tedious, and you need to + * worry about quoting and escaping the data. + * + * If you're just inserting a single row, it probably won't matter much. You + * can use prepared or parameterised statements to take care of the escaping + * for you. But if you're inserting large numbers of rows you will want + * something better. + * + * Inserting rows one by one using INSERT statements involves a lot of + * pointless overhead, especially when you are working with a remote database + * server over the network. You may end up sending each row over the network + * as a separate query, and waiting for a reply. Do it "in bulk" using + * `stream_to`, and you may find that it goes many times faster. Sometimes + * you gain orders of magnitude in speed. + * + * Here's how it works: you create a `stream_to` stream to start writing to + * your table. You will probably want to specify the columns. Then, you + * feed your data into the stream one row at a time. And finally, you call the + * stream's @ref complete function to tell it to finalise the operation, wait + * for completion, and check for errors. + * + * (You _must_ complete the stream before committing or aborting the + * transaction. The connection is in a special state while the stream is + * active, where it can't process commands, and can't commit or abort a + * transaction.) + * + * So how do you feed a row of data into the stream? There's several ways, but + * the preferred one is to call its @ref write_values. Pass the field values + * as arguments. Doesn't matter what type they are, as long as libpqxx knows + * how to convert them to PostgreSQL's text format: `int`, `std::string` or + * `std:string_view`, `float` and `double`, `bool`... lots of basic types + * are supported. If some of the values are null, feel free to use + * `std::optional`, `std::shared_ptr`, or `std::unique_ptr`. + * + * The arguments' types don't even have to match the fields' SQL types. If you + * want to insert an `int` into a `DECIMAL` column, that's your choice -- it + * will produce a `DECIMAL` value which happens to be integral. Insert a + * `float` into a `VARCHAR` column? That's fine, you'll get a string whose + * contents happen to read like a number. And so on. You can even insert + * different types of value in the same column on different rows. If you have + * a code path where a particular field is always null, just insert `nullptr`. + * + * There is another way to insert rows: the `<<` ("shift-left") operator. + * It's not as fast and it doesn't support variable arguments: each row must be + * either a `std::tuple` or something iterable, such as a `std::vector`, or + * anything else with a `begin()` and `end()`. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_to : transaction_focus +{ +public: + /// Stream data to a pre-quoted table and columns. + /** This factory can be useful when it's not convenient to provide the + * columns list in the form of a `std::initializer_list`, or when the list + * of columns is simply not known at compile time. + * + * Also use this if you need to create multiple streams using the same table + * path and/or columns list, and you want to save a bit of work on composing + * the internal SQL statement for starting the stream. It lets you compose + * the string representations for the table path and the columns list, so you + * can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns to which the stream will write. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will write all columns in the table, in schema order. + */ + static stream_to raw_table( + transaction_base &tx, std::string_view path, std::string_view columns = "") + { + return {tx, path, columns}; + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this to stream data to a table, where the list of columns is known at + * compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns Optionally, the columns to which the stream should write. + * If you do not pass this, the stream will write to all columns in the + * table, in schema order. + */ + static stream_to table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}) + { + auto const &conn{tx.conn()}; + return raw_table(tx, conn.quote_table(path), conn.quote_columns(columns)); + } + +#if defined(PQXX_HAVE_CONCEPTS) + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, table_path path, COLUMNS const &columns) + { + auto const &conn{tx.conn()}; + return stream_to::raw_table( + tx, conn.quote_table(path), tx.conn().quote_columns(columns)); + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, std::string_view path, COLUMNS const &columns) + { + return stream_to::raw_table(tx, path, tx.conn().quote_columns(columns)); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Create a stream, without specifying columns. + /** @deprecated Use @ref table or @ref raw_table as a factory. + * + * Fields will be inserted in whatever order the columns have in the + * database. + * + * You'll probably want to specify the columns, so that the mapping between + * your data fields and the table is explicit in your code, and not hidden + * in an "implicit contract" between your code and your schema. + */ + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &tx, std::string_view table_name) : + stream_to{tx, table_name, ""sv} + {} + + /// Create a stream, specifying column names as a container of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Columns const &columns); + + /// Create a stream, specifying column names as a sequence of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Iter columns_begin, + Iter columns_end); + + ~stream_to() noexcept; + + /// Does this stream still need to @ref complete()? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream been through its concluding @c complete()? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Complete the operation, and check for errors. + /** Always call this to close the stream in an orderly fashion, even after + * an error. (In the case of an error, abort the transaction afterwards.) + * + * The only circumstance where it's safe to skip this is after an error, if + * you're discarding the entire connection. + */ + void complete(); + + /// Insert a row of data. + /** Returns a reference to the stream, so you can chain the calls. + * + * The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * If you don't already happen to have your fields in the form of a tuple or + * container, prefer @c write_values. It's faster and more convenient. + */ + template stream_to &operator<<(Row const &row) + { + write_row(row); + return *this; + } + + /// Stream a `stream_from` straight into a `stream_to`. + /** This can be useful when copying between different databases. If the + * source and the destination are on the same database, you'll get better + * performance doing it all in a regular query. + */ + stream_to &operator<<(stream_from &); + + /// Insert a row of data, given in the form of a @c std::tuple or container. + /** The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * The preferred way to insert a row is @c write_values. + */ + template void write_row(Row const &row) + { + fill_buffer(row); + write_buffer(); + } + + /// Insert values as a row. + /** This is the recommended way of inserting data. Pass your field values, + * of any convertible type. + */ + template void write_values(Ts const &...fields) + { + fill_buffer(fields...); + write_buffer(); + } + +private: + /// Stream a pre-quoted table name and columns list. + stream_to( + transaction_base &tx, std::string_view path, std::string_view columns); + + bool m_finished = false; + + /// Reusable buffer for a row. Saves doing an allocation for each row. + std::string m_buffer; + + /// Reusable buffer for converting/escaping a field. + std::string m_field_buf; + + /// Glyph scanner, for parsing the client encoding. + internal::glyph_scanner_func *m_scanner; + + /// Write a row of raw text-format data into the destination table. + void write_raw_line(std::string_view); + + /// Write a row of data from @c m_buffer into the destination table. + /** Resets the buffer for the next row. + */ + void write_buffer(); + + /// COPY encoding for a null field, plus subsequent separator. + static constexpr std::string_view null_field{"\\N\t"}; + + /// Estimate buffer space needed for a field which is always null. + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &) + { + return std::size(null_field); + } + + /// Estimate buffer space needed for field f. + /** The estimate is not very precise. We don't actually know how much space + * we'll need once the escaping comes in. + */ + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &field) + { + return is_null(field) ? std::size(null_field) : size_buffer(field); + } + + /// Append escaped version of @c data to @c m_buffer, plus a tab. + void escape_field_to_buffer(std::string_view data); + + /// Append string representation for @c f to @c m_buffer. + /** This is for the general case, where the field may contain a value. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &f) + { + // We append each field, terminated by a tab. That will leave us with + // one tab too many, assuming we write any fields at all; we remove that + // at the end. + if (is_null(f)) + { + // Easy. Append null and tab in one go. + m_buffer.append(null_field); + } + else + { + // Convert f into m_buffer. + + using traits = string_traits; + auto const budget{estimate_buffer(f)}; + auto const offset{std::size(m_buffer)}; + + if constexpr (std::is_arithmetic_v) + { + // Specially optimised for "safe" types, which never need any + // escaping. Convert straight into m_buffer. + + // The budget we get from size_buffer() includes room for the trailing + // zero, which we must remove. But we're also inserting tabs between + // fields, so we re-purpose the extra byte for that. + auto const total{offset + budget}; + m_buffer.resize(total); + auto const data{m_buffer.data()}; + char *const end{traits::into_buf(data + offset, data + total, f)}; + *(end - 1) = '\t'; + // Shrink to fit. Keep the tab though. + m_buffer.resize(static_cast(end - data)); + } + else if constexpr ( + std::is_same_v or + std::is_same_v or + std::is_same_v) + { + // This string may need escaping. + m_field_buf.resize(budget); + escape_field_to_buffer(f); + } + else + { + // This field needs to be converted to a string, and after that, + // escaped as well. + m_field_buf.resize(budget); + auto const data{m_field_buf.data()}; + escape_field_to_buffer( + traits::to_buf(data, data + std::size(m_field_buf), f)); + } + } + } + + /// Append string representation for a null field to @c m_buffer. + /** This special case is for types which are always null. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &) + { + m_buffer.append(null_field); + } + + /// Write raw COPY line into @c m_buffer, based on a container of fields. + template + std::enable_if_t> + fill_buffer(Container const &c) + { + // To avoid unnecessary allocations and deallocations, we run through c + // twice: once to determine how much buffer space we may need, and once to + // actually write it into the buffer. + std::size_t budget{0}; + for (auto const &f : c) budget += estimate_buffer(f); + m_buffer.reserve(budget); + for (auto const &f : c) append_to_buffer(f); + } + + /// Estimate how many buffer bytes we need to write tuple. + template + static std::size_t + budget_tuple(Tuple const &t, std::index_sequence) + { + return (estimate_buffer(std::get(t)) + ...); + } + + /// Write tuple of fields to @c m_buffer. + template + void append_tuple(Tuple const &t, std::index_sequence) + { + (append_to_buffer(std::get(t)), ...); + } + + /// Write raw COPY line into @c m_buffer, based on a tuple of fields. + template void fill_buffer(std::tuple const &t) + { + using indexes = std::make_index_sequence; + + m_buffer.reserve(budget_tuple(t, indexes{})); + append_tuple(t, indexes{}); + } + + /// Write raw COPY line into @c m_buffer, based on varargs fields. + template void fill_buffer(const Ts &...fields) + { + (..., append_to_buffer(fields)); + } + + constexpr static std::string_view s_classname{"stream_to"}; +}; + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Columns const &columns) : + stream_to{tx, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Iter columns_begin, + Iter columns_end) : + stream_to{ + tx, + tx.quote_name( + table_name, + separated_list(",", columns_begin, columns_end, [&tx](auto col) { + return tx.quote_name(*col); + }))} +{} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/subtransaction b/ext/libpqxx-7.7.3/include/pqxx/subtransaction new file mode 100644 index 0000000..e0d1549 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/subtransaction @@ -0,0 +1,8 @@ +/** pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one inside a transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx new file mode 100644 index 0000000..e66b7a7 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/subtransaction.hxx @@ -0,0 +1,96 @@ +/* Definition of the pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one within a transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/subtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SUBTRANSACTION +#define PQXX_H_SUBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx +{ +/** + * @ingroup transactions + */ +/// "Transaction" nested within another transaction +/** A subtransaction can be executed inside a backend transaction, or inside + * another subtransaction. This can be useful when, for example, statements in + * a transaction may harmlessly fail and you don't want them to abort the + * entire transaction. Here's an example of how a temporary table may be + * dropped before re-creating it, without failing if the table did not exist: + * + * ```cxx + * void do_job(connection &C) + * { + * string const temptable = "fleetingtable"; + * + * work W(C, "do_job"); + * do_firstpart(W); + * + * // Attempt to delete our temporary table if it already existed. + * try + * { + * subtransaction S(W, "droptemp"); + * S.exec0("DROP TABLE " + temptable); + * S.commit(); + * } + * catch (undefined_table const &) + * { + * // Table did not exist. Which is what we were hoping to achieve anyway. + * // Carry on without regrets. + * } + * + * // S may have gone into a failed state and been destroyed, but the + * // upper-level transaction W is still fine. We can continue to use it. + * W.exec0("CREATE TEMP TABLE " + temptable + "(bar integer, splat + * varchar)"); + * + * do_lastpart(W); + * } + * ``` + * + * (This is just an example. If you really wanted to do drop a table without + * an error if it doesn't exist, you'd use DROP TABLE IF EXISTS.) + * + * There are no isolation levels inside a transaction. They are not needed + * because all actions within the same backend transaction are always performed + * sequentially anyway. + * + * @warning While the subtransaction is "live," you cannot execute queries or + * open streams etc. on its parent transaction. A transaction can have at most + * one object of a type derived from @ref pqxx::transaction_focus active on it + * at a time. + */ +class PQXX_LIBEXPORT subtransaction : public transaction_focus, + public dbtransaction +{ +public: + /// Nest a subtransaction nested in another transaction. + explicit subtransaction(dbtransaction &t, std::string_view tname = ""sv); + + /// Nest a subtransaction in another subtransaction. + explicit subtransaction(subtransaction &t, std::string_view name = ""sv); + + virtual ~subtransaction() noexcept override; + +private: + std::string quoted_name() const + { + return quote_name(transaction_focus::name()); + } + virtual void do_commit() override; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/time b/ext/libpqxx-7.7.3/include/pqxx/time new file mode 100644 index 0000000..85df057 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/time @@ -0,0 +1,6 @@ +/** Date/time string conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/time.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/time.hxx b/ext/libpqxx-7.7.3/include/pqxx/time.hxx new file mode 100644 index 0000000..effed05 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/time.hxx @@ -0,0 +1,88 @@ +/** Support for date/time values. + * + * At the moment this supports dates, but not times. + */ +#ifndef PQXX_H_TIME +#define PQXX_H_TIME + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/strconv.hxx" + + +#if defined(PQXX_HAVE_YEAR_MONTH_DAY) + +namespace pqxx +{ +using namespace std::literals; + +template<> +struct nullness + : no_null +{}; + + +/// String representation for a Gregorian date in ISO-8601 format. +/** @warning Experimental. There may still be design problems, particularly + * when it comes to BC years. + * + * PostgreSQL supports a choice of date formats, but libpqxx does not. The + * other formats in turn support a choice of "month before day" versus "day + * before month," meaning that it's not necessarily known which format a given + * date is supposed to be. So I repeat: ISO-8601-style format only! + * + * Invalid dates will not convert. This includes February 29 on non-leap + * years, which is why it matters that `year_month_day` represents a + * _Gregorian_ date. + * + * The range of years is limited. At the time of writing, PostgreSQL 14 + * supports years from 4713 BC to 294276 AD inclusive, and C++20 supports + * a range of 32767 BC to 32767 AD inclusive. So in practice, years must fall + * between 4713 BC and 32767 AD, inclusive. + * + * @warning Support for BC (or BCE) years is still experimental. I still need + * confirmation on this issue: it looks as if C++ years are astronomical years, + * which means they have a Year Zero. Regular BC/AD years do not have a year + * zero, so the year 1 AD follows directly after 1 BC. + * + * So, what to our calendars (and to PostgreSQL) is the year "0001 BC" seems to + * count as year "0" in a `std::chrono::year_month_day`. The year 0001 AD is + * still equal to 1 as you'd expect, and all AD years work normally, but all + * years before then are shifted by one. For instance, the year 543 BC would + * be -542 in C++. + */ +template<> struct PQXX_LIBEXPORT string_traits +{ + [[nodiscard]] static zview + to_buf(char *begin, char *end, std::chrono::year_month_day const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::chrono::year_month_day const &value); + + [[nodiscard]] static std::chrono::year_month_day + from_string(std::string_view text); + + [[nodiscard]] static std::size_t + size_buffer(std::chrono::year_month_day const &) noexcept + { + static_assert(int{(std::chrono::year::min)()} >= -99999); + static_assert(int{(std::chrono::year::max)()} <= 99999); + return 5 + 1 + 2 + 1 + 2 + std::size(s_bc) + 1; + } + +private: + /// The "BC" suffix for years before 1 AD. + static constexpr std::string_view s_bc{" BC"sv}; +}; +} // namespace pqxx +#endif // PQXX_HAVE_YEAR_MONTH_DAY +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction b/ext/libpqxx-7.7.3/include/pqxx/transaction new file mode 100644 index 0000000..a7ae39d --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction @@ -0,0 +1,8 @@ +/** pqxx::transaction class. + * + * pqxx::transaction represents a standard database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction.hxx b/ext/libpqxx-7.7.3/include/pqxx/transaction.hxx new file mode 100644 index 0000000..e90917e --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction.hxx @@ -0,0 +1,108 @@ +/* Definition of the pqxx::transaction class. + * pqxx::transaction represents a standard database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION +#define PQXX_H_TRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref transaction class template. +class PQXX_LIBEXPORT basic_transaction : public dbtransaction +{ +protected: + basic_transaction( + connection &c, zview begin_command, std::string_view tname); + basic_transaction(connection &c, zview begin_command, std::string &&tname); + basic_transaction(connection &c, zview begin_command); + + virtual ~basic_transaction() noexcept override = 0; + +private: + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + */ +//@{ + +/// Standard back-end transaction, templatised on isolation level. +/** This is the type you'll normally want to use to represent a transaction on + * the database. + * + * Usage example: double all wages. + * + * ```cxx + * extern connection C; + * work T(C); + * try + * { + * T.exec0("UPDATE employees SET wage=wage*2"); + * T.commit(); // NOTE: do this inside try block + * } + * catch (exception const &e) + * { + * cerr << e.what() << endl; + * T.abort(); // Usually not needed; same happens when T's life ends. + * } + * ``` + */ +template< + isolation_level ISOLATION = isolation_level::read_committed, + write_policy READWRITE = write_policy::read_write> +class transaction final : public internal::basic_transaction +{ +public: + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * @param tname Optional name for transaction. Must begin with a letter and + * may contain letters and digits only. + */ + transaction(connection &c, std::string_view tname) : + internal::basic_transaction{ + c, internal::begin_cmd, tname} + {} + + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * may contain letters and digits only. + */ + explicit transaction(connection &c) : + internal::basic_transaction{ + c, internal::begin_cmd} + {} + + virtual ~transaction() noexcept override { close(); } +}; + + +/// The default transaction type. +using work = transaction<>; + +/// Read-only transaction. +using read_transaction = + transaction; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction_base b/ext/libpqxx-7.7.3/include/pqxx/transaction_base new file mode 100644 index 0000000..c39219a --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction_base @@ -0,0 +1,9 @@ +/** Base for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction_base.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx b/ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx new file mode 100644 index 0000000..4363cc5 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction_base.hxx @@ -0,0 +1,810 @@ +/* Common code and definitions for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_BASE +#define PQXX_H_TRANSACTION_BASE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +/* End-user programs need not include this file, unless they define their own + * transaction classes. This is not something the typical program should want + * to do. + * + * However, reading this file is worthwhile because it defines the public + * interface for the available transaction classes such as transaction and + * nontransaction. + */ + +#include "pqxx/connection.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/util.hxx" + +namespace pqxx::internal::gate +{ +class transaction_subtransaction; +class transaction_sql_cursor; +class transaction_stream_to; +class transaction_transaction_focus; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +using namespace std::literals; + + +class transaction_focus; + + +/** + * @defgroup transactions Transaction classes + * + * All database access goes through instances of these classes. + * However, not all implementations of this interface need to provide full + * transactional integrity. + * + * Several implementations of this interface are shipped with libpqxx, + * including the plain transaction class, the entirely unprotected + * nontransaction, and the more cautious robusttransaction. + */ + +/// Interface definition (and common code) for "transaction" classes. +/** + * @ingroup transactions + * + * Abstract base class for all transaction types. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base +{ +public: + transaction_base() = delete; + transaction_base(transaction_base const &) = delete; + transaction_base(transaction_base &&) = delete; + transaction_base &operator=(transaction_base const &) = delete; + transaction_base &operator=(transaction_base &&) = delete; + + virtual ~transaction_base() = 0; + + /// Commit the transaction. + /** Make the effects of this transaction definite. If you destroy a + * transaction without invoking its @ref commit() first, that will implicitly + * abort it. (For the @ref nontransaction class though, "commit" and "abort" + * really don't do anything, hence its name.) + * + * There is, however, a minute risk that you might lose your connection to + * the database at just the wrong moment here. In that case, libpqxx may be + * unable to determine whether the database was able to complete the + * transaction, or had to roll it back. In that scenario, @ref commit() will + * throw an in_doubt_error. There is a different transaction class called + * @ref robusttransaction which takes some special precautions to reduce this + * risk. + */ + void commit(); + + /// Abort the transaction. + /** No special effort is required to call this function; it will be called + * implicitly when the transaction is destructed. + */ + void abort(); + + /** + * @ingroup escaping-functions + * + * Use these when writing SQL queries that incorporate C++ values as SQL + * constants. + * + * The functions you see here are just convenience shortcuts to the same + * functions on the connection object. + */ + //@{ + /// Escape string for use as SQL string literal in this transaction. + template [[nodiscard]] auto esc(ARGS &&...args) const + { + return conn().esc(std::forward(args)...); + } + + /// Escape binary data for use as SQL string literal in this transaction. + /** Raw, binary data is treated differently from regular strings. Binary + * strings are never interpreted as text, so they may safely include byte + * values or byte sequences that don't happen to represent valid characters + * in the character encoding being used. + * + * The binary string does not stop at the first zero byte, as is the case + * with textual strings. Instead, it may contain zero bytes anywhere. If + * it happens to contain bytes that look like quote characters, or other + * things that can disrupt their use in SQL queries, they will be replaced + * with special escape sequences. + */ + template [[nodiscard]] auto esc_raw(ARGS &&...args) const + { + return conn().esc_raw(std::forward(args)...); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(zview text) + { + return conn().unesc_bin(text); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const *text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(char const text[]) + { + return conn().unesc_bin(text); + } + + /// Represent object as SQL string, including quoting & escaping. + /** Nulls are recognized and represented as SQL nulls. */ + template [[nodiscard]] std::string quote(T const &t) const + { + return conn().quote(t); + } + + [[deprecated( + "Use std::basic_string instead of binarystring.")]] std::string + quote(binarystring const &t) const + { + return conn().quote(t.bytes_view()); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const + { + return quote(binary_cast(bin, len)); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(zview bin) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Binary-escape and quote a binary string for use as an SQL constant. + /** For binary data you can also just use @ref quote(data). */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return conn().quote_raw(data); + } +#endif + + /// Escape an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const + { + return conn().quote_name(identifier); + } + + /// Escape string for literal LIKE match. + [[nodiscard]] std::string + esc_like(std::string_view bin, char escape_char = '\\') const + { + return conn().esc_like(bin, escape_char); + } + //@} + + /** + * @name Command execution + * + * There are many functions for executing (or "performing") a command (or + * "query"). This is the most fundamental thing you can do with the library, + * and you always do it from a transaction class. + * + * Command execution can throw many types of exception, including sql_error, + * broken_connection, and many sql_error subtypes such as + * feature_not_supported or insufficient_privilege. But any exception thrown + * by the C++ standard library may also occur here. All exceptions you will + * see libpqxx throw are derived from std::exception. + * + * One unusual feature in libpqxx is that you can give your query a name or + * description. This does not mean anything to the database, but sometimes + * it can help libpqxx produce more helpful error messages, making problems + * in your code easier to debug. + * + * Many of the execution functions used to accept a `desc` argument, a + * human-readable description of the statement for use in error messages. + * This could make failures easier to debug. Future versions will use + * C++20's `std::source_location` to identify the failing statement. + */ + //@{ + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated("The desc parameter is going away.")]] result + exec(std::string_view query, std::string_view desc); + + /// Execute a command. + /** + * @param query Query or command to execute. + * @return A result set describing the query's or command's result. + */ + result exec(std::string_view query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated( + "Pass your query as a std::string_view, not stringstream.")]] result + exec(std::stringstream const &query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query.str(), desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec0(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(0, query, desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec0(zview query) { return exec_n(0, query); } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] row + exec1(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(1, query, desc).front(); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + row exec1(zview query) { return exec_n(1, query).front(); } + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec_n(result::size_type rows, zview query, std::string_view desc); + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec_n(result::size_type rows, zview query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(rows, query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template + [[deprecated("The desc parameter is going away.")]] TYPE + query_value(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row const r{exec1(query, desc)}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template TYPE query_value(zview query) + { + row const r{exec1(query)}; + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Execute a query, and loop over the results row by row. + /** Converts the rows to `std::tuple`, of the column types you specify. + * + * Use this with a range-based "for" loop. It executes the query, and + * directly maps the resulting rows onto a `std::tuple` of the types you + * specify. It starts before all the data from the server is in, so if your + * network connection to the server breaks while you're iterating, you'll get + * an exception partway through. + * + * The stream lives entirely within the lifetime of the transaction. Make + * sure you destroy the stream before you destroy the transaction. Either + * iterate the stream all the way to the end, or destroy first the stream + * and then the transaction without touching either in any other way. Until + * the stream has finished, the transaction is in a special state where it + * cannot execute queries. + * + * As a special case, tuple may contain `std::string_view` fields, but the + * strings to which they point will only remain valid until you extract the + * next row. After that, the memory holding the string may be overwritten or + * deallocated. + * + * If any of the columns can be null, and the C++ type to which it translates + * does not have a null value, wrap the type in `std::optional` (or if + * you prefer, `std::shared_ptr` or `std::unique_ptr)`. These templates + * do recognise null values, and libpqxx will know how to convert to them. + * + * The connection is in a special state until the iteration finishes. So if + * it does not finish due to a `break` or a `return` or an exception, then + * the entire connection becomes effectively unusable. + * + * Querying in this way is faster than the `exec()` methods for larger + * results (but slower for small ones). You can start processing rows before + * the full result is in. Also, `stream()` scales better in terms of memory + * usage. Where @ref exec() reads the entire result into memory at once, + * `stream()` will read and process one row at at a time. + * + * Your query executes as part of a COPY command, not as a stand-alone query, + * so there are limitations to what you can do in the query. It can be + * either a SELECT or VALUES query; or an INSERT, UPDATE, or DELETE with a + * RETURNING clause. See the documentation for PostgreSQL's COPY command for + * the details: + * + * https://www.postgresql.org/docs/current/sql-copy.html + * + * Iterating in this way does require each of the field types you pass to be + * default-constructible, copy-constructible, and assignable. These + * requirements may be loosened once libpqxx moves on to C++20. + */ + template + [[nodiscard]] auto stream(std::string_view query) & + { + // Tricky: std::make_unique() supports constructors but not RVO functions. + return pqxx::internal::owning_stream_input_iteration{ + std::unique_ptr{ + new stream_from{stream_from::query(*this, query)}}}; + } + + // C++20: Concept like std::invocable, but without specifying param types. + /// Perform a streaming query, and for each result row, call `func`. + /** Here, `func` can be a function, a `std::function`, a lambda, or an + * object that supports the function call operator. Of course `func` must + * have an unambiguous signature; it can't be overloaded or generic. + * + * The `for_each` function executes `query` in a stream using + * @ref pqxx::stream_from. Every time a row of data comes in from the + * server, it converts the row's fields to the types of `func`'s respective + * parameters, and calls `func` with those values. + * + * This will not work for all queries, but straightforward `SELECT` and + * `UPDATE ... RETURNING` queries should work. Consult the documentation for + * @ref pqxx::stream_from and PostgreSQL's underlying `COPY` command for the + * full details. + * + * Streaming a query like this is likely to be slower than the @ref exec() + * functions for small result sets, but faster for large result sets. So if + * performance matters, you'll want to use `for_each` if you query large + * amounts of data, but not if you do lots of queries with small outputs. + */ + template + inline auto for_each(std::string_view query, CALLABLE &&func) + { + using param_types = + pqxx::internal::strip_types_t>; + param_types const *const sample{nullptr}; + auto data_stream{stream_like(query, sample)}; + for (auto const &fields : data_stream) std::apply(func, fields); + } + + /** + * @name Parameterized statements + * + * You'll often need parameters in the queries you execute: "select the + * car with this licence plate." If the parameter is a string, you need to + * quote it and escape any special characters inside it, or it may become a + * target for an SQL injection attack. If it's an integer (for example), + * you need to convert it to a string, but in the database's format, without + * locale-specific niceties like "," separators between the thousands. + * + * Parameterised statements are an easier and safer way to do this. They're + * like prepared statements, but for a single use. You don't need to name + * them, and you don't need to prepare them first. + * + * Your query will include placeholders like `$1` and `$2` etc. in the places + * where you want the arguments to go. Then, you pass the argument values + * and the actual query is constructed for you. + * + * Pass the exact right number of parameters, and in the right order. The + * parameters in the query don't have to be neatly ordered from `$1` to + * `$2` to `$3` - but you must pass the argument for `$1` first, the one + * for `$2` second, etc. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. + */ + //@{ + /// Execute an SQL statement with parameters. + template result exec_params(zview query, Args &&...args) + { + params pp(args...); + return internal_exec_params(query, pp.make_c_params()); + } + + // Execute parameterised statement, expect a single-row result. + /** @throw unexpected_rows if the result does not consist of exactly one row. + */ + template row exec_params1(zview query, Args &&...args) + { + return exec_params_n(1, query, std::forward(args)...).front(); + } + + // Execute parameterised statement, expect a result with zero rows. + /** @throw unexpected_rows if the result contains rows. + */ + template result exec_params0(zview query, Args &&...args) + { + return exec_params_n(0, query, std::forward(args)...); + } + + // Execute parameterised statement, expect exactly a given number of rows. + /** @throw unexpected_rows if the result contains the wrong number of rows. + */ + template + result exec_params_n(std::size_t rows, zview query, Args &&...args) + { + auto const r{exec_params(query, std::forward(args)...)}; + check_rowcount_params(rows, std::size(r)); + return r; + } + //@} + + /** + * @name Prepared statements + * + * These are very similar to parameterised statements. The difference is + * that you prepare them in advance, giving them identifying names. You can + * then call them by these names, passing in the argument values appropriate + * for that call. + * + * You prepare a statement on the connection, using + * @ref pqxx::connection::prepare(). But you then call the statement in a + * transaction, using the functions you see here. + * + * Never try to prepare, execute, or unprepare a prepared statement manually + * using direct SQL queries when you also use the libpqxx equivalents. For + * any given statement, either prepare, manage, and execute it through the + * dedicated libpqxx functions; or do it all directly in SQL. Don't mix the + * two, or the code may get confused. + * + * See \ref prepared for a full discussion. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. If you need a zero byte, you're dealing with binary strings, not + * regular strings. Represent binary strings on the SQL side as `BYTEA` + * (or as large objects). On the C++ side, use types like + * `std::basic_string` or `std::basic_string_view` + * or (in C++20) `std::vector`. Also, consider large objects on + * the SQL side and @ref blob on the C++ side. + */ + //@{ + + /// Execute a prepared statement, with optional arguments. + template + result exec_prepared(zview statement, Args &&...args) + { + params pp(args...); + return internal_exec_prepared(statement, pp.make_c_params()); + } + + /// Execute a prepared statement, and expect a single-row result. + /** @throw pqxx::unexpected_rows if the result was not exactly 1 row. + */ + template + row exec_prepared1(zview statement, Args &&...args) + { + return exec_prepared_n(1, statement, std::forward(args)...).front(); + } + + /// Execute a prepared statement, and expect a result with zero rows. + /** @throw pqxx::unexpected_rows if the result contained rows. + */ + template + result exec_prepared0(zview statement, Args &&...args) + { + return exec_prepared_n(0, statement, std::forward(args)...); + } + + /// Execute a prepared statement, expect a result with given number of rows. + /** @throw pqxx::unexpected_rows if the result did not contain exactly the + * given number of rows. + */ + template + result + exec_prepared_n(result::size_type rows, zview statement, Args &&...args) + { + auto const r{exec_prepared(statement, std::forward(args)...)}; + check_rowcount_prepared(statement, rows, std::size(r)); + return r; + } + + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Have connection process a warning message. + void process_notice(char const msg[]) const { m_conn.process_notice(msg); } + /// Have connection process a warning message. + void process_notice(zview msg) const { m_conn.process_notice(msg); } + //@} + + /// The connection in which this transaction lives. + [[nodiscard]] constexpr connection &conn() const noexcept { return m_conn; } + + /// Set session variable using SQL "SET" command. + /** @deprecated To set a transaction-local variable, execute an SQL `SET` + * command. To set a session variable, use the connection's + * @ref set_session_var function. + * + * @warning When setting a string value, you must make sure that the string + * is "safe." If you call @ref quote() on the string, it will return a + * safely escaped and quoted version for use as an SQL literal. + * + * @warning This function executes SQL. Do not try to set or get variables + * while a pipeline or table stream is active. + * + * @param var The variable to set. + * @param value The new value to store in the variable. This can be any SQL + * expression. + */ + [[deprecated( + "Set transaction-local variables using SQL SET statements.")]] void + set_variable(std::string_view var, std::string_view value); + + /// Read session variable using SQL "SHOW" command. + /** @warning This executes SQL. Do not try to set or get variables while a + * pipeline or table stream is active. + */ + [[deprecated("Read variables using SQL SHOW statements.")]] std::string + get_variable(std::string_view); + + // C++20: constexpr. + /// Transaction name, if you passed one to the constructor; or empty string. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + +protected: + /// Create a transaction (to be called by implementation classes only). + /** The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + m_conn{c}, m_name{tname}, m_rollback_cmd{rollback_cmd} + {} + + /// Create a transaction (to be called by implementation classes only). + /** Its rollback command will be "ROLLBACK". + * + * The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base(connection &c, std::string_view tname); + + /// Create a transaction (to be called by implementation classes only). + explicit transaction_base(connection &c); + + /// Register this transaction with the connection. + void register_transaction(); + + /// End transaction. To be called by implementing class' destructor. + void close() noexcept; + + /// To be implemented by derived implementation class: commit transaction. + virtual void do_commit() = 0; + + /// Transaction type-specific way of aborting a transaction. + /** @warning This will become "final", since this function can be called + * from the implementing class destructor. + */ + virtual void do_abort(); + + /// Set the rollback command. + void set_rollback_cmd(std::shared_ptr cmd) + { + m_rollback_cmd = cmd; + } + + /// Execute query on connection directly. + result direct_exec(std::string_view, std::string_view desc = ""sv); + result + direct_exec(std::shared_ptr, std::string_view desc = ""sv); + +private: + enum class status + { + active, + aborted, + committed, + in_doubt + }; + + PQXX_PRIVATE void check_pending_error(); + + result + internal_exec_prepared(zview statement, internal::c_params const &args); + + result internal_exec_params(zview query, internal::c_params const &args); + + /// Throw unexpected_rows if prepared statement returned wrong no. of rows. + void check_rowcount_prepared( + zview statement, result::size_type expected_rows, + result::size_type actual_rows); + + /// Throw unexpected_rows if wrong row count from parameterised statement. + void + check_rowcount_params(std::size_t expected_rows, std::size_t actual_rows); + + /// Describe this transaction to humans, e.g. "transaction 'foo'". + [[nodiscard]] std::string description() const; + + friend class pqxx::internal::gate::transaction_transaction_focus; + PQXX_PRIVATE void register_focus(transaction_focus *); + PQXX_PRIVATE void unregister_focus(transaction_focus *) noexcept; + PQXX_PRIVATE void register_pending_error(zview) noexcept; + PQXX_PRIVATE void register_pending_error(std::string &&) noexcept; + + /// Like @ref stream(), but takes a tuple rather than a parameter pack. + template + auto stream_like(std::string_view query, std::tuple const *) + { + return stream(query); + } + + connection &m_conn; + + /// Current "focus": a pipeline, a nested transaction, a stream... + /** This pointer is used for only one purpose: sanity checks against mistakes + * such as opening one while another is still active. + */ + transaction_focus const *m_focus = nullptr; + + status m_status = status::active; + bool m_registered = false; + std::string m_name; + std::string m_pending_error; + + /// SQL command for aborting this type of transaction. + std::shared_ptr m_rollback_cmd; + + static constexpr std::string_view s_type_name{"transaction"sv}; +}; + + +// C++20: Can borrowed_range help? +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +std::string_view transaction_base::query_value( + zview query, std::string_view desc) = delete; +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +zview transaction_base::query_value( + zview query, std::string_view desc) = delete; + +} // namespace pqxx + + +namespace pqxx::internal +{ +/// The SQL command for starting a given type of transaction. +template +extern const zview begin_cmd; + +// These are not static members, so "constexpr" does not imply "inline". +template<> +inline constexpr zview begin_cmd{ + "BEGIN"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY"_zv}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction_focus b/ext/libpqxx-7.7.3/include/pqxx/transaction_focus new file mode 100644 index 0000000..fe78a9b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction_focus @@ -0,0 +1,7 @@ +/** + * Transaction focus: types which monopolise a transaction's attention. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx b/ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx new file mode 100644 index 0000000..0707e3c --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transaction_focus.hxx @@ -0,0 +1,89 @@ +/** Transaction focus: types which monopolise a transaction's attention. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_FOCUS +#define PQXX_H_TRANSACTION_FOCUS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Base class for things that monopolise a transaction's attention. +/** You probably won't need to use this class. But it can be useful to _know_ + * that a given libpqxx class is derived from it. + * + * Pipelines, SQL statements, and data streams are examples of classes derived + * from `transaction_focus`. For any given transaction, only one object of + * such a class can be active at any given time. + */ +class PQXX_LIBEXPORT transaction_focus +{ +public: + transaction_focus( + transaction_base &t, std::string_view cname, std::string_view oname) : + m_trans{t}, m_classname{cname}, m_name{oname} + {} + + transaction_focus( + transaction_base &t, std::string_view cname, std::string &&oname) : + m_trans{t}, m_classname{cname}, m_name{std::move(oname)} + {} + + transaction_focus(transaction_base &t, std::string_view cname) : + m_trans{t}, m_classname{cname} + {} + + transaction_focus() = delete; + transaction_focus(transaction_focus const &) = delete; + transaction_focus &operator=(transaction_focus const &) = delete; + + /// Class name, for human consumption. + [[nodiscard]] constexpr std::string_view classname() const noexcept + { + return m_classname; + } + + /// Name for this object, if the caller passed one; empty string otherwise. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + + [[nodiscard]] std::string description() const + { + return pqxx::internal::describe_object(m_classname, m_name); + } + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus(transaction_focus &&) = delete; + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus &operator=(transaction_focus &&) = delete; + +protected: + void register_me(); + void unregister_me() noexcept; + void reg_pending_error(std::string const &) noexcept; + bool registered() const noexcept { return m_registered; } + + transaction_base &m_trans; + +private: + bool m_registered = false; + std::string_view m_classname; + std::string m_name; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/transactor b/ext/libpqxx-7.7.3/include/pqxx/transactor new file mode 100644 index 0000000..29d1b96 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transactor @@ -0,0 +1,8 @@ +/** pqxx::transactor class. + * + * pqxx::transactor is a framework-style wrapper for safe transactions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transactor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/transactor.hxx b/ext/libpqxx-7.7.3/include/pqxx/transactor.hxx new file mode 100644 index 0000000..eefd04b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/transactor.hxx @@ -0,0 +1,147 @@ +/* Transactor framework, a wrapper for safely retryable transactions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTOR +#define PQXX_H_TRANSACTOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +/** + * @defgroup transactor Transactor framework + * + * Sometimes a transaction can fail for completely transient reasons, such as a + * conflict with another transaction in SERIALIZABLE isolation. The right way + * to handle those failures is often just to re-run the transaction from + * scratch. + * + * For example, your REST API might be handling each HTTP request in its own + * database transaction, and if this kind of transient failure happens, you + * simply want to "replay" the whole request, in a fresh transaction. + * + * You won't necessarily want to execute the exact same SQL commands with the + * exact same data. Some of your SQL statements may depend on state that can + * vary between retries. Data in the database may already have changed, for + * instance. So instead of dumbly replaying the SQL, you re-run the same + * application code that produced those SQL commands, from the start. + * + * The transactor framework makes it a little easier for you to do this safely, + * and avoid typical pitfalls. You encapsulate the work that you want to do + * into a callable that you pass to the @ref perform function. + * + * Here's how it works. You write your transaction code as a lambda or + * function, which creates its own transaction object, does its work, and + * commits at the end. You pass that callback to @ref pqxx::perform, which + * runs it for you. + * + * If there's a failure inside your callback, there will be an exception. Your + * transaction object goes out of scope and gets destroyed, so that it aborts + * implicitly. Seeing this, @ref perform tries running your callback again. It + * stops doing that when the callback succeeds, or when it has failed too many + * times, or when there's an error that leaves the database in an unknown + * state, such as a lost connection just while we're waiting for the database + * to confirm a commit. It all depends on the type of exception. + * + * The callback takes no arguments. If you're using lambdas, the easy way to + * pass arguments is for the lambda to "capture" them from your variables. Or, + * if you're using functions, you may want to use `std::bind`. + * + * Once your callback succeeds, it can return a result, and @ref perform will + * return that result back to you. + */ +//@{ + +/// Simple way to execute a transaction with automatic retry. +/** + * Executes your transaction code as a callback. Repeats it until it completes + * normally, or it throws an error other than the few libpqxx-generated + * exceptions that the framework understands, or after a given number of failed + * attempts, or if the transaction ends in an "in-doubt" state. + * + * (An in-doubt state is one where libpqxx cannot determine whether the server + * finally committed a transaction or not. This can happen if the network + * connection to the server is lost just while we're waiting for its reply to + * a "commit" statement. The server may have completed the commit, or not, but + * it can't tell you because there's no longer a connection. + * + * Using this still takes a bit of care. If your callback makes use of data + * from the database, you'll probably have to query that data within your + * callback. If the attempt to perform your callback fails, and the framework + * tries again, you'll be in a new transaction and the data in the database may + * have changed under your feet. + * + * Also be careful about changing variables or data structures from within + * your callback. The run may still fail, and perhaps get run again. The + * ideal way to do it (in most cases) is to return your result from your + * callback, and change your program's data state only after @ref perform + * completes successfully. + * + * @param callback Transaction code that can be called with no arguments. + * @param attempts Maximum number of times to attempt performing callback. + * Must be greater than zero. + * @return Whatever your callback returns. + */ +template +inline auto perform(TRANSACTION_CALLBACK &&callback, int attempts = 3) + -> std::invoke_result_t +{ + if (attempts <= 0) + throw std::invalid_argument{ + "Zero or negative number of attempts passed to pqxx::perform()."}; + + for (; attempts > 0; --attempts) + { + try + { + return std::invoke(callback); + } + catch (in_doubt_error const &) + { + // Not sure whether transaction went through or not. The last thing in + // the world that we should do now is try again! + throw; + } + catch (statement_completion_unknown const &) + { + // Not sure whether our last statement succeeded. Don't risk running it + // again. + throw; + } + catch (broken_connection const &) + { + // Connection failed. May be worth retrying, if the transactor opens its + // own connection. + if (attempts <= 1) + throw; + continue; + } + catch (transaction_rollback const &) + { + // Some error that may well be transient, such as serialization failure + // or deadlock. Worth retrying. + if (attempts <= 1) + throw; + continue; + } + } + throw pqxx::internal_error{"No outcome reached on perform()."}; +} +} // namespace pqxx +//@} +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/types b/ext/libpqxx-7.7.3/include/pqxx/types new file mode 100644 index 0000000..23a5caa --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/types @@ -0,0 +1,7 @@ +/** + * Basic typedefs and forward declarations. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/types.hxx b/ext/libpqxx-7.7.3/include/pqxx/types.hxx new file mode 100644 index 0000000..f95b598 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/types.hxx @@ -0,0 +1,173 @@ +/* Basic type aliases and forward declarations. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TYPES +#define PQXX_H_TYPES + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + + +namespace pqxx +{ +/// Number of rows in a result set. +using result_size_type = int; + +/// Difference between result sizes. +using result_difference_type = int; + +/// Number of fields in a row of database data. +using row_size_type = int; + +/// Difference between row sizes. +using row_difference_type = int; + +/// Number of bytes in a field of database data. +using field_size_type = std::size_t; + +/// Number of bytes in a large object. +using large_object_size_type = int64_t; + + +// Forward declarations, to help break compilation dependencies. +// These won't necessarily include all classes in libpqxx. +class binarystring; +class connection; +class const_result_iterator; +class const_reverse_result_iterator; +class const_reverse_row_iterator; +class const_row_iterator; +class dbtransaction; +class field; +class largeobjectaccess; +class notification_receiver; +struct range_error; +class result; +class row; +class stream_from; +class transaction_base; + +/// Marker for @ref stream_from constructors: "stream from table." +/** @deprecated Use @ref stream_from::table() instead. + */ +struct from_table_t +{}; + +/// Marker for @ref stream_from constructors: "stream from query." +/** @deprecated Use @ref stream_from::query() instead. + */ +struct from_query_t +{}; + + +/// Format code: is data text or binary? +/** Binary-compatible with libpq's format codes. + */ +enum class format : int +{ + text = 0, + binary = 1, +}; + + +/// Remove any constness, volatile, and reference-ness from a type. +/** @deprecated In C++20 we'll replace this with std::remove_cvref. + */ +template +using strip_t = std::remove_cv_t>; + + +#if defined(PQXX_HAVE_CONCEPTS) +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#else // PQXX_HAVE_CONCEPTS +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#endif // PQXX_HAVE_CONCEPTS + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Any type that we can read as a string of `char`. +template +concept char_string = std::ranges::contiguous_range and + std::same_as < strip_t>, +char > ; + +/// Concept: Anything we can iterate to get things we can read as strings. +template +concept char_strings = + std::ranges::range and char_string>>; + +/// Concept: Anything we might want to treat as binary data. +template +concept potential_binary = std::ranges::contiguous_range and + (sizeof(value_type) == 1); +#endif // PQXX_HAVE_CONCEPTS + + +// C++20: Retire these compatibility definitions. +#if defined(PQXX_HAVE_CONCEPTS) + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG std::ranges::range + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG pqxx::char_string + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG pqxx::char_strings + +#else // PQXX_HAVE_CONCEPTS + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG typename + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG typename + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG typename + +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/util b/ext/libpqxx-7.7.3/include/pqxx/util new file mode 100644 index 0000000..6d85ab6 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/util @@ -0,0 +1,6 @@ +/** Various utility definitions for libpqxx. + */ +// Actual definitions in .hxx file so editors and such recognize file type +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/util.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/util.hxx b/ext/libpqxx-7.7.3/include/pqxx/util.hxx new file mode 100644 index 0000000..4aa5ecf --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/util.hxx @@ -0,0 +1,521 @@ +/* Various utility definitions for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_UTIL +#define PQXX_H_UTIL + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/internal/encodings.hxx" +#include "pqxx/types.hxx" +#include "pqxx/version.hxx" + + +/// The home of all libpqxx classes, functions, templates, etc. +namespace pqxx +{} + +#include + + +/// Internal items for libpqxx' own use. Do not use these yourself. +namespace pqxx::internal +{ + +// C++20: Retire wrapper. +/// Same as `std::cmp_less`, or a workaround where that's not available. +template +inline constexpr bool cmp_less(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less(lhs, rhs); +#else + // We need a variable just because lgtm.com gives off a false positive + // warning when we compare the values directly. It considers that a + // "self-comparison." + constexpr bool left_signed{std::is_signed_v}; + if constexpr (left_signed == std::is_signed_v) + return lhs < rhs; + else if constexpr (std::is_signed_v) + return (lhs <= 0) ? true : (std::make_unsigned_t(lhs) < rhs); + else + return (rhs <= 0) ? false : (lhs < std::make_unsigned_t(rhs)); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater, or workaround if not available. +template +inline constexpr bool cmp_greater(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater(lhs, rhs); +#else + return cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_less_equal, or workaround if not available. +template +inline constexpr bool cmp_less_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less_equal(lhs, rhs); +#else + return not cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater_equal, or workaround if not available. +template +inline constexpr bool cmp_greater_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater_equal(lhs, rhs); +#else + return not cmp_less(lhs, rhs); +#endif +} + + +/// Efficiently concatenate two strings. +/** This is a special case of concatenate(), needed because dependency + * management does not let us use that function here. + */ +[[nodiscard]] inline std::string cat2(std::string_view x, std::string_view y) +{ + std::string buf; + auto const xs{std::size(x)}, ys{std::size(y)}; + buf.resize(xs + ys); + x.copy(std::data(buf), xs); + y.copy(std::data(buf) + xs, ys); + return buf; +} +} // namespace pqxx::internal + + +namespace pqxx +{ +using namespace std::literals; + +/// Suppress compiler warning about an unused item. +template inline constexpr void ignore_unused(T &&...) noexcept +{} + + +/// Cast a numeric value to another type, or throw if it underflows/overflows. +/** Both types must be arithmetic types, and they must either be both integral + * or both floating-point types. + */ +template +inline TO check_cast(FROM value, std::string_view description) +{ + static_assert(std::is_arithmetic_v); + static_assert(std::is_arithmetic_v); + static_assert(std::is_integral_v == std::is_integral_v); + + // The rest of this code won't quite work for bool, but bool is trivially + // convertible to other arithmetic types as far as I can see. + if constexpr (std::is_same_v) + return static_cast(value); + + // Depending on our "if constexpr" conditions, this parameter may not be + // needed. Some compilers will warn. + ignore_unused(description); + + using from_limits = std::numeric_limits; + using to_limits = std::numeric_limits; + if constexpr (std::is_signed_v) + { + if constexpr (std::is_signed_v) + { + if (value < to_limits::lowest()) + throw range_error{internal::cat2("Cast underflow: "sv, description)}; + } + else + { + // FROM is signed, but TO is not. Treat this as a special case, because + // there may not be a good broader type in which the compiler can even + // perform our check. + if (value < 0) + throw range_error{internal::cat2( + "Casting negative value to unsigned type: "sv, description)}; + } + } + else + { + // No need to check: the value is unsigned so can't fall below the range + // of the TO type. + } + + if constexpr (std::is_integral_v) + { + using unsigned_from = std::make_unsigned_t; + using unsigned_to = std::make_unsigned_t; + constexpr auto from_max{static_cast((from_limits::max)())}; + constexpr auto to_max{static_cast((to_limits::max)())}; + if constexpr (from_max > to_max) + { + if (internal::cmp_greater(value, to_max)) + throw range_error{internal::cat2("Cast overflow: "sv, description)}; + } + } + else if constexpr ((from_limits::max)() > (to_limits::max)()) + { + if (value > (to_limits::max)()) + throw range_error{internal::cat2("Cast overflow: ", description)}; + } + + return static_cast(value); +} + + +/** Check library version at link time. + * + * Ensures a failure when linking an application against a radically + * different libpqxx version than the one against which it was compiled. + * + * Sometimes application builds fail in unclear ways because they compile + * using headers from libpqxx version X, but then link against libpqxx + * binary version Y. A typical scenario would be one where you're building + * against a libpqxx which you have built yourself, but a different version + * is installed on the system. + * + * The check_library_version template is declared for any library version, + * but only actually defined for the version of the libpqxx binary against + * which the code is linked. + * + * If the library binary is a different version than the one declared in + * these headers, then this call will fail to link: there will be no + * definition for the function with these exact template parameter values. + * There will be a definition, but the version in the parameter values will + * be different. + */ +inline PQXX_PRIVATE void check_version() noexcept +{ + // There is no particular reason to do this here in @ref connection, except + // to ensure that every meaningful libpqxx client will execute it. The call + // must be in the execution path somewhere or the compiler won't try to link + // it. We can't use it to initialise a global or class-static variable, + // because a smart compiler might resolve it at compile time. + // + // On the other hand, we don't want to make a useless function call too + // often for performance reasons. A local static variable is initialised + // only on the definition's first execution. Compilers will be well + // optimised for this behaviour, so there's a minimal one-time cost. + static auto const version_ok{internal::PQXX_VERSION_CHECK()}; + ignore_unused(version_ok); +} + + +/// Descriptor of library's thread-safety model. +/** This describes what the library knows about various risks to thread-safety. + */ +struct PQXX_LIBEXPORT thread_safety_model +{ + /// Is the underlying libpq build thread-safe? + bool safe_libpq = false; + + /// Is Kerberos thread-safe? + /** @warning Is currently always `false`. + * + * If your application uses Kerberos, all accesses to libpqxx or Kerberos + * must be serialized. Confine their use to a single thread, or protect it + * with a global lock. + */ + bool safe_kerberos = false; + + /// A human-readable description of any thread-safety issues. + std::string description; +}; + + +/// Describe thread safety available in this build. +[[nodiscard]] PQXX_LIBEXPORT thread_safety_model describe_thread_safety(); + + +#if defined(PQXX_HAVE_CONCEPTS) +# define PQXX_POTENTIAL_BINARY_ARG pqxx::potential_binary +#else +# define PQXX_POTENTIAL_BINARY_ARG typename +#endif + + +/// Cast binary data to a type that libpqxx will recognise as binary. +/** There are many different formats for storing binary data in memory. You + * may have yours as a `std::string`, or a `std::vector`, or one of + * many other types. + * + * But for libpqxx to recognise your data as binary, it needs to be a + * `std::basic_string`, or a `std::basic_string_view`; + * or in C++20 or better, any contiguous block of `std::byte`. + * + * Use `binary_cast` as a convenience helper to cast your data as a + * `std::basic_string_view`. + * + * @warning There are two things you should be aware of! First, the data must + * be contiguous in memory. In C++20 the compiler will enforce this, but in + * C++17 it's your own problem. Second, you must keep the object where you + * store the actual data alive for as long as you might use this function's + * return value. + */ +template +std::basic_string_view binary_cast(TYPE const &data) +{ + static_assert(sizeof(value_type) == 1); + return { + reinterpret_cast( + const_cast const *>( + std::data(data))), + std::size(data)}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +concept char_sized = (sizeof(CHAR) == 1); +# define PQXX_CHAR_SIZED_ARG char_sized +#else +# define PQXX_CHAR_SIZED_ARG typename +#endif + +/// Construct a type that libpqxx will recognise as binary. +/** Takes a data pointer and a size, without being too strict about their + * types, and constructs a `std::basic_string_view` pointing to + * the same data. + * + * This makes it a little easier to turn binary data, in whatever form you + * happen to have it, into binary data as libpqxx understands it. + */ +template +std::basic_string_view binary_cast(CHAR const *data, SIZE size) +{ + static_assert(sizeof(CHAR) == 1); + return { + reinterpret_cast(data), + check_cast(size, "binary data size")}; +} + + +/// The "null" oid. +constexpr oid oid_none{0}; +} // namespace pqxx + + +/// Private namespace for libpqxx's internal use; do not access. +/** This namespace hides definitions internal to libpqxx. These are not + * supposed to be used by client programs, and they may change at any time + * without notice. + * + * Conversely, if you find something in this namespace tremendously useful, by + * all means do lodge a request for its publication. + * + * @warning Here be dragons! + */ +namespace pqxx::internal +{ +using namespace std::literals; + + +/// A safer and more generic replacement for `std::isdigit`. +/** Turns out `std::isdigit` isn't as easy to use as it sounds. It takes an + * `int`, but requires it to be nonnegative. Which means it's an outright + * liability on systems where `char` is signed. + */ +template inline constexpr bool is_digit(CHAR c) noexcept +{ + return (c >= '0') and (c <= '9'); +} + + +/// Describe an object for humans, based on class name and optional name. +/** Interprets an empty name as "no name given." + */ +[[nodiscard]] std::string +describe_object(std::string_view class_name, std::string_view name); + + +/// Check validity of registering a new "guest" in a "host." +/** The host might be e.g. a connection, and the guest a transaction. The + * host can only have one guest at a time, so it is an error to register a new + * guest while the host already has a guest. + * + * If the new registration is an error, this function throws a descriptive + * exception. + * + * Pass the old guest (if any) and the new guest (if any), for both, a type + * name (at least if the guest is not null), and optionally an object name + * (but which may be omitted if the caller did not assign one). + */ +void check_unique_register( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Like @ref check_unique_register, but for un-registering a guest. +/** Pass the guest which was registered, as well as the guest which is being + * unregistered, so that the function can check that they are the same one. + */ +void check_unique_unregister( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Compute buffer size needed to escape binary data for use as a BYTEA. +/** This uses the hex-escaping format. The return value includes room for the + * "\x" prefix. + */ +inline constexpr std::size_t size_esc_bin(std::size_t binary_bytes) noexcept +{ + return 2 + (2 * binary_bytes) + 1; +} + + +/// Compute binary size from the size of its escaped version. +/** Do not include a terminating zero in `escaped_bytes`. + */ +inline constexpr std::size_t size_unesc_bin(std::size_t escaped_bytes) noexcept +{ + return (escaped_bytes - 2) / 2; +} + + +// TODO: Use actual binary type for "data". +/// Hex-escape binary data into a buffer. +/** The buffer must be able to accommodate + * `size_esc_bin(std::size(binary_data))` bytes, and the function will write + * exactly that number of bytes into the buffer. This includes a trailing + * zero. + */ +void PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data, char buffer[]) noexcept; + + +/// Hex-escape binary data into a std::string. +std::string PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data); + + +/// Reconstitute binary data from its escaped version. +void PQXX_LIBEXPORT +unesc_bin(std::string_view escaped_data, std::byte buffer[]); + + +/// Reconstitute binary data from its escaped version. +std::basic_string + PQXX_LIBEXPORT unesc_bin(std::string_view escaped_data); + + +/// Transitional: std::ssize(), or custom implementation if not available. +template auto ssize(T const &c) +{ +#if defined(__cpp_lib_ssize) && __cplusplus >= __cpp_lib_ssize + return std::ssize(c); +#else + using signed_t = std::make_signed_t; + return static_cast(std::size(c)); +#endif // __cpp_lib_ssize +} + + +/// Helper for determining a function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(RETURN (&func)(ARGS...)); + + +/// Helper for determining a `std::function`'s parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(std::function const &); + + +/// Helper for determining a member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...)); + + +/// Helper for determining a const member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...) const); + + +/// Helper for determining a callable type's parameter types. +/** This specialisation should work for lambdas. + * + * This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +auto args_f(CALLABLE const &f) + -> decltype(member_args_f(&CALLABLE::operator())); + + +/// A callable's parameter types, as a tuple. +template +using args_t = decltype(args_f(std::declval())); + + +/// Helper: Apply `strip_t` to each of a tuple type's component types. +/** This function has no definition. It is not meant to be called, only to be + * used to deduce the right types. + */ +template +std::tuple...> strip_types(std::tuple const &); + + +/// Take a tuple type and apply @ref strip_t to its component types. +template +using strip_types_t = decltype(strip_types(std::declval())); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/version b/ext/libpqxx-7.7.3/include/pqxx/version new file mode 100644 index 0000000..8dd5e48 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/version @@ -0,0 +1,7 @@ +/** libpqxx version info. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/version.hxx" +#include "pqxx/internal/header-post.hxx" + diff --git a/ext/libpqxx-7.7.3/include/pqxx/version.hxx b/ext/libpqxx-7.7.3/include/pqxx/version.hxx new file mode 100644 index 0000000..a159f1b --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/version.hxx @@ -0,0 +1,55 @@ +/* Version info for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_VERSION + +# if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +# endif + +/// Full libpqxx version string. +# define PQXX_VERSION "7.7.3" +/// Library ABI version. +# define PQXX_ABI "7.7" + +/// Major version number. +# define PQXX_VERSION_MAJOR 7 +/// Minor version number. +# define PQXX_VERSION_MINOR 7 + +# define PQXX_VERSION_CHECK check_pqxx_version_7_7 + +namespace pqxx::internal +{ +/// Library version check stub. +/** Helps detect version mismatches between libpqxx headers and the libpqxx + * library binary. + * + * Sometimes users run into trouble linking their code against libpqxx because + * they build their own libpqxx, but the system also has a different version + * installed. The declarations in the headers against which they compile their + * code will differ from the ones used to build the libpqxx version they're + * using, leading to confusing link errors. The solution is to generate a link + * error when the libpqxx binary is not the same version as the libpqxx headers + * used to compile the code. + * + * This function's definition is in the libpqxx binary, so it's based on the + * version as found in the binary. The headers contain a call to the function, + * whose name contains the libpqxx version as found in the headers. (The + * library build process will use its own local headers even if another version + * of the headers is installed on the system.) + * + * If the libpqxx binary was compiled for a different version than the user's + * code, linking will fail with an error: `check_pqxx_version_*_*` will not + * exist for the given version number. + */ +PQXX_LIBEXPORT int PQXX_VERSION_CHECK() noexcept; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/version.hxx.template b/ext/libpqxx-7.7.3/include/pqxx/version.hxx.template new file mode 100644 index 0000000..40837f1 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/version.hxx.template @@ -0,0 +1,55 @@ +/* Version info for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_VERSION + +#if !defined(PQXX_HEADER_PRE) +#error "Include libpqxx headers as , not ." +#endif + +/// Full libpqxx version string. +# define PQXX_VERSION "@PQXXVERSION@" +/// Library ABI version. +# define PQXX_ABI "@PQXX_ABI@" + +/// Major version number. +# define PQXX_VERSION_MAJOR @PQXX_MAJOR@ +/// Minor version number. +# define PQXX_VERSION_MINOR @PQXX_MINOR@ + +# define PQXX_VERSION_CHECK check_pqxx_version_@PQXX_MAJOR@_@PQXX_MINOR@ + +namespace pqxx::internal +{ +/// Library version check stub. +/** Helps detect version mismatches between libpqxx headers and the libpqxx + * library binary. + * + * Sometimes users run into trouble linking their code against libpqxx because + * they build their own libpqxx, but the system also has a different version + * installed. The declarations in the headers against which they compile their + * code will differ from the ones used to build the libpqxx version they're + * using, leading to confusing link errors. The solution is to generate a link + * error when the libpqxx binary is not the same version as the libpqxx headers + * used to compile the code. + * + * This function's definition is in the libpqxx binary, so it's based on the + * version as found in the binary. The headers contain a call to the function, + * whose name contains the libpqxx version as found in the headers. (The + * library build process will use its own local headers even if another version + * of the headers is installed on the system.) + * + * If the libpqxx binary was compiled for a different version than the user's + * code, linking will fail with an error: `check_pqxx_version_*_*` will not + * exist for the given version number. + */ +PQXX_LIBEXPORT int PQXX_VERSION_CHECK() noexcept; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/include/pqxx/zview b/ext/libpqxx-7.7.3/include/pqxx/zview new file mode 100644 index 0000000..66ea2a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/zview @@ -0,0 +1,6 @@ +/** Zero-terminated string view class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/zview.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/include/pqxx/zview.hxx b/ext/libpqxx-7.7.3/include/pqxx/zview.hxx new file mode 100644 index 0000000..36a779f --- /dev/null +++ b/ext/libpqxx-7.7.3/include/pqxx/zview.hxx @@ -0,0 +1,163 @@ +/* Zero-terminated string view. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/zview instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ZVIEW +#define PQXX_H_ZVIEW + +#include +#include +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// Marker-type wrapper: zero-terminated `std::string_view`. +/** @warning Use this only if the underlying string is zero-terminated. + * + * When you construct a zview, you are promising that if the data pointer is + * non-null, the underlying string is zero-terminated. It otherwise behaves + * exactly like a std::string_view. + * + * The terminating zero is not "in" the string, so it does not count as part of + * the view's length. + * + * The added guarantee lets the view be used as a C-style string, which often + * matters since libpqxx builds on top of a C library. For this reason, zview + * also adds a @ref c_str method. + */ +class zview : public std::string_view +{ +public: + constexpr zview() noexcept = default; + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char const text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Explicitly promote a `string_view` to a `zview`. + explicit constexpr zview(std::string_view other) noexcept : + std::string_view{other} + {} + + /// Construct from any initialiser you might use for `std::string_view`. + /** @warning Only do this if you are sure that the string is zero-terminated. + */ + template + explicit constexpr zview(Args &&...args) : + std::string_view(std::forward(args)...) + {} + + // C++20: constexpr. + /// @warning There's an implicit conversion from `std::string`. + zview(std::string const &str) noexcept : + std::string_view{str.c_str(), str.size()} + {} + + /// Construct a `zview` from a C-style string. + /** @warning This scans the string to discover its length. So if you need to + * do it many times, it's probably better to create the `zview` once and + * re-use it. + */ + constexpr zview(char const str[]) : std::string_view{str} {} + + /// Construct a `zview` from a string literal. + /** A C++ string literal ("foo") normally looks a lot like a pointer to + * char const, but that's not really true. It's actually an array of char, + * which _devolves_ to a pointer when you pass it. + * + * For the purpose of creating a `zview` there is one big difference: if we + * know the array's size, we don't need to scan through the string in order + * to find out its length. + */ + template + constexpr zview(char const (&literal)[size]) : zview(literal, size - 1) + {} + + /// Either a null pointer, or a zero-terminated text buffer. + [[nodiscard]] constexpr char const *c_str() const &noexcept + { + return data(); + } +}; + + +/// Support @ref zview literals. +/** You can "import" this selectively into your namespace, without pulling in + * all of the @ref pqxx namespace: + * + * ```cxx + * using pqxx::operator"" _zv; + * ``` + */ +constexpr zview operator"" _zv(char const str[], std::size_t len) noexcept +{ + return zview{str, len}; +} +} // namespace pqxx + + +#if defined(PQXX_HAVE_CONCEPTS) +/// A zview is a view. +template<> inline constexpr bool std::ranges::enable_view{true}; + + +/// A zview is a borrowed range. +template<> +inline constexpr bool std::ranges::enable_borrowed_range{true}; + +namespace pqxx::internal +{ +/// Concept: T is a known zero-terminated string type. +/** There's no unified API for these string types. It's just a check for some + * known types. Any code that makes use of the concept will still have to + * support each of these individually. + */ +template +concept ZString = std::is_convertible_v < strip_t, +char const * > or std::is_convertible_v, zview> or + std::is_convertible_v; +} // namespace pqxx::internal +#endif // PQXX_HAVE_CONCEPTS + + +namespace pqxx::internal +{ +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(char const str[]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +template +inline constexpr char const *as_c_string(char (&str)[N]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(pqxx::zview str) noexcept +{ + return str.c_str(); +} +// C++20: Make this constexpr. +/// Get a raw C string pointer. +inline char const *as_c_string(std::string const &str) noexcept +{ + return str.c_str(); +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array new file mode 100644 index 0000000..689f5b2 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array @@ -0,0 +1,6 @@ +/** Handling of SQL arrays. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/array.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array.hxx new file mode 100644 index 0000000..8440a24 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/array.hxx @@ -0,0 +1,103 @@ +/* Handling of SQL arrays. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ARRAY +#define PQXX_H_ARRAY + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx +{ +/// Low-level array parser. +/** Use this to read an array field retrieved from the database. + * + * This parser will only work reliably if your client encoding is UTF-8, ASCII, + * or a single-byte encoding which is a superset of ASCII (such as Latin-1). + * + * Also, the parser only supports array element types which use either a comma + * or a semicolon ("," or ";") as the separator between array elements. All + * built-in types use comma, except for one which uses semicolon, but some + * custom types may not work. + * + * The input is a C-style string containing the textual representation of an + * array, as returned by the database. The parser reads this representation + * on the fly. The string must remain in memory until parsing is done. + * + * Parse the array by making calls to @ref get_next until it returns a + * @ref juncture of "done". The @ref juncture tells you what the parser found + * in that step: did the array "nest" to a deeper level, or "un-nest" back up? + */ +class PQXX_LIBEXPORT array_parser +{ +public: + /// What's the latest thing found in the array? + enum class juncture + { + /// Starting a new row. + row_start, + /// Ending the current row. + row_end, + /// Found a NULL value. + null_value, + /// Found a string value. + string_value, + /// Parsing has completed. + done, + }; + + // TODO: constexpr noexcept. Breaks ABI. + /// Constructor. You don't need this; use @ref field::as_array instead. + /** The parser only remains valid while the data underlying the @ref result + * remains valid. Once all `result` objects referring to that data have been + * destroyed, the parser will no longer refer to valid memory. + */ + explicit array_parser( + std::string_view input, + internal::encoding_group = internal::encoding_group::MONOBYTE); + + /// Parse the next step in the array. + /** Returns what it found. If the juncture is @ref juncture::string_value, + * the string will contain the value. Otherwise, it will be empty. + * + * Call this until the @ref array_parser::juncture it returns is + * @ref juncture::done. + */ + std::pair get_next(); + +private: + std::string_view m_input; + internal::glyph_scanner_func *const m_scan; + + /// Current parsing position in the input. + std::string::size_type m_pos = 0u; + + std::string::size_type scan_single_quoted_string() const; + std::string parse_single_quoted_string(std::string::size_type end) const; + std::string::size_type scan_double_quoted_string() const; + std::string parse_double_quoted_string(std::string::size_type end) const; + std::string::size_type scan_unquoted_string() const; + std::string parse_unquoted_string(std::string::size_type end) const; + + std::string::size_type scan_glyph(std::string::size_type pos) const; + std::string::size_type + scan_glyph(std::string::size_type pos, std::string::size_type end) const; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring new file mode 100644 index 0000000..77551d9 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring @@ -0,0 +1,6 @@ +/** BYTEA (binary string) conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring.hxx new file mode 100644 index 0000000..47c82a0 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/binarystring.hxx @@ -0,0 +1,236 @@ +/* Deprecated representation for raw, binary data. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BINARYSTRING +#define PQXX_H_BINARYSTRING + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class binarystring; +template<> struct string_traits; + + +/// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type. +/** @ingroup escaping-functions + * @deprecated Use @c std::basic_string and + * @c std::basic_string_view for binary data. In C++20 or better, + * any @c contiguous_range of @c std::byte will do. + * + * This class represents a binary string as stored in a field of type @c bytea. + * + * Internally a binarystring is zero-terminated, but it may also contain null + * bytes, they're just like any other byte value. So don't assume that it's + * safe to treat the contents as a C-style string. + * + * The binarystring retains its value even if the result it was obtained from + * is destroyed, but it cannot be copied or assigned. + * + * \relatesalso transaction_base::quote_raw + * + * To include a @c binarystring value in an SQL query, escape and quote it + * using the transaction's @c quote_raw function. + * + * @warning This class is implemented as a reference-counting smart pointer. + * Copying, swapping, and destroying binarystring objects that refer to the + * same underlying data block is not thread-safe. If you wish to pass + * binarystrings around between threads, make sure that each of these + * operations is protected against concurrency with similar operations on the + * same object, or other objects pointing to the same data block. + */ +class PQXX_LIBEXPORT binarystring +{ +public: + using char_type = unsigned char; + using value_type = std::char_traits::char_type; + using size_type = std::size_t; + using difference_type = long; + using const_reference = value_type const &; + using const_pointer = value_type const *; + using const_iterator = const_pointer; + using const_reverse_iterator = std::reverse_iterator; + + [[deprecated("Use std::byte for binary data.")]] binarystring( + binarystring const &) = default; + + /// Read and unescape bytea field. + /** The field will be zero-terminated, even if the original bytea field + * isn't. + * @param F the field to read; must be a bytea field + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + field const &); + + /// Copy binary data from std::string_view on binary data. + /** This is inefficient in that it copies the data to a buffer allocated on + * the heap. + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + std::string_view); + + /// Copy binary data of given length straight out of memory. + [[deprecated("Use std::byte for binary data.")]] binarystring( + void const *, std::size_t); + + /// Efficiently wrap a buffer of binary data in a @c binarystring. + [[deprecated("Use std::byte for binary data.")]] binarystring( + std::shared_ptr ptr, size_type size) : + m_buf{std::move(ptr)}, m_size{size} + {} + + /// Size of converted string in bytes. + [[nodiscard]] size_type size() const noexcept { return m_size; } + /// Size of converted string in bytes. + [[nodiscard]] size_type length() const noexcept { return size(); } + [[nodiscard]] bool empty() const noexcept { return size() == 0; } + + [[nodiscard]] const_iterator begin() const noexcept { return data(); } + [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); } + [[nodiscard]] const_iterator end() const noexcept { return data() + m_size; } + [[nodiscard]] const_iterator cend() const noexcept { return end(); } + + [[nodiscard]] const_reference front() const noexcept { return *begin(); } + [[nodiscard]] const_reference back() const noexcept + { + return *(data() + m_size - 1); + } + + [[nodiscard]] const_reverse_iterator rbegin() const + { + return const_reverse_iterator{end()}; + } + [[nodiscard]] const_reverse_iterator crbegin() const { return rbegin(); } + [[nodiscard]] const_reverse_iterator rend() const + { + return const_reverse_iterator{begin()}; + } + [[nodiscard]] const_reverse_iterator crend() const { return rend(); } + + /// Unescaped field contents. + [[nodiscard]] value_type const *data() const noexcept { return m_buf.get(); } + + [[nodiscard]] const_reference operator[](size_type i) const noexcept + { + return data()[i]; + } + + [[nodiscard]] PQXX_PURE bool operator==(binarystring const &) const noexcept; + [[nodiscard]] bool operator!=(binarystring const &rhs) const noexcept + { + return not operator==(rhs); + } + + binarystring &operator=(binarystring const &); + + /// Index contained string, checking for valid index. + const_reference at(size_type) const; + + /// Swap contents with other binarystring. + void swap(binarystring &); + + /// Raw character buffer (no terminating zero is added). + /** @warning No terminating zero is added! If the binary data did not end in + * a null character, you will not find one here. + */ + [[nodiscard]] char const *get() const noexcept + { + return reinterpret_cast(m_buf.get()); + } + + /// Read contents as a std::string_view. + [[nodiscard]] std::string_view view() const noexcept + { + return std::string_view(get(), size()); + } + + /// Read as regular C++ string (may include null characters). + /** This creates and returns a new string object. Don't call this + * repeatedly; retrieve your string once and keep it in a local variable. + * Also, do not expect to be able to compare the string's address to that of + * an earlier invocation. + */ + [[nodiscard]] std::string str() const; + + /// Access data as a pointer to @c std::byte. + [[nodiscard]] std::byte const *bytes() const + { + return reinterpret_cast(get()); + } + + /// Read data as a @c std::basic_string_view. + [[nodiscard]] std::basic_string_view bytes_view() const + { + return std::basic_string_view{bytes(), size()}; + } + +private: + std::shared_ptr m_buf; + size_type m_size{0}; +}; + + +template<> struct nullness : no_null +{}; + + +/// String conversion traits for @c binarystring. +/** Defines the conversions between a @c binarystring and its PostgreSQL + * textual format, for communication with the database. + * + * These conversions rely on the "hex" format which was introduced in + * PostgreSQL 9.0. Both your libpq and the server must be recent enough to + * speak this format. + */ +template<> struct string_traits +{ + static std::size_t size_buffer(binarystring const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, binarystring const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, binarystring const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + std::string_view text{value.view()}; + internal::esc_bin(binary_cast(text), begin); + return begin + budget; + } + + static binarystring from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::shared_ptr buf{ + new unsigned char[size], [](unsigned char const *x) { delete[] x; }}; + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.get())); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return binarystring{std::move(buf), size}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob new file mode 100644 index 0000000..3fd0afa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob @@ -0,0 +1,6 @@ +/** Binary Large Objects interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob.hxx new file mode 100644 index 0000000..6d77be7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/blob.hxx @@ -0,0 +1,351 @@ +/* Binary Large Objects interface. + * + * Read or write large objects, stored in their own storage on the server. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BLOB +#define PQXX_H_BLOB + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#if defined(PQXX_HAVE_PATH) +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/** Binary large object. + * + * This is how you store data that may be too large for the `BYTEA` type. + * Access operations are similar to those for a file: you can read, write, + * query or set the current reading/writing position, and so on. + * + * These large objects live in their own storage on the server, indexed by an + * integer object identifier ("oid"). + * + * Two `blob` objects may refer to the same actual large object in the + * database at the same time. Each will have its own reading/writing position, + * but writes to the one will of course affect what the other sees. + */ +class PQXX_LIBEXPORT blob +{ +public: + /// Create a new, empty large object. + /** You may optionally specify an oid for the new blob. If you do, then + * the new object will have that oid -- or creation will fail if there + * already is an object with that oid. + */ + [[nodiscard]] static oid create(dbtransaction &, oid = 0); + + /// Delete a large object, or fail if it does not exist. + static void remove(dbtransaction &, oid); + + /// Open blob for reading. Any attempt to write to it will fail. + [[nodiscard]] static blob open_r(dbtransaction &, oid); + // Open blob for writing. Any attempt to read from it will fail. + [[nodiscard]] static blob open_w(dbtransaction &, oid); + // Open blob for reading and/or writing. + [[nodiscard]] static blob open_rw(dbtransaction &, oid); + + /// You can default-construct a blob, but it won't do anything useful. + /** Most operations on a default-constructed blob will throw @ref + * usage_error. + */ + blob() = default; + + /// You can move a blob, but not copy it. The original becomes unusable. + blob(blob &&); + /// You can move a blob, but not copy it. The original becomes unusable. + blob &operator=(blob &&); + + blob(blob const &) = delete; + blob &operator=(blob const &) = delete; + ~blob(); + + /// Maximum number of bytes that can be read or written at a time. + /** The underlying protocol only supports reads and writes up to 2 GB + * exclusive. + * + * If you need to read or write more data to or from a binary large object, + * you'll have to break it up into chunks. + */ + static constexpr std::size_t chunk_limit = 0x7fffffff; + + /// Read up to `size` bytes of the object into `buf`. + /** Uses a buffer that you provide, resizing it as needed. If it suits you, + * this lets you allocate the buffer once and then re-use it multiple times. + * + * Resizes `buf` as needed. + * + * @warning The underlying protocol only supports reads up to 2GB at a time. + * If you need to read more, try making repeated calls to @ref append_to_buf. + */ + std::size_t read(std::basic_string &buf, std::size_t size); + +#if defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::span read(std::span buf) + { + return buf.subspan(0, raw_read(std::data(buf), std::size(buf))); + } +#endif // PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template std::span read(DATA &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#else // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + /// Read up to `std::size(buf)` bytes from the object. + /** @deprecated As libpqxx moves to C++20 as its baseline language version, + * this will take and return `std::span`. + * + * Retrieves bytes from the blob, at the current position, until `buf` is + * full (i.e. its current size is reached), or there are no more bytes to + * read, whichever comes first. + * + * This function will not change either the size or the capacity of `buf`, + * only its contents. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::basic_string_view read(std::vector &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#endif // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) + /// Write `data` to large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#else + /// Write `data` large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#endif + + /// Resize large object to `size` bytes. + /** If the blob is more than `size` bytes long, this removes the end so as + * to make the blob the desired length. + * + * If the blob is less than `size` bytes long, it adds enough zero bytes to + * make it the desired length. + */ + void resize(std::int64_t size); + + /// Return the current reading/writing position in the large object. + [[nodiscard]] std::int64_t tell() const; + + /// Set the current reading/writing position to an absolute offset. + /** Returns the new file offset. */ + std::int64_t seek_abs(std::int64_t offset = 0); + /// Move the current reading/writing position forwards by an offset. + /** To move backwards, pass a negative offset. + * + * Returns the new file offset. + */ + std::int64_t seek_rel(std::int64_t offset = 0); + /// Set the current position to an offset relative to the end of the blob. + /** You'll probably want an offset of zero or less. + * + * Returns the new file offset. + */ + std::int64_t seek_end(std::int64_t offset = 0); + + /// Create a binary large object containing given `data`. + /** You may optionally specify an oid for the new object. If you do, and an + * object with that oid already exists, creation will fail. + */ + static oid from_buf( + dbtransaction &tx, std::basic_string_view data, oid id = 0); + + /// Append `data` to binary large object. + /** The underlying protocol only supports appending blocks up to 2 GB. + */ + static void append_from_buf( + dbtransaction &tx, std::basic_string_view data, oid id); + + /// Read client-side file and store it server-side as a binary large object. + [[nodiscard]] static oid from_file(dbtransaction &, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + [[nodiscard]] static oid + from_file(dbtransaction &tx, std::filesystem::path const &path) + { + return from_file(tx, path.c_str()); + } +#endif + + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + */ + static oid from_file(dbtransaction &, char const path[], oid); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + * + * This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static oid + from_file(dbtransaction &tx, std::filesystem::path const &path, oid id) + { + return from_file(tx, path.c_str(), id); + } +#endif + + /// Convenience function: Read up to `max_size` bytes from blob with `id`. + /** You could easily do this yourself using the @ref open_r and @ref read + * functions, but it can save you a bit of code to do it this way. + */ + static void to_buf( + dbtransaction &, oid, std::basic_string &, + std::size_t max_size); + + /// Read part of the binary large object with `id`, and append it to `buf`. + /** Use this to break up a large read from one binary large object into one + * massive buffer. Just keep calling this function until it returns zero. + * + * The `offset` is how far into the large object your desired chunk is, and + * `append_max` says how much to try and read in one go. + */ + static std::size_t append_to_buf( + dbtransaction &tx, oid id, std::int64_t offset, + std::basic_string &buf, std::size_t append_max); + + /// Write a binary large object's contents to a client-side file. + static void to_file(dbtransaction &, oid, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Write a binary large object's contents to a client-side file. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static void + to_file(dbtransaction &tx, oid id, std::filesystem::path const &path) + { + to_file(tx, id, path.c_str()); + } +#endif + + /// Close this blob. + /** This does not delete the blob from the database; it only terminates your + * local object for accessing the blob. + * + * Resets the blob to a useless state similar to one that was + * default-constructed. + * + * The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + */ + void close(); + +private: + PQXX_PRIVATE blob(connection &conn, int fd) noexcept : + m_conn{&conn}, m_fd{fd} + {} + static PQXX_PRIVATE blob open_internal(dbtransaction &, oid, int); + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::connection *) noexcept; + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::dbtransaction const &) noexcept; + static PQXX_PRIVATE std::string errmsg(connection const *); + static PQXX_PRIVATE std::string errmsg(dbtransaction const &tx) + { + return errmsg(&tx.conn()); + } + PQXX_PRIVATE std::string errmsg() const { return errmsg(m_conn); } + PQXX_PRIVATE std::int64_t seek(std::int64_t offset, int whence); + std::size_t raw_read(std::byte buf[], std::size_t size); + void raw_write(std::byte const buf[], std::size_t size); + + connection *m_conn = nullptr; + int m_fd = -1; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite new file mode 100644 index 0000000..2bfa7ad --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite @@ -0,0 +1,6 @@ +/** Handling of SQL "composite types." + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite.hxx new file mode 100644 index 0000000..439b133 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/composite.hxx @@ -0,0 +1,149 @@ +#ifndef PQXX_H_COMPOSITE +#define PQXX_H_COMPOSITE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Parse a string representation of a value of a composite type. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own @ref string_traits + * for a composite type. + * + * This function interprets `text` as the string representation of a value of + * some composite type, and sets each of `fields` to the respective values of + * its fields. The field types must be copy-assignable. + * + * The number of fields must match the number of fields in the composite type, + * and there must not be any other text in the input. The function is meant to + * handle any value string that the backend can produce, but not necessarily + * every valid alternative spelling. + * + * Fields in composite types can be null. When this happens, the C++ type of + * the corresponding field reference must be of a type that can handle nulls. + * If you are working with a type that does not have an inherent null value, + * such as e.g. `int`, consider using `std::optional`. + */ +template +inline void parse_composite( + pqxx::internal::encoding_group enc, std::string_view text, T &...fields) +{ + static_assert(sizeof...(fields) > 0); + + auto const scan{pqxx::internal::get_glyph_scanner(enc)}; + auto const data{std::data(text)}; + auto const size{std::size(text)}; + if (size == 0) + throw conversion_error{"Cannot parse composite value from empty string."}; + + std::size_t here{0}, next{scan(data, size, here)}; + if (next != 1 or data[here] != '(') + throw conversion_error{ + internal::concat("Invalid composite value string: ", text)}; + + here = next; + + constexpr auto num_fields{sizeof...(fields)}; + std::size_t index{0}; + (pqxx::internal::parse_composite_field( + index, text, here, fields, scan, num_fields - 1), + ...); + if (here != std::size(text)) + throw conversion_error{internal::concat( + "Composite value did not end at the closing parenthesis: '", text, + "'.")}; + if (text[here - 1] != ')') + throw conversion_error{internal::concat( + "Composive value did not end in parenthesis: '", text, "'")}; +} + + +/// Parse a string representation of a value of a composite type. +/** @warning This version only works for UTF-8 and single-byte encodings. + * + * For proper encoding support, use the composite-type support in the + * `field` class. + */ +template +inline void parse_composite(std::string_view text, T &...fields) +{ + parse_composite(pqxx::internal::encoding_group::MONOBYTE, text, fields...); +} +} // namespace pqxx + + +namespace pqxx::internal +{ +constexpr char empty_composite_str[]{"()"}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Estimate the buffer size needed to represent a value of a composite type. +/** Returns a conservative estimate. + */ +template +[[nodiscard]] inline std::size_t +composite_size_buffer(T const &...fields) noexcept +{ + constexpr auto num{sizeof...(fields)}; + + // Size for a multi-field composite includes room for... + // + opening parenthesis + // + field budgets + // + separating comma per field + // - comma after final field + // + closing parenthesis + // + terminating zero + + if constexpr (num == 0) + return std::size(pqxx::internal::empty_composite_str); + else + return 1 + (pqxx::internal::size_composite_field_buffer(fields) + ...) + + num + 1; +} + + +/// Render a series of values as a single composite SQL value. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own `string_traits` + * for a composite type. + */ +template +inline char *composite_into_buf(char *begin, char *end, T const &...fields) +{ + if (std::size_t(end - begin) < composite_size_buffer(fields...)) + throw conversion_error{ + "Buffer space may not be enough to represent composite value."}; + + constexpr auto num_fields{sizeof...(fields)}; + if constexpr (num_fields == 0) + { + constexpr char empty[]{"()"}; + std::memcpy(begin, empty, std::size(empty)); + return begin + std::size(empty); + } + + char *pos{begin}; + *pos++ = '('; + + (pqxx::internal::write_composite_field(pos, end, fields), ...); + + // If we've got multiple fields, "backspace" that last comma. + if constexpr (num_fields > 1) + --pos; + *pos++ = ')'; + *pos++ = '\0'; + return pos; +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/config-public-compiler.h b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/config-public-compiler.h new file mode 100644 index 0000000..3668a10 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/config-public-compiler.h @@ -0,0 +1,81 @@ +/* include/pqxx/config.h.in. Generated from configure.ac by autoheader. */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ +/* Define to 1 if you have the `pq' library (-lpq). */ +/* #undef HAVE_LIBPQ */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MEMORY_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDLIB_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRINGS_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRING_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STAT_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TYPES_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +/* #undef LT_OBJDIR */ +/* Name of package */ +/* #undef PACKAGE */ +/* Define to the address where bug reports for this package should be sent. */ +/* #undef PACKAGE_BUGREPORT */ +/* Define to the full name of this package. */ +/* #undef PACKAGE_NAME */ +/* Define to the full name and version of this package. */ +/* #undef PACKAGE_STRING */ +/* Define to the one symbol short name of this package. */ +/* #undef PACKAGE_TARNAME */ +/* Define to the home page for this package. */ +/* #undef PACKAGE_URL */ +/* Define to the version of this package. */ +/* #undef PACKAGE_VERSION */ +/* Define if supports floating-point conversion. */ +#define PQXX_HAVE_CHARCONV_FLOAT +/* Define if supports integer conversion. */ +#define PQXX_HAVE_CHARCONV_INT +/* Define if compiler has C++20 std::cmp_greater etc. */ +/* #undef PQXX_HAVE_CMP */ +/* Define if compiler supports Concepts and header. */ +/* #undef PQXX_HAVE_CONCEPTS */ +/* Define if compiler supports __cxa_demangle */ +#define PQXX_HAVE_CXA_DEMANGLE +/* Define if g++ supports pure attribute */ +#define PQXX_HAVE_GCC_PURE +/* Define if g++ supports visibility attribute. */ +#define PQXX_HAVE_GCC_VISIBILITY +/* Define if likely & unlikely work. */ +/* #undef PQXX_HAVE_LIKELY */ +/* Define if operator[] can take multiple arguments. */ +/* #undef PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT */ +/* Define if compiler has usable std::filesystem::path. */ +#define PQXX_HAVE_PATH +/* Define if poll() is available. */ +#define PQXX_HAVE_POLL +/* Define if libpq has PQencryptPasswordConn (since pg 10). */ +#define PQXX_HAVE_PQENCRYPTPASSWORDCONN +/* Define if libpq has pipeline mode (since pg 14). */ +#define PQXX_HAVE_PQ_PIPELINE +/* Define if std::this_thread::sleep_for works. */ +#define PQXX_HAVE_SLEEP_FOR +/* Define if compiler has std::span. */ +/* #undef PQXX_HAVE_SPAN */ +/* Define if strerror_r() is available. */ +#define PQXX_HAVE_STRERROR_R +/* Define if strerror_s() is available. */ +/* #undef PQXX_HAVE_STRERROR_S */ +/* Define if thread_local is fully supported. */ +#define PQXX_HAVE_THREAD_LOCAL +/* Define if std::chrono has year_month_day etc. */ +/* #undef PQXX_HAVE_YEAR_MONTH_DAY */ +/* Define to 1 if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ +/* Version number of package */ +/* #undef VERSION */ diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection new file mode 100644 index 0000000..82ff43a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection @@ -0,0 +1,8 @@ +/** pqxx::connection class. + * + * pqxx::connection encapsulates a connection to a database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection.hxx new file mode 100644 index 0000000..92454bb --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/connection.hxx @@ -0,0 +1,1261 @@ +/* Definition of the connection class. + * + * pqxx::connection encapsulates a connection to a database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CONNECTION +#define PQXX_H_CONNECTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Double-check in order to suppress an overzealous Visual C++ warning (#418). +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/params.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +/** + * @addtogroup connections + * + * Use of the libpqxx library starts here. + * + * Everything that can be done with a database through libpqxx must go through + * a @ref pqxx::connection object. It connects to a database when you create + * it, and it terminates that communication during destruction. + * + * Many things come together in this class. Handling of error and warning + * messages, for example, is defined by @ref pqxx::errorhandler objects in the + * context of a connection. Prepared statements are also defined here. + * + * When you connect to a database, you pass a connection string containing any + * parameters and options, such as the server address and the database name. + * + * These are identical to the ones in libpq, the C language binding upon which + * libpqxx itself is built: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * There are also environment variables you can set to provide defaults, again + * as defined by libpq: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * You can also create a database connection _asynchronously_ using an + * intermediate @ref pqxx::connecting object. + */ + +namespace pqxx::internal +{ +class sql_cursor; + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: T is a range of pairs of zero-terminated strings. +template +concept ZKey_ZValues = std::ranges::input_range and requires(T t) +{ + {std::cbegin(t)}; + { + std::get<0>(*std::cbegin(t)) + } -> ZString; + { + std::get<1>(*std::cbegin(t)) + } -> ZString; +} and std::tuple_size_v::value_type> +== 2; +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class connection_dbtransaction; +class connection_errorhandler; +class connection_largeobject; +class connection_notification_receiver; +class connection_pipeline; +class connection_sql_cursor; +class connection_stream_from; +class connection_stream_to; +class connection_transaction; +class const_connection_largeobject; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Representation of a PostgreSQL table path. +/** A "table path" consists of a table name, optionally prefixed by a schema + * name, which in turn is optionally prefixed by a database name. + * + * A minimal example of a table path would be `{mytable}`. But a table path + * may also take the forms `{myschema,mytable}` or + * `{mydb,myschema,mytable}`. + */ +using table_path = std::initializer_list; + + +/// Encrypt a password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] std::string + PQXX_LIBEXPORT + encrypt_password(char const user[], char const password[]); + +/// Encrypt password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] inline std::string +encrypt_password(zview user, zview password) +{ +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return encrypt_password(user.c_str(), password.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Error verbosity levels. +enum class error_verbosity : int +{ + // These values must match those in libpq's PGVerbosity enum. + terse = 0, + normal = 1, + verbose = 2 +}; + + +/// Connection to a database. +/** This is the first class to look at when you wish to work with a database + * through libpqxx. The connection opens during construction, and closes upon + * destruction. + * + * When creating a connection, you can pass a connection URI or a postgres + * connection string, to specify the database server's address, a login + * username, and so on. If you don't, the connection will try to obtain them + * from certain environment variables. If those are not set either, the + * default is to try and connect to the local system's port 5432. + * + * Find more about connection strings here: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * The variables are documented here: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * To query or manipulate the database once connected, use one of the + * transaction classes (see pqxx/transaction_base.hxx) and perhaps also the + * transactor framework (see pqxx/transactor.hxx). + * + * When a connection breaks, you will typically get a @ref broken_connection + * exception. This can happen at almost any point. + * + * @warning On Unix-like systems, including GNU and BSD systems, your program + * may receive the SIGPIPE signal when the connection to the backend breaks. By + * default this signal will abort your program. Use "signal(SIGPIPE, SIG_IGN)" + * if you want your program to continue running after a connection fails. + */ +class PQXX_LIBEXPORT connection +{ +public: + connection() : connection{""} {} + + /// Connect to a database, using `options` string. + explicit connection(char const options[]) + { + check_version(); + init(options); + } + + /// Connect to a database, using `options` string. + explicit connection(zview options) : connection{options.c_str()} + { + // (Delegates to other constructor which calls check_version for us.) + } + + /// Move constructor. + /** Moving a connection is not allowed if it has an open transaction, or has + * error handlers or notification receivers registered on it. In those + * situations, other objects may hold references to the old object which + * would become invalid and might produce hard-to-diagnose bugs. + */ + connection(connection &&rhs); + +#if defined(PQXX_HAVE_CONCEPTS) + /// Connect to a database, passing options as a range of key/value pairs. + /** @warning Experimental. Requires C++20 "concepts" support. Define + * `PQXX_HAVE_CONCEPTS` to enable it. + * + * There's no need to escape the parameter values. + * + * See the PostgreSQL libpq documentation for the full list of possible + * options: + * + * https://postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS + * + * The options can be anything that can be iterated as a series of pairs of + * zero-terminated strings: `std::pair`, or + * `std::tuple`, or + * `std::map`, and so on. + */ + template + inline connection(MAPPING const ¶ms); +#endif // PQXX_HAVE_CONCEPTS + + ~connection() + { + try + { + close(); + } + catch (std::exception const &) + {} + } + + /// Move assignment. + /** Neither connection can have an open transaction, registered error + * handlers, or registered notification receivers. + */ + connection &operator=(connection &&rhs); + + connection(connection const &) = delete; + connection &operator=(connection const &) = delete; + + /// Is this connection open at the moment? + /** @warning This function is **not** needed in most code. Resist the + * temptation to check it after opening a connection. The `connection` + * constructor will throw a @ref broken_connection exception if can't connect + * to the database. + */ + [[nodiscard]] bool PQXX_PURE is_open() const noexcept; + + /// Invoke notice processor function. The message should end in newline. + void process_notice(char const[]) noexcept; + /// Invoke notice processor function. Newline at end is recommended. + /** The zview variant, with a message ending in newline, is the most + * efficient way to call process_notice. + */ + void process_notice(zview) noexcept; + + /// Enable tracing to a given output stream, or nullptr to disable. + void trace(std::FILE *) noexcept; + + /** + * @name Connection properties + * + * These are probably not of great interest, since most are derived from + * information supplied by the client program itself, but they are included + * for completeness. + * + * The connection needs to be currently active for these to work. + */ + //@{ + /// Name of database we're connected to, if any. + [[nodiscard]] char const *dbname() const; + + /// Database user ID we're connected under, if any. + [[nodiscard]] char const *username() const; + + /// Address of server, or nullptr if none specified (i.e. default or local) + [[nodiscard]] char const *hostname() const; + + /// Server port number we're connected to. + [[nodiscard]] char const *port() const; + + /// Process ID for backend process, or 0 if inactive. + [[nodiscard]] int PQXX_PURE backendpid() const &noexcept; + + /// Socket currently used for connection, or -1 for none. Use with care! + /** Query the current socket number. This is intended for event loops based + * on functions such as select() or poll(), where you're waiting for any of + * multiple file descriptors to become ready for communication. + * + * Please try to stay away from this function. It is really only meant for + * event loops that need to wait on more than one file descriptor. If all + * you need is to block until a notification arrives, for instance, use + * await_notification(). If you want to issue queries and retrieve results + * in nonblocking fashion, check out the pipeline class. + */ + [[nodiscard]] int PQXX_PURE sock() const &noexcept; + + /// What version of the PostgreSQL protocol is this connection using? + /** The answer can be 0 (when there is no connection); 3 for protocol 3.0; or + * possibly higher values as newer protocol versions come into use. + */ + [[nodiscard]] int PQXX_PURE protocol_version() const noexcept; + + /// What version of the PostgreSQL server are we connected to? + /** The result is a bit complicated: each of the major, medium, and minor + * release numbers is written as a two-digit decimal number, and the three + * are then concatenated. Thus server version 9.4.2 will be returned as the + * decimal number 90402. If there is no connection to the server, this + * returns zero. + * + * @warning When writing version numbers in your code, don't add zero at the + * beginning! Numbers beginning with zero are interpreted as octal (base-8) + * in C++. Thus, 070402 is not the same as 70402, and 080000 is not a number + * at all because there is no digit "8" in octal notation. Use strictly + * decimal notation when it comes to these version numbers. + */ + [[nodiscard]] int PQXX_PURE server_version() const noexcept; + //@} + + /// @name Text encoding + /** + * Each connection is governed by a "client encoding," which dictates how + * strings and other text is represented in bytes. The database server will + * send text data to you in this encoding, and you should use it for the + * queries and data which you send to the server. + * + * Search the PostgreSQL documentation for "character set encodings" to find + * out more about the available encodings, how to extend them, and how to use + * them. Not all server-side encodings are compatible with all client-side + * encodings or vice versa. + * + * Encoding names are case-insensitive, so e.g. "UTF8" is equivalent to + * "utf8". + * + * You can change the client encoding, but this may not work when the + * connection is in a special state, such as when streaming a table. It's + * not clear what happens if you change the encoding during a transaction, + * and then abort the transaction. + */ + //@{ + /// Get client-side character encoding, by name. + [[nodiscard]] std::string get_client_encoding() const; + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(zview encoding) & + { + set_client_encoding(encoding.c_str()); + } + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(char const encoding[]) &; + + /// Get the connection's encoding, as a PostgreSQL-defined code. + [[nodiscard]] int PQXX_PRIVATE encoding_id() const; + + //@} + + /// Set session variable, using SQL's `SET` command. + /** @deprecated To set a session variable, use @ref set_session_var. To set + * a transaction-local variable, execute an SQL `SET` command. + * + * @warning When setting a string value, you must escape and quote it first. + * Use the @ref quote() function to do that. + * + * @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + * + * @param var Variable to set. + * @param value New value for Var. This can be any SQL expression. If it's + * a string, be sure that it's properly escaped and quoted. + */ + [[deprecated("To set session variables, use set_session_var.")]] void + set_variable(std::string_view var, std::string_view value) &; + + /// Set one of the session variables to a new value. + /** This executes SQL, so do not do it while a pipeline or stream is active + * on the connection. + * + * The value you set here will last for the rest of the connection's + * duration, or until you set a new value. + * + * If you set the value while in a @ref dbtransaction (i.e. any transaction + * that is not a @ref nontransaction), then rolling back the transaction will + * undo the change. + * + * All applies to setting _session_ variables. You can also set the same + * variables as _local_ variables, in which case they will always revert to + * their previous value when the transaction ends (or when you overwrite them + * of course). To set a local variable, simply execute an SQL statement + * along the lines of "`SET LOCAL var = 'value'`" inside your transaction. + * + * @param var The variable to set. + * @param value The new value for the variable. + * @throw @ref variable_set_to_null if the value is null; this is not + * allowed. + */ + template + void set_session_var(std::string_view var, TYPE const &value) & + { + if constexpr (nullness::has_null) + { + if (nullness::is_null(value)) + throw variable_set_to_null{ + internal::concat("Attempted to set variable ", var, " to null.")}; + } + exec(internal::concat("SET ", quote_name(var), "=", quote(value))); + } + + /// Read session variable, using SQL's `SHOW` command. + /** @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + */ + [[deprecated("Use get_var instead.")]] std::string + get_variable(std::string_view); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * @return a blank `std::optional` if the variable's value is null, or its + * string value otherwise. + */ + std::string get_var(std::string_view var); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * If there is any possibility that the variable is null, ensure that `TYPE` + * can represent null values. + */ + template TYPE get_var_as(std::string_view var) + { + return from_string(get_var(var)); + } + + /** + * @name Notifications and Receivers + */ + //@{ + /// Check for pending notifications and take appropriate action. + /** This does not block. To wait for incoming notifications, either call + * await_notification() (it calls this function); or wait for incoming data + * on the connection's socket (i.e. wait to read), and then call this + * function repeatedly until it returns zero. After that, there are no more + * pending notifications so you may want to wait again. + * + * If any notifications are pending when you call this function, it + * processes them by finding any receivers that match the notification string + * and invoking those. If no receivers match, there is nothing to invoke but + * we do consider the notification processed. + * + * If any of the client-registered receivers throws an exception, the + * function will report it using the connection's errorhandlers. It does not + * re-throw the exceptions. + * + * @return Number of notifications processed. + */ + int get_notifs(); + + /// Wait for a notification to come in. + /** There are other events that will also terminate the wait, such as the + * backend failing. It will also wake up periodically. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs() repeatedly until it returns zero. + * + * @return Number of notifications processed. + */ + int await_notification(); + + /// Wait for a notification to come in, or for given timeout to pass. + /** There are other events that will also terminate the wait, such as the + * backend failing, or timeout expiring. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs repeatedly until it returns zero. + * + * @return Number of notifications processed + */ + int await_notification(std::time_t seconds, long microseconds); + //@} + + /** + * @name Password encryption + * + * Use this when setting a new password for the user if password encryption + * is enabled. Inputs are the SQL name for the user for whom you with to + * encrypt a password; the plaintext password; and the hash algorithm. + * + * The algorithm must be one of "md5", "scram-sha-256" (introduced in + * PostgreSQL 10), or `nullptr`. If the pointer is null, this will query + * the `password_encryption setting` from the server, and use the default + * algorithm as defined there. + * + * @return encrypted version of the password, suitable for encrypted + * PostgreSQL authentication. + * + * Thus you can change a user's password with: + * ```cxx + * void setpw(transaction_base &t, string const &user, string const &pw) + * { + * t.exec0("ALTER USER " + user + " " + * "PASSWORD '" + t.conn().encrypt_password(user,pw) + "'"); + * } + * ``` + * + * When building this against a libpq older than version 10, this will use + * an older function which only supports md5. In that case, requesting a + * different algorithm than md5 will result in a @ref feature_not_supported + * exception. + */ + //@{ + /// Encrypt a password for a given user. + [[nodiscard]] std::string + encrypt_password(zview user, zview password, zview algorithm) + { + return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str()); + } + /// Encrypt a password for a given user. + [[nodiscard]] std::string encrypt_password( + char const user[], char const password[], char const *algorithm = nullptr); + //@} + + /** + * @name Prepared statements + * + * PostgreSQL supports prepared SQL statements, i.e. statements that you can + * register under a name you choose, optimized once by the backend, and + * executed any number of times under the given name. + * + * Prepared statement definitions are not sensitive to transaction + * boundaries. A statement defined inside a transaction will remain defined + * outside that transaction, even if the transaction itself is subsequently + * aborted. Once a statement has been prepared, it will only go away if you + * close the connection or explicitly "unprepare" the statement. + * + * Use the `pqxx::transaction_base::exec_prepared` functions to execute a + * prepared statement. See @ref prepared for a full discussion. + * + * @warning Using prepared statements can save time, but if your statement + * takes parameters, it may also make your application significantly slower! + * The reason is that the server works out a plan for executing the query + * when you prepare it. At that time, of course it does not know the values + * for the parameters that you will pass. If you execute a query without + * preparing it, then the server works out the plan on the spot, with full + * knowledge of the parameter values. + * + * A statement's definition can refer to its parameters as `$1`, `$2`, etc. + * The first parameter you pass to the call provides a value for `$1`, and + * so on. + * + * Here's an example of how to use prepared statements. + * + * ```cxx + * using namespace pqxx; + * void foo(connection &c) + * { + * c.prepare("findtable", "select * from pg_tables where name=$1"); + * work tx{c}; + * result r = tx.exec_prepared("findtable", "mytable"); + * if (std::empty(r)) throw runtime_error{"mytable not found!"}; + * } + * ``` + */ + //@{ + + /// Define a prepared statement. + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(zview name, zview definition) & + { + prepare(name.c_str(), definition.c_str()); + } + + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(char const name[], char const definition[]) &; + + /// Define a nameless prepared statement. + /** + * This can be useful if you merely want to pass large binary parameters to a + * statement without otherwise wishing to prepare it. If you use this + * feature, always keep the definition and the use close together to avoid + * the nameless statement being redefined unexpectedly by code somewhere + * else. + */ + void prepare(char const definition[]) &; + void prepare(zview definition) & { return prepare(definition.c_str()); } + + /// Drop prepared statement. + void unprepare(std::string_view name); + + //@} + + // C++20: constexpr. Breaks ABI. + /// Suffix unique number to name to make it unique within session context. + /** Used internally to generate identifiers for SQL objects (such as cursors + * and nested transactions) based on a given human-readable base name. + */ + [[nodiscard]] std::string adorn_name(std::string_view); + + /** + * @defgroup escaping-functions String-escaping functions + */ + //@{ + + /// Escape string for use as SQL string literal on this connection. + /** @warning This accepts a length, and it does not require a terminating + * zero byte. But if there is a zero byte, escaping stops there even if + * it's not at the end of the string! + */ + [[deprecated("Use std::string_view or pqxx:zview.")]] std::string + esc(char const text[], std::size_t maxlen) const + { + return esc(std::string_view{text, maxlen}); + } + + /// Escape string for use as SQL string literal on this connection. + [[nodiscard]] std::string esc(char const text[]) const + { + return esc(std::string_view{text}); + } + +#if defined(PQXX_HAVE_SPAN) + /// Escape string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `text`, there must be at least 2 bytes of space in + * `buffer`; plus there must be one byte of space for a trailing zero. + * Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + [[nodiscard]] std::string_view + esc(std::string_view text, std::span buffer) + { + auto const size{std::size(text)}, space{std::size(buffer)}; + auto const needed{2 * size + 1}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + auto const data{buffer.data()}; + return {data, esc_to_buf(text, data)}; + } +#endif + + /// Escape string for use as SQL string literal on this connection. + /** @warning This is meant for text strings only. It cannot contain bytes + * whose value is zero ("nul bytes"). + */ + [[nodiscard]] std::string esc(std::string_view text) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** This is identical to `esc_raw(data)`. */ + template [[nodiscard]] std::string esc(DATA const &data) const + { + return esc_raw(data); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `data`, there must be at least two bytes of space in + * `buffer`; plus there must be two bytes of space for a header and one for + * a trailing zero. Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + template + [[nodiscard]] zview esc(DATA const &data, std::span buffer) const + { + auto const size{std::size(data)}, space{std::size(buffer)}; + auto const needed{internal::size_esc_bin(std::size(data))}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape binary string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + + std::basic_string_view view{std::data(data), std::size(data)}; + auto const out{std::data(buffer)}; + // Actually, in the modern format, we know beforehand exactly how many + // bytes we're going to fill. Just leave out the trailing zero. + internal::esc_bin(view, out); + return zview{out, needed - 1}; + } +#endif + + /// Escape binary string for use as SQL string literal on this connection. + [[deprecated("Use std::byte for binary data.")]] std::string + esc_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string esc_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string + esc_raw(std::basic_string_view, std::span buffer) const; +#endif + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + template + [[nodiscard]] std::string esc_raw(DATA const &data) const + { + return esc_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + template + [[nodiscard]] zview esc_raw(DATA const &data, std::span buffer) const + { + return this->esc(binary_cast(data), buffer); + } +#endif + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return unesc_raw(text.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const text[]) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + * + * (The data must be encoded in PostgreSQL's "hex" format. The legacy + * "bytea" escape format, used prior to PostgreSQL 9.0, is no longer + * supported.) + */ + [[nodiscard]] std::basic_string + unesc_bin(std::string_view text) const + { + std::basic_string buf; + buf.resize(pqxx::internal::size_unesc_bin(std::size(text))); + pqxx::internal::unesc_bin(text, buf.data()); + return buf; + } + + /// Escape and quote a string of binary data. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape and quote a string of binary data. + std::string quote_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape and quote a string of binary data. + /** You can also just use @ref quote with binary data. */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return quote_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table name. + /** When passing just a table name, this is just another name for + * @ref quote_name. + */ + [[nodiscard]] std::string quote_table(std::string_view name) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table path. + /** A table path consists of a table name, optionally prefixed by a schema + * name; and if both are given, they are in turn optionally prefixed by a + * database name. + * + * Each portion of the path (database name, schema name, table name) will be + * quoted separately, and they will be joined together by dots. So for + * example, `myschema.mytable` will become `"myschema"."mytable"`. + */ + [[nodiscard]] std::string quote_table(table_path) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Quote and comma-separate a series of column names. + /** Use this to save a bit of work in cases where you repeatedly need to pass + * the same list of column names, e.g. with @ref stream_to and @ref + * stream_from. Some functions that need to quote the columns list + * internally, will have a "raw" alternative which let you do the quoting + * yourself. It's a bit of extra work, but it can in rare cases let you + * eliminate some duplicate work in quoting them repeatedly. + */ + template + inline std::string quote_columns(STRINGS const &columns) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Represent object as SQL string, including quoting & escaping. + /** + * Recognises nulls and represents them as SQL nulls. They get no quotes. + */ + template + [[nodiscard]] inline std::string quote(T const &t) const; + + [[deprecated("Use std::byte for binary data.")]] std::string + quote(binarystring const &) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote binary data for use as a BYTEA value in SQL statement. + [[nodiscard]] std::string + quote(std::basic_string_view bytes) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape string for literal LIKE match. + /** Use this when part of an SQL "LIKE" pattern should match only as a + * literal string, not as a pattern, even if it contains "%" or "_" + * characters that would normally act as wildcards. + * + * The string does not get string-escaped or quoted. You do that later. + * + * For instance, let's say you have a string `name` entered by the user, + * and you're searching a `file` column for items that match `name` + * followed by a dot and three letters. Even if `name` contains wildcard + * characters "%" or "_", you only want those to match literally, so "_" + * only matches "_" and "%" only matches a single "%". + * + * You do that by "like-escaping" `name`, appending the wildcard pattern + * `".___"`, and finally, escaping and quoting the result for inclusion in + * your query: + * + * ```cxx + * tx.exec( + * "SELECT file FROM item WHERE file LIKE " + + * tx.quote(tx.esc_like(name) + ".___")); + * ``` + * + * The SQL "LIKE" operator also lets you choose your own escape character. + * This is supported, but must be a single-byte character. + */ + [[nodiscard]] std::string + esc_like(std::string_view text, char escape_char = '\\') const; + //@} + + /// Attempt to cancel the ongoing query, if any. + /** You can use this from another thread, and/or while a query is executing + * in a pipeline, but it's up to you to ensure that you're not canceling the + * wrong query. This may involve locking. + */ + void cancel_query(); + +#if defined(_WIN32) || __has_include() + /// Set socket to blocking (true) or nonblocking (false). + /** @warning Do not use this unless you _really_ know what you're doing. + * @warning This function is available on most systems, but not necessarily + * all. + */ + void set_blocking(bool block) &; +#endif // defined(_WIN32) || __has_include() + + /// Set session verbosity. + /** Set the verbosity of error messages to "terse", "normal" (the default), + * or "verbose." + * + * If "terse", returned messages include severity, primary text, and + * position only; this will normally fit on a single line. "normal" produces + * messages that include the above plus any detail, hint, or context fields + * (these might span multiple lines). "verbose" includes all available + * fields. + */ + void set_verbosity(error_verbosity verbosity) &noexcept; + + /// Return pointers to the active errorhandlers. + /** The entries are ordered from oldest to newest handler. + * + * You may use this to find errorhandlers that your application wants to + * delete when destroying the connection. Be aware, however, that libpqxx + * may also add errorhandlers of its own, and those will be included in the + * list. If this is a problem for you, derive your errorhandlers from a + * custom base class derived from pqxx::errorhandler. Then use dynamic_cast + * to find which of the error handlers are yours. + * + * The pointers point to the real errorhandlers. The container it returns + * however is a copy of the one internal to the connection, not a reference. + */ + [[nodiscard]] std::vector get_errorhandlers() const; + + /// Return a connection string encapsulating this connection's options. + /** The connection must be currently open for this to work. + * + * Returns a reconstruction of this connection's connection string. It may + * not exactly match the connection string you passed in when creating this + * connection. + */ + [[nodiscard]] std::string connection_string() const; + + /// Explicitly close the connection. + /** The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + * + * Closing a connection is idempotent. Closing a connection that's already + * closed does nothing. + */ + void close(); + + /// Seize control of a raw libpq connection. + /** @warning Do not do this. Please. It's for very rare, very specific + * use-cases. The mechanism may change (or break) in unexpected ways in + * future versions. + * + * @param raw_conn a raw libpq `PQconn` pointer. + */ + static connection seize_raw_connection(internal::pq::PGconn *raw_conn) + { + return connection{raw_conn}; + } + + /// Release the raw connection without closing it. + /** @warning Do not do this. It's for very rare, very specific use-cases. + * The mechanism may change (or break) in unexpected ways in future versions. + * + * The `connection` object becomes unusable after this. + */ + internal::pq::PGconn *release_raw_connection() && + { + return std::exchange(m_conn, nullptr); + } + +private: + friend class connecting; + enum connect_mode + { + connect_nonblocking + }; + connection(connect_mode, zview connection_string); + + /// For use by @ref seize_raw_connection. + explicit connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} {} + + /// Poll for ongoing connection, try to progress towards completion. + /** Returns a pair of "now please wait to read data from socket" and "now + * please wait to write data to socket." Both will be false when done. + * + * Throws an exception if polling indicates that the connection has failed. + */ + std::pair poll_connect(); + + // Initialise based on connection string. + void init(char const options[]); + // Initialise based on parameter names and values. + void init(char const *params[], char const *values[]); + void complete_init(); + + result make_result( + internal::pq::PGresult *pgr, std::shared_ptr const &query, + std::string_view desc = ""sv); + + void PQXX_PRIVATE set_up_state(); + + int PQXX_PRIVATE PQXX_PURE status() const noexcept; + + /// Escape a string, into a buffer allocated by the caller. + /** The buffer must have room for at least `2*std::size(text) + 1` bytes. + * + * Returns the number of bytes written, including the trailing zero. + */ + std::size_t esc_to_buf(std::string_view text, char *buf) const; + + friend class internal::gate::const_connection_largeobject; + char const *PQXX_PURE err_msg() const noexcept; + + void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept; + + result exec_prepared(std::string_view statement, internal::c_params const &); + + /// Throw @ref usage_error if this connection is not in a movable state. + void check_movable() const; + /// Throw @ref usage_error if not in a state where it can be move-assigned. + void check_overwritable() const; + + friend class internal::gate::connection_errorhandler; + void PQXX_PRIVATE register_errorhandler(errorhandler *); + void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept; + + friend class internal::gate::connection_transaction; + result exec(std::string_view, std::string_view = ""sv); + result + PQXX_PRIVATE exec(std::shared_ptr, std::string_view = ""sv); + void PQXX_PRIVATE register_transaction(transaction_base *); + void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept; + + friend class internal::gate::connection_stream_from; + std::pair>, std::size_t> + PQXX_PRIVATE read_copy_line(); + + friend class internal::gate::connection_stream_to; + void PQXX_PRIVATE write_copy_line(std::string_view); + void PQXX_PRIVATE end_copy_write(); + + friend class internal::gate::connection_largeobject; + internal::pq::PGconn *raw_connection() const { return m_conn; } + + friend class internal::gate::connection_notification_receiver; + void add_receiver(notification_receiver *); + void remove_receiver(notification_receiver *) noexcept; + + friend class internal::gate::connection_pipeline; + void PQXX_PRIVATE start_exec(char const query[]); + bool PQXX_PRIVATE consume_input() noexcept; + bool PQXX_PRIVATE is_busy() const noexcept; + internal::pq::PGresult *get_result(); + + friend class internal::gate::connection_dbtransaction; + friend class internal::gate::connection_sql_cursor; + + result exec_params(std::string_view query, internal::c_params const &args); + + /// Connection handle. + internal::pq::PGconn *m_conn = nullptr; + + /// Active transaction on connection, if any. + /** We don't use this for anything, except to check for open transactions + * when we close the connection or start a new transaction. + * + * We also don't allow move construction or move assignment while there's a + * transaction, since moving the connection in that case would leave one or + * more pointers back from the transaction to the connection dangling. + */ + transaction_base const *m_trans = nullptr; + + std::list m_errorhandlers; + + using receiver_list = + std::multimap; + /// Notification receivers. + receiver_list m_receivers; + + /// Unique number to use as suffix for identifiers (see adorn_name()). + int m_unique_id = 0; +}; + + +/// @deprecated Old base class for connection. They are now the same class. +using connection_base = connection; + + +/// An ongoing, non-blocking stepping stone to a connection. +/** Use this when you want to create a connection to the database, but without + * blocking your whole thread. It is only available on systems that have + * the `` header, and Windows. + * + * Connecting in this way is probably not "faster" (it's more complicated and + * has some extra overhead), but in some situations you can use it to make your + * application as a whole faster. It all depends on having other useful work + * to do in the same thread, and being able to wait on a socket. If you have + * other I/O going on at the same time, your event loop can wait for both the + * libpqxx socket and your own sockets, and wake up whenever any of them is + * ready to do work. + * + * Connecting in this way is not properly "asynchronous;" it's merely + * "nonblocking." This means it's not a super-high-performance mechanism like + * you might get with e.g. `io_uring`. In particular, if we need to look up + * the database hostname in DNS, that will happen synchronously. + * + * To use this, create the `connecting` object, passing a connection string. + * Then loop: If @ref wait_to_read returns true, wait for the socket to have + * incoming data on it. If @ref wait_to_write returns true, wait for the + * socket to be ready for writing. Then call @ref process to process any + * incoming or outgoing data. Do all of this until @ref done returns true (or + * there is an exception). Finally, call @ref produce to get the completed + * connection. + * + * For example: + * + * ```cxx + * pqxx::connecting cg{}; + * + * // Loop until we're done connecting. + * while (!cg.done()) + * { + * wait_for_fd(cg.sock(), cg.wait_to_read(), cg.wait_to_write()); + * cg.process(); + * } + * + * pqxx::connection conn = std::move(cg).produce(); + * + * // At this point, conn is a working connection. You can no longer use + * // cg at all. + * ``` + */ +class PQXX_LIBEXPORT connecting +{ +public: + /// Start connecting. + connecting(zview connection_string = ""_zv); + + connecting(connecting const &) = delete; + connecting(connecting &&) = default; + connecting &operator=(connecting const &) = delete; + connecting &operator=(connecting &&) = default; + + /// Get the socket. The socket may change during the connection process. + [[nodiscard]] int sock() const &noexcept { return m_conn.sock(); } + + /// Should we currently wait to be able to _read_ from the socket? + [[nodiscard]] constexpr bool wait_to_read() const &noexcept + { + return m_reading; + } + + /// Should we currently wait to be able to _write_ to the socket? + [[nodiscard]] constexpr bool wait_to_write() const &noexcept + { + return m_writing; + } + + /// Progress towards completion (but don't block). + void process() &; + + /// Is our connection finished? + [[nodiscard]] constexpr bool done() const &noexcept + { + return not m_reading and not m_writing; + } + + /// Produce the completed connection object. + /** Use this only once, after @ref done returned `true`. Once you have + * called this, the `connecting` instance has no more use or meaning. You + * can't call any of its member functions afterwards. + * + * This member function is rvalue-qualified, meaning that you can only call + * it on an rvalue instance of the class. If what you have is not an rvalue, + * turn it into one by wrapping it in `std::move()`. + */ + [[nodiscard]] connection produce() &&; + +private: + connection m_conn; + bool m_reading{false}; + bool m_writing{true}; +}; + + +template inline std::string connection::quote(T const &t) const +{ + if constexpr (nullness::always_null) + { + return "NULL"; + } + else + { + if (is_null(t)) + return "NULL"; + auto const text{to_string(t)}; + + // Okay, there's an easy way to do this and there's a hard way. The easy + // way was "quote, esc(to_string(t)), quote". I'm going with the hard way + // because it's going to save some string manipulation that will probably + // incur some unnecessary memory allocations and deallocations. + std::string buf{'\''}; + buf.resize(2 + 2 * std::size(text) + 1); + auto const content_bytes{esc_to_buf(text, buf.data() + 1)}; + auto const closing_quote{1 + content_bytes}; + buf[closing_quote] = '\''; + auto const end{closing_quote + 1}; + buf.resize(end); + return buf; + } +} + + +template +inline std::string connection::quote_columns(STRINGS const &columns) const +{ + return separated_list( + ","sv, std::cbegin(columns), std::cend(columns), + [this](auto col) { return this->quote_name(*col); }); +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +inline connection::connection(MAPPING const ¶ms) +{ + check_version(); + + std::vector keys, values; + if constexpr (std::ranges::sized_range) + { + auto const size{std::ranges::size(params) + 1}; + keys.reserve(size); + values.reserve(size); + } + for (auto const &[key, value] : params) + { + keys.push_back(internal::as_c_string(key)); + values.push_back(internal::as_c_string(value)); + } + keys.push_back(nullptr); + values.push_back(nullptr); + init(std::data(keys), std::data(values)); +} +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor new file mode 100644 index 0000000..e20b3a4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor @@ -0,0 +1,8 @@ +/** Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor.hxx new file mode 100644 index 0000000..b392e24 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/cursor.hxx @@ -0,0 +1,483 @@ +/* Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CURSOR +#define PQXX_H_CURSOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Common definitions for cursor types +/** In C++ terms, fetches are always done in pre-increment or pre-decrement + * fashion--i.e. the result does not include the row the cursor is on at the + * beginning of the fetch, and the cursor ends up being positioned on the last + * row in the result. + * + * There are singular positions akin to `end()` at both the beginning and the + * end of the cursor's range of movement, although these fit in so naturally + * with the semantics that one rarely notices them. The cursor begins at the + * first of these, but any fetch in the forward direction will move the cursor + * off this position and onto the first row before returning anything. + */ +class PQXX_LIBEXPORT cursor_base +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Cursor access-pattern policy + /** Allowing a cursor to move forward only can result in better performance, + * so use this access policy whenever possible. + */ + enum access_policy + { + /// Cursor can move forward only + forward_only, + /// Cursor can move back and forth + random_access + }; + + /// Cursor update policy + /** + * @warning Not all PostgreSQL versions support updatable cursors. + */ + enum update_policy + { + /// Cursor can be used to read data but not to write + read_only, + /// Cursor can be used to update data as well as read it + update + }; + + /// Cursor destruction policy + /** The normal thing to do is to make a cursor object the owner of the SQL + * cursor it represents. There may be cases, however, where a cursor needs + * to persist beyond the end of the current transaction (and thus also beyond + * the lifetime of the cursor object that created it!), where it can be + * "adopted" into a new cursor object. See the basic_cursor documentation + * for an explanation of cursor adoption. + * + * If a cursor is created with "loose" ownership policy, the object + * representing the underlying SQL cursor will not take the latter with it + * when its own lifetime ends, nor will its originating transaction. + * + * @warning Use this feature with care and moderation. Only one cursor + * object should be responsible for any one underlying SQL cursor at any + * given time. + */ + enum ownership_policy + { + /// Destroy SQL cursor when cursor object is closed at end of transaction + owned, + /// Leave SQL cursor in existence after close of object and transaction + loose + }; + + cursor_base() = delete; + cursor_base(cursor_base const &) = delete; + cursor_base &operator=(cursor_base const &) = delete; + + /** + * @name Special movement distances. + */ + //@{ + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read until end. + /** @return Maximum value for result::difference_type, so the cursor will + * attempt to read the largest possible result set. + */ + [[nodiscard]] static difference_type all() noexcept; + + /// Special value: read one row only. + /** @return Unsurprisingly, 1. + */ + [[nodiscard]] static constexpr difference_type next() noexcept { return 1; } + + /// Special value: read backwards, one row only. + /** @return Unsurprisingly, -1. + */ + [[nodiscard]] static constexpr difference_type prior() noexcept + { + return -1; + } + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read backwards from current position back to origin. + /** @return Minimum value for result::difference_type. + */ + [[nodiscard]] static difference_type backward_all() noexcept; + + //@} + + /// Name of underlying SQL cursor + /** + * @returns Name of SQL cursor, which may differ from original given name. + * @warning Don't use this to access the SQL cursor directly without going + * through the provided wrapper classes! + */ + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_name; + } + +protected: + cursor_base(connection &, std::string_view Name, bool embellish_name = true); + + std::string const m_name; +}; +} // namespace pqxx + + +#include + + +namespace pqxx +{ +/// "Stateless cursor" class: easy API for retrieving parts of result sets +/** This is a front-end for SQL cursors, but with a more C++-like API. + * + * Actually, stateless_cursor feels entirely different from SQL cursors. You + * don't keep track of positions, fetches, and moves; you just say which rows + * you want. See the retrieve() member function. + */ +template +class stateless_cursor +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Create cursor. + /** + * @param tx The transaction within which you want to create the cursor. + * @param query The SQL query whose results the cursor should traverse. + * @param cname A hint for the cursor's name. The actual SQL cursor's name + * will be based on this (though not necessarily identical). + * @param hold Create a `WITH HOLD` cursor? Such cursors stay alive after + * the transaction has ended, so you can continue to use it. + */ + stateless_cursor( + transaction_base &tx, std::string_view query, std::string_view cname, + bool hold) : + m_cur{tx, query, cname, cursor_base::random_access, up, op, hold} + {} + + /// Adopt an existing scrolling SQL cursor. + /** This lets you define a cursor yourself, and then wrap it in a + * libpqxx-managed `stateless_cursor` object. + * + * @param tx The transaction within which you want to manage the cursor. + * @param adopted_cursor Your cursor's SQL name. + */ + stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) : + m_cur{tx, adopted_cursor, op} + { + // Put cursor in known position + m_cur.move(cursor_base::backward_all()); + } + + /// Close this cursor. + /** The destructor will do this for you automatically. + * + * Closing a cursor is idempotent. Closing a cursor that's already closed + * does nothing. + */ + void close() noexcept { m_cur.close(); } + + /// Number of rows in cursor's result set + /** @note This function is not const; it may need to scroll to find the size + * of the result set. + */ + [[nodiscard]] size_type size() + { + return internal::obtain_stateless_cursor_size(m_cur); + } + + /// Retrieve rows from begin_pos (inclusive) to end_pos (exclusive) + /** Rows are numbered starting from 0 to size()-1. + * + * @param begin_pos First row to retrieve. May be one row beyond the end of + * the result set, to avoid errors for empty result sets. Otherwise, must be + * a valid row number in the result set. + * @param end_pos Row up to which to fetch. Rows are returned ordered from + * begin_pos to end_pos, i.e. in ascending order if begin_pos < end_pos but + * in descending order if begin_pos > end_pos. The end_pos may be + * arbitrarily inside or outside the result set; only existing rows are + * included in the result. + */ + result retrieve(difference_type begin_pos, difference_type end_pos) + { + return internal::stateless_cursor_retrieve( + m_cur, result::difference_type(size()), begin_pos, end_pos); + } + + /// Return this cursor's name. + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_cur.name(); + } + +private: + internal::sql_cursor m_cur; +}; + + +class icursor_iterator; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class icursor_iterator_icursorstream; +class icursorstream_icursor_iterator; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Simple read-only cursor represented as a stream of results +/** SQL cursors can be tricky, especially in C++ since the two languages seem + * to have been designed on different planets. An SQL cursor has two singular + * positions akin to `end()` on either side of the underlying result set. + * + * These cultural differences are hidden from view somewhat by libpqxx, which + * tries to make SQL cursors behave more like familiar C++ entities such as + * iterators, sequences, streams, and containers. + * + * Data is fetched from the cursor as a sequence of result objects. Each of + * these will contain the number of rows defined as the stream's stride, except + * of course the last block of data which may contain fewer rows. + * + * This class can create or adopt cursors that live outside any backend + * transaction, which your backend version may not support. + */ +class PQXX_LIBEXPORT icursorstream +{ +public: + using size_type = cursor_base::size_type; + using difference_type = cursor_base::difference_type; + + /// Set up a read-only, forward-only cursor. + /** Roughly equivalent to a C++ Standard Library istream, this cursor type + * supports only two operations: reading a block of rows while moving + * forward, and moving forward without reading any data. + * + * @param context Transaction context in which this cursor will be active. + * @param query SQL query whose results this cursor shall iterate. + * @param basename Suggested name for the SQL cursor; the library will append + * a unique code to ensure its uniqueness. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + */ + icursorstream( + transaction_base &context, std::string_view query, + std::string_view basename, difference_type sstride = 1); + + /// Adopt existing SQL cursor. Use with care. + /** Forms a cursor stream around an existing SQL cursor, as returned by e.g. + * a server-side function. The SQL cursor will be cleaned up by the stream's + * destructor as if it had been created by the stream; cleaning it up by hand + * or adopting the same cursor twice is an error. + * + * Passing the name of the cursor as a string is not allowed, both to avoid + * confusion with the other constructor and to discourage unnecessary use of + * adopted cursors. + * + * @warning It is technically possible to adopt a "WITH HOLD" cursor, i.e. a + * cursor that stays alive outside its creating transaction. However, any + * cursor stream (including the underlying SQL cursor, naturally) must be + * destroyed before its transaction context object is destroyed. Therefore + * the only way to use SQL's WITH HOLD feature is to adopt the cursor, but + * defer doing so until after entering the transaction context that will + * eventually destroy it. + * + * @param context Transaction context in which this cursor will be active. + * @param cname Result field containing the name of the SQL cursor to adopt. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + * @param op Ownership policy. Determines whether the cursor underlying this + * stream will be destroyed when the stream is closed. + */ + icursorstream( + transaction_base &context, field const &cname, difference_type sstride = 1, + cursor_base::ownership_policy op = cursor_base::owned); + + /// Return `true` if this stream may still return more data. + constexpr operator bool() const &noexcept { return not m_done; } + + /// Read new value into given result object; same as operator `>>`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C.get(r1).get(r2);") + */ + icursorstream &get(result &res) + { + res = fetchblock(); + return *this; + } + /// Read new value into given result object; same as `get(result&)`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C >> r1 >> r2;") + */ + icursorstream &operator>>(result &res) { return get(res); } + + /// Move given number of rows forward without reading data. + /** Ignores any stride that you may have set. It moves by a given number of + * rows, not a number of strides. + * + * @return Reference to this stream itself, to facilitate "chained" + * invocations. + */ + icursorstream &ignore(std::streamsize n = 1) &; + + /// Change stride, i.e. the number of rows to fetch per read operation. + /** + * @param stride Must be a positive number. + */ + void set_stride(difference_type stride) &; + [[nodiscard]] constexpr difference_type stride() const noexcept + { + return m_stride; + } + +private: + result fetchblock(); + + friend class internal::gate::icursorstream_icursor_iterator; + size_type forward(size_type n = 1); + void insert_iterator(icursor_iterator *) noexcept; + void remove_iterator(icursor_iterator *) const noexcept; + + void service_iterators(difference_type); + + internal::sql_cursor m_cur; + + difference_type m_stride; + difference_type m_realpos, m_reqpos; + + mutable icursor_iterator *m_iterators; + + bool m_done; +}; + + +/// Approximate istream_iterator for icursorstream. +/** Intended as an implementation of an input_iterator (as defined by the C++ + * Standard Library), this class supports only two basic operations: reading + * the current element, and moving forward. In addition to the minimal + * guarantees for istream_iterators, this class supports multiple successive + * reads of the same position (the current result set is cached in the + * iterator) even after copying and even after new data have been read from the + * stream. This appears to be a requirement for input_iterators. Comparisons + * are also supported in the general case. + * + * The iterator does not care about its own position, however. Moving an + * iterator forward moves the underlying stream forward and reads the data from + * the new stream position, regardless of the iterator's old position in the + * stream. + * + * The stream's stride defines the granularity for all iterator movement or + * access operations, i.e. "ici += 1" advances the stream by one stride's worth + * of rows, and "*ici++" reads one stride's worth of rows from the stream. + * + * @warning Do not read from the underlying stream or its cursor, move its read + * position, or change its stride, between the time the first icursor_iterator + * on it is created and the time its last icursor_iterator is destroyed. + * + * @warning Manipulating these iterators within the context of a single cursor + * stream is not thread-safe. Creating a new iterator, copying one, + * or destroying one affects the stream as a whole. + */ +class PQXX_LIBEXPORT icursor_iterator +{ +public: + using iterator_category = std::input_iterator_tag; + using value_type = result; + using pointer = result const *; + using reference = result const &; + using istream_type = icursorstream; + using size_type = istream_type::size_type; + using difference_type = istream_type::difference_type; + + icursor_iterator() noexcept; + explicit icursor_iterator(istream_type &) noexcept; + icursor_iterator(icursor_iterator const &) noexcept; + ~icursor_iterator() noexcept; + + result const &operator*() const + { + refresh(); + return m_here; + } + result const *operator->() const + { + refresh(); + return &m_here; + } + icursor_iterator &operator++(); + icursor_iterator operator++(int); + icursor_iterator &operator+=(difference_type); + icursor_iterator &operator=(icursor_iterator const &) noexcept; + + [[nodiscard]] bool operator==(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + [[nodiscard]] bool operator<(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator>(icursor_iterator const &rhs) const + { + return rhs < *this; + } + [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const + { + return not(*this > rhs); + } + [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const + { + return not(*this < rhs); + } + +private: + void refresh() const; + + friend class internal::gate::icursor_iterator_icursorstream; + difference_type pos() const noexcept { return m_pos; } + void fill(result const &); + + icursorstream *m_stream{nullptr}; + result m_here; + difference_type m_pos; + icursor_iterator *m_prev{nullptr}, *m_next{nullptr}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction new file mode 100644 index 0000000..fa8d264 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction @@ -0,0 +1,8 @@ +/** pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/dbtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction.hxx new file mode 100644 index 0000000..d85cb17 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/dbtransaction.hxx @@ -0,0 +1,70 @@ +/* Definition of the pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/dbtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_DBTRANSACTION +#define PQXX_H_DBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/transaction_base.hxx" + +namespace pqxx +{ +/// Abstract transaction base class: bracket transactions on the database. +/** + * @ingroup transactions + * + * Use a dbtransaction-derived object such as "work" (transaction<>) to enclose + * operations on a database in a single "unit of work." This ensures that the + * whole series of operations either succeeds as a whole or fails completely. + * In no case will it leave half-finished work behind in the database. + * + * Once processing on a transaction has succeeded and any changes should be + * allowed to become permanent in the database, call commit(). If something + * has gone wrong and the changes should be forgotten, call abort() instead. + * If you do neither, an implicit abort() is executed at destruction time. + * + * It is an error to abort a transaction that has already been committed, or to + * commit a transaction that has already been aborted. Aborting an already + * aborted transaction or committing an already committed one is allowed, to + * make error handling easier. Repeated aborts or commits have no effect after + * the first one. + * + * Database transactions are not suitable for guarding long-running processes. + * If your transaction code becomes too long or too complex, consider ways to + * break it up into smaller ones. Unfortunately there is no universal recipe + * for this. + * + * The actual operations for committing/aborting the backend transaction are + * implemented by a derived class. The implementing concrete class must also + * call @ref close from its destructor. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE dbtransaction : public transaction_base +{ +protected: + /// Begin transaction. + explicit dbtransaction(connection &c) : transaction_base{c} {} + /// Begin transaction. + dbtransaction(connection &c, std::string_view tname) : + transaction_base{c, tname} + {} + /// Begin transaction. + dbtransaction( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + transaction_base{c, tname, rollback_cmd} + {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler new file mode 100644 index 0000000..ea572ee --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler @@ -0,0 +1,8 @@ +/** pqxx::errorhandler class. + * + * Callbacks for handling errors and warnings. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler.hxx new file mode 100644 index 0000000..2ffb570 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/errorhandler.hxx @@ -0,0 +1,92 @@ +/* Definition of the pqxx::errorhandler class. + * + * pqxx::errorhandler handlers errors and warnings in a database session. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/errorhandler instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ERRORHANDLER +#define PQXX_H_ERRORHANDLER + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/types.hxx" + + +namespace pqxx::internal::gate +{ +class errorhandler_connection; +} + + +namespace pqxx +{ +/** + * @addtogroup errorhandler + */ +//@{ + +/// Base class for error-handler callbacks. +/** To receive errors and warnings from a connection, subclass this with your + * own error-handler functor, and instantiate it for the connection. Destroying + * the handler un-registers it. + * + * A connection can have multiple error handlers at the same time. When the + * database connection emits an error or warning message, it passes the message + * to each error handler, starting with the most recently registered one and + * progressing towards the oldest one. However an error handler may also + * instruct the connection not to pass the message to further handlers by + * returning "false." + * + * @warning Strange things happen when a result object outlives its parent + * connection. If you register an error handler on a connection, then you must + * not access the result after destroying the connection. This applies even if + * you destroy the error handler first! + */ +class PQXX_LIBEXPORT errorhandler +{ +public: + explicit errorhandler(connection &); + virtual ~errorhandler(); + + /// Define in subclass: receive an error or warning message from the + /// database. + /** + * @return Whether the same error message should also be passed to the + * remaining, older errorhandlers. + */ + virtual bool operator()(char const msg[]) noexcept = 0; + + errorhandler() = delete; + errorhandler(errorhandler const &) = delete; + errorhandler &operator=(errorhandler const &) = delete; + +private: + connection *m_home; + + friend class internal::gate::errorhandler_connection; + void unregister() noexcept; +}; + + +/// An error handler that suppresses any previously registered error handlers. +class quiet_errorhandler : public errorhandler +{ +public: + /// Suppress error notices. + quiet_errorhandler(connection &conn) : errorhandler{conn} {} + + /// Revert to previous handling of error notices. + virtual bool operator()(char const[]) noexcept override { return false; } +}; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except new file mode 100644 index 0000000..e5dd508 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except @@ -0,0 +1,8 @@ +/** libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except.hxx new file mode 100644 index 0000000..24f9594 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/except.hxx @@ -0,0 +1,447 @@ +/* Definition of libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/except instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_EXCEPT +#define PQXX_H_EXCEPT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + + +namespace pqxx +{ +/** + * @addtogroup exception Exception classes + * + * These exception classes follow, roughly, the two-level hierarchy defined by + * the PostgreSQL SQLSTATE error codes (see Appendix A of the PostgreSQL + * documentation corresponding to your server version). This is not a complete + * mapping though. There are other differences as well, e.g. the error code + * for `statement_completion_unknown` has a separate status in libpqxx as + * @ref in_doubt_error, and `too_many_connections` is classified as a + * `broken_connection` rather than a subtype of `insufficient_resources`. + * + * @see http://www.postgresql.org/docs/9.4/interactive/errcodes-appendix.html + * + * @{ + */ + +/// Run-time failure encountered by libpqxx, similar to std::runtime_error. +struct PQXX_LIBEXPORT failure : std::runtime_error +{ + explicit failure(std::string const &); +}; + + +/// Exception class for lost or failed backend connection. +/** + * @warning When this happens on Unix-like systems, you may also get a SIGPIPE + * signal. That signal aborts the program by default, so if you wish to be + * able to continue after a connection breaks, be sure to disarm this signal. + * + * If you're working on a Unix-like system, see the manual page for + * `signal` (2) on how to deal with SIGPIPE. The easiest way to make this + * signal harmless is to make your program ignore it: + * + * ```cxx + * #include + * + * int main() + * { + * signal(SIGPIPE, SIG_IGN); + * // ... + * ``` + */ +struct PQXX_LIBEXPORT broken_connection : failure +{ + broken_connection(); + explicit broken_connection(std::string const &); +}; + + +/// The caller attempted to set a variable to null, which is not allowed. +struct PQXX_LIBEXPORT variable_set_to_null : failure +{ + variable_set_to_null(); + explicit variable_set_to_null(std::string const &); +}; + + +/// Exception class for failed queries. +/** Carries, in addition to a regular error message, a copy of the failed query + * and (if available) the SQLSTATE value accompanying the error. + */ +class PQXX_LIBEXPORT sql_error : public failure +{ + /// Query string. Empty if unknown. + std::string const m_query; + /// SQLSTATE string describing the error type, if known; or empty string. + std::string const m_sqlstate; + +public: + explicit sql_error( + std::string const &whatarg = "", std::string const &Q = "", + char const sqlstate[] = nullptr); + virtual ~sql_error() noexcept override; + + /// The query whose execution triggered the exception + [[nodiscard]] PQXX_PURE std::string const &query() const noexcept; + + /// SQLSTATE error code if known, or empty string otherwise. + [[nodiscard]] PQXX_PURE std::string const &sqlstate() const noexcept; +}; + + +/// "Help, I don't know whether transaction was committed successfully!" +/** Exception that might be thrown in rare cases where the connection to the + * database is lost while finishing a database transaction, and there's no way + * of telling whether it was actually executed by the backend. In this case + * the database is left in an indeterminate (but consistent) state, and only + * manual inspection will tell which is the case. + */ +struct PQXX_LIBEXPORT in_doubt_error : failure +{ + explicit in_doubt_error(std::string const &); +}; + + +/// The backend saw itself forced to roll back the ongoing transaction. +struct PQXX_LIBEXPORT transaction_rollback : sql_error +{ + explicit transaction_rollback( + std::string const &whatarg, std::string const &q = "", + char const sqlstate[] = nullptr); +}; + + +/// Transaction failed to serialize. Please retry it. +/** Can only happen at transaction isolation levels REPEATABLE READ and + * SERIALIZABLE. + * + * The current transaction cannot be committed without violating the guarantees + * made by its isolation level. This is the effect of a conflict with another + * ongoing transaction. The transaction may still succeed if you try to + * perform it again. + */ +struct PQXX_LIBEXPORT serialization_failure : transaction_rollback +{ + explicit serialization_failure( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// We can't tell whether our last statement succeeded. +struct PQXX_LIBEXPORT statement_completion_unknown : transaction_rollback +{ + explicit statement_completion_unknown( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// The ongoing transaction has deadlocked. Retrying it may help. +struct PQXX_LIBEXPORT deadlock_detected : transaction_rollback +{ + explicit deadlock_detected( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// Internal error in libpqxx library +struct PQXX_LIBEXPORT internal_error : std::logic_error +{ + explicit internal_error(std::string const &); +}; + + +/// Error in usage of libpqxx library, similar to std::logic_error +struct PQXX_LIBEXPORT usage_error : std::logic_error +{ + explicit usage_error(std::string const &); +}; + + +/// Invalid argument passed to libpqxx, similar to std::invalid_argument +struct PQXX_LIBEXPORT argument_error : std::invalid_argument +{ + explicit argument_error(std::string const &); +}; + + +/// Value conversion failed, e.g. when converting "Hello" to int. +struct PQXX_LIBEXPORT conversion_error : std::domain_error +{ + explicit conversion_error(std::string const &); +}; + + +/// Could not convert value to string: not enough buffer space. +struct PQXX_LIBEXPORT conversion_overrun : conversion_error +{ + explicit conversion_overrun(std::string const &); +}; + + +/// Something is out of range, similar to std::out_of_range +struct PQXX_LIBEXPORT range_error : std::out_of_range +{ + explicit range_error(std::string const &); +}; + + +/// Query returned an unexpected number of rows. +struct PQXX_LIBEXPORT unexpected_rows : public range_error +{ + explicit unexpected_rows(std::string const &msg) : range_error{msg} {} +}; + + +/// Database feature not supported in current setup. +struct PQXX_LIBEXPORT feature_not_supported : sql_error +{ + explicit feature_not_supported( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Error in data provided to SQL statement. +struct PQXX_LIBEXPORT data_exception : sql_error +{ + explicit data_exception( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT integrity_constraint_violation : sql_error +{ + explicit integrity_constraint_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT restrict_violation : integrity_constraint_violation +{ + explicit restrict_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT not_null_violation : integrity_constraint_violation +{ + explicit not_null_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT foreign_key_violation : integrity_constraint_violation +{ + explicit foreign_key_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT unique_violation : integrity_constraint_violation +{ + explicit unique_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT check_violation : integrity_constraint_violation +{ + explicit check_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_state : sql_error +{ + explicit invalid_cursor_state( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_sql_statement_name : sql_error +{ + explicit invalid_sql_statement_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_name : sql_error +{ + explicit invalid_cursor_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT syntax_error : sql_error +{ + /// Approximate position in string where error occurred, or -1 if unknown. + int const error_position; + + explicit syntax_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr, int pos = -1) : + sql_error{err, Q, sqlstate}, error_position{pos} + {} +}; + +struct PQXX_LIBEXPORT undefined_column : syntax_error +{ + explicit undefined_column( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_function : syntax_error +{ + explicit undefined_function( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_table : syntax_error +{ + explicit undefined_table( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT insufficient_privilege : sql_error +{ + explicit insufficient_privilege( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Resource shortage on the server +struct PQXX_LIBEXPORT insufficient_resources : sql_error +{ + explicit insufficient_resources( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT disk_full : insufficient_resources +{ + explicit disk_full( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT out_of_memory : insufficient_resources +{ + explicit out_of_memory( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT too_many_connections : broken_connection +{ + explicit too_many_connections(std::string const &err) : + broken_connection{err} + {} +}; + +/// PL/pgSQL error +/** Exceptions derived from this class are errors from PL/pgSQL procedures. + */ +struct PQXX_LIBEXPORT plpgsql_error : sql_error +{ + explicit plpgsql_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Exception raised in PL/pgSQL procedure +struct PQXX_LIBEXPORT plpgsql_raise : plpgsql_error +{ + explicit plpgsql_raise( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_no_data_found : plpgsql_error +{ + explicit plpgsql_no_data_found( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_too_many_rows : plpgsql_error +{ + explicit plpgsql_too_many_rows( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT blob_already_exists : failure +{ + explicit blob_already_exists(std::string const &); +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field new file mode 100644 index 0000000..37cb69e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field @@ -0,0 +1,8 @@ +/** pqxx::field class. + * + * pqxx::field refers to a field in a query result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field.hxx new file mode 100644 index 0000000..b8b869f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/field.hxx @@ -0,0 +1,542 @@ +/* Definitions for the pqxx::field class. + * + * pqxx::field refers to a field in a query result. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_FIELD +#define PQXX_H_FIELD + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/array.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" + +namespace pqxx +{ +/// Reference to a field in a result set. +/** A field represents one entry in a row. It represents an actual value + * in the result set, and can be converted to various types. + */ +class PQXX_LIBEXPORT field +{ +public: + using size_type = field_size_type; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + /** Create field as reference to a field in a result set. + * @param r Row that this field is part of. + * @param c Column number of this field. + */ + [[deprecated( + "Do not construct fields yourself. Get them from the row.")]] field(row const &r, row_size_type c) noexcept; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + [[deprecated( + "Do not construct fields yourself. Get them from the " + "row.")]] field() noexcept = default; + + /** + * @name Comparison + */ + //@{ + // TODO: noexcept. Breaks ABI. + /// Byte-by-byte comparison of two fields (all nulls are considered equal) + /** @warning null handling is still open to discussion and change! + * + * Handling of null values differs from that in SQL where a comparison + * involving a null value yields null, so nulls are never considered equal + * to one another or even to themselves. + * + * Null handling also probably differs from the closest equivalent in C++, + * which is the NaN (Not-a-Number) value, a singularity comparable to + * SQL's null. This is because the builtin == operator demands that a == a. + * + * The usefulness of this operator is questionable. No interpretation + * whatsoever is imposed on the data; 0 and 0.0 are considered different, + * as are null vs. the empty string, or even different (but possibly + * equivalent and equally valid) encodings of the same Unicode character + * etc. + */ + [[nodiscard]] PQXX_PURE bool operator==(field const &) const; + + /// Byte-by-byte comparison (all nulls are considered equal) + /** @warning See operator==() for important information about this operator + */ + [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /** + * @name Column information + */ + //@{ + /// Column name. + [[nodiscard]] PQXX_PURE char const *name() const &; + + /// Column type. + [[nodiscard]] oid PQXX_PURE type() const; + + /// What table did this column come from? + [[nodiscard]] PQXX_PURE oid table() const; + + /// Return row number. The first row is row 0, the second is row 1, etc. + PQXX_PURE constexpr row_size_type num() const noexcept { return col(); } + + /// What column number in its originating table did this column come from? + [[nodiscard]] PQXX_PURE row_size_type table_column() const; + //@} + + /** + * @name Content access + */ + //@{ + /// Read as `string_view`, or an empty one if null. + /** The result only remains usable while the data for the underlying + * @ref result exists. Once all `result` objects referring to that data have + * been destroyed, the `string_view` will no longer point to valid memory. + */ + [[nodiscard]] PQXX_PURE std::string_view view() const & + { + return std::string_view(c_str(), size()); + } + + /// Read as plain C string. + /** Since the field's data is stored internally in the form of a + * zero-terminated C string, this is the fastest way to read it. Use the + * to() or as() functions to convert the string to other types such as + * `int`, or to C++ strings. + * + * Do not use this for BYTEA values, or other binary values. To read those, + * convert the value to your desired type using `to()` or `as()`. For + * example: `f.as>()`. + */ + [[nodiscard]] PQXX_PURE char const *c_str() const &; + + /// Is this field's value null? + [[nodiscard]] PQXX_PURE bool is_null() const noexcept; + + /// Return number of bytes taken up by the field's value. + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + + /// Read value into obj; or if null, leave obj untouched and return `false`. + /** This can be used with optional types (except pointers other than C-style + * strings). + */ + template + auto to(T &obj) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + if (is_null()) + { + return false; + } + else + { + auto const bytes{c_str()}; + from_string(bytes, obj); + return true; + } + } + + /// Read field as a composite value, write its components into `fields`. + /** @warning This is still experimental. It may change or be replaced. + * + * Returns whether the field was null. If it was, it will not touch the + * values in `fields`. + */ + template bool composite_to(T &...fields) const + { + if (is_null()) + { + return false; + } + else + { + parse_composite(m_home.m_encoding, view(), fields...); + return true; + } + } + + /// Read value into obj; or leave obj untouched and return `false` if null. + template bool operator>>(T &obj) const { return to(obj); } + + /// Read value into obj; or if null, use default value and return `false`. + /** This can be used with `std::optional`, as well as with standard smart + * pointer types, but not with raw pointers. If the conversion from a + * PostgreSQL string representation allocates a pointer (e.g. using `new`), + * then the object's later deallocation should be baked in as well, right + * from the point where the object is created. So if you want a pointer, use + * a smart pointer, not a raw pointer. + * + * There is one exception, of course: C-style strings. Those are just + * pointers to the field's internal text data. + */ + template + auto to(T &obj, T const &default_value) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = from_string(this->view()); + return not null; + } + + /// Return value as object of given type, or default value if null. + /** Note that unless the function is instantiated with an explicit template + * argument, the Default value's type also determines the result type. + */ + template T as(T const &default_value) const + { + if (is_null()) + return default_value; + else + return from_string(this->view()); + } + + /// Return value as object of given type, or throw exception if null. + /** Use as `as>()` or `as()` as + * an alternative to `get()`; this is disabled for use with raw pointers + * (other than C-strings) because storage for the value can't safely be + * allocated here + */ + template T as() const + { + if (is_null()) + { + if constexpr (not nullness::has_null) + internal::throw_null_conversion(type_name); + else + return nullness::null(); + } + else + { + return from_string(this->view()); + } + } + + /// Return value wrapped in some optional type (empty for nulls). + /** Use as `get()` as before to obtain previous behavior, or specify + * container type with `get()` + */ + template class O = std::optional> + constexpr O get() const + { + return as>(); + } + + // TODO: constexpr noexcept, once array_parser constructor gets those. + /// Parse the field as an SQL array. + /** Call the parser to retrieve values (and structure) from the array. + * + * Make sure the @ref result object stays alive until parsing is finished. If + * you keep the @ref row of `field` object alive, it will keep the @ref + * result object alive as well. + */ + array_parser as_array() const & + { + return array_parser{c_str(), m_home.m_encoding}; + } + //@} + + +protected: + constexpr result const &home() const noexcept { return m_home; } + constexpr result::size_type idx() const noexcept { return m_row; } + constexpr row_size_type col() const noexcept { return m_col; } + + // TODO: Create gates. + friend class pqxx::result; + friend class pqxx::row; + field( + result const &r, result_size_type row_num, row_size_type col_num) noexcept + : + m_col{col_num}, m_home{r}, m_row{row_num} + {} + + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + row_size_type m_col; + +private: + result m_home; + result::size_type m_row; +}; + + +template<> inline bool field::to(std::string &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = std::string{view()}; + return not null; +} + + +template<> +inline bool field::to( + std::string &obj, std::string const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = std::string{view()}; + return not null; +} + + +/// Specialization: `to(char const *&)`. +/** The buffer has the same lifetime as the data in this result (i.e. of this + * result object, or the last remaining one copied from it etc.), so take care + * not to use it after the last result object referring to this query result is + * destroyed. + */ +template<> inline bool field::to(char const *&obj) const +{ + bool const null{is_null()}; + if (not null) + obj = c_str(); + return not null; +} + + +template<> inline bool field::to(std::string_view &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = view(); + return not null; +} + + +template<> +inline bool field::to( + std::string_view &obj, std::string_view const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = view(); + return not null; +} + + +template<> inline std::string_view field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return view(); +} + + +template<> +inline std::string_view +field::as(std::string_view const &default_value) const +{ + return is_null() ? default_value : view(); +} + + +template<> inline bool field::to(zview &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = zview{c_str(), size()}; + return not null; +} + + +template<> +inline bool field::to(zview &obj, zview const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = zview{c_str(), size()}; + return not null; +} + + +template<> inline zview field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return zview{c_str(), size()}; +} + + +template<> inline zview field::as(zview const &default_value) const +{ + return is_null() ? default_value : zview{c_str(), size()}; +} + + +template> +class field_streambuf : public std::basic_streambuf +{ +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = std::ios::openmode; + using seekdir = std::ios::seekdir; + + explicit field_streambuf(field const &f) : m_field{f} { initialize(); } + +protected: + virtual int sync() override { return traits_type::eof(); } + + virtual pos_type seekoff(off_type, seekdir, openmode) override + { + return traits_type::eof(); + } + virtual pos_type seekpos(pos_type, openmode) override + { + return traits_type::eof(); + } + virtual int_type overflow(int_type) override { return traits_type::eof(); } + virtual int_type underflow() override { return traits_type::eof(); } + +private: + field const &m_field; + + int_type initialize() + { + auto g{static_cast(const_cast(m_field.c_str()))}; + this->setg(g, g, g + std::size(m_field)); + return int_type(std::size(m_field)); + } +}; + + +/// Input stream that gets its data from a result field +/** Use this class exactly as you would any other istream to read data from a + * field. All formatting and streaming operations of `std::istream` are + * supported. What you'll typically want to use, however, is the fieldstream + * alias (which defines a @ref basic_fieldstream for `char`). This is similar + * to how e.g. `std::ifstream` relates to `std::basic_ifstream`. + * + * This class has only been tested for the char type (and its default traits). + */ +template> +class basic_fieldstream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + basic_fieldstream(field const &f) : super{nullptr}, m_buf{f} + { + super::init(&m_buf); + } + +private: + field_streambuf m_buf; +}; + +using fieldstream = basic_fieldstream; + +/// Write a result field to any type of stream +/** This can be convenient when writing a field to an output stream. More + * importantly, it lets you write a field to e.g. a `stringstream` which you + * can then use to read, format and convert the field in ways that to() does + * not support. + * + * Example: parse a field into a variable of the nonstandard + * "long long" type. + * + * ```cxx + * extern result R; + * long long L; + * stringstream S; + * + * // Write field's string into S + * S << R[0][0]; + * + * // Parse contents of S into L + * S >> L; + * ``` + */ +template +inline std::basic_ostream & +operator<<(std::basic_ostream &s, field const &value) +{ + s.write(value.c_str(), std::streamsize(std::size(value))); + return s; +} + + +/// Convert a field's value to type `T`. +/** Unlike the "regular" `from_string`, this knows how to deal with null + * values. + */ +template inline T from_string(field const &value) +{ + if (value.is_null()) + { + if constexpr (nullness::has_null) + return nullness::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + return from_string(value.view()); + } +} + + +/// Convert a field's value to `nullptr_t`. +/** Yes, you read that right. This conversion does nothing useful. It always + * returns `nullptr`. + * + * Except... what if the field is not null? In that case, this throws + * @ref conversion_error. + */ +template<> +inline std::nullptr_t from_string(field const &value) +{ + if (not value.is_null()) + throw conversion_error{ + "Extracting non-null field into nullptr_t variable."}; + return nullptr; +} + + +/// Convert a field to a string. +template<> PQXX_LIBEXPORT std::string to_string(field const &value); +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/array-composite.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/array-composite.hxx new file mode 100644 index 0000000..d2b6603 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/array-composite.hxx @@ -0,0 +1,305 @@ +#if !defined(PQXX_ARRAY_COMPOSITE_HXX) +# define PQXX_ARRAY_COMPOSITE_HXX + +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +// Find the end of a double-quoted string. +/** `input[pos]` must be the opening double quote. + * + * Returns the offset of the first position after the closing quote. + */ +inline std::size_t scan_double_quoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + // XXX: find_char<'"', '\\'>(). + auto next{scan(input, size, pos)}; + bool at_quote{false}; + for (pos = next, next = scan(input, size, pos); pos < size; + pos = next, next = scan(input, size, pos)) + { + if (at_quote) + { + if (next - pos == 1 and input[pos] == '"') + { + // We just read a pair of double quotes. Carry on. + at_quote = false; + } + else + { + // We just read one double quote, and now we're at a character that's + // not a second double quote. Ergo, that last character was the + // closing double quote and this is the position right after it. + return pos; + } + } + else if (next - pos == 1) + { + switch (input[pos]) + { + case '\\': + // Backslash escape. Skip ahead by one more character. + pos = next; + next = scan(input, size, pos); + break; + + case '"': + // This is either the closing double quote, or the first of a pair of + // double quotes. + at_quote = true; + break; + } + } + else + { + // Multibyte character. Carry on. + } + } + if (not at_quote) + throw argument_error{ + "Missing closing double-quote: " + std::string{input}}; + return pos; +} + + +/// Un-quote and un-escape a double-quoted SQL string. +inline std::string parse_double_quoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + // Maximum output size is same as the input size, minus the opening and + // closing quotes. Or in the extreme opposite case, the real number could be + // half that. Usually it'll be a pretty close estimate. + output.reserve(std::size_t(end - pos - 2)); + + for (auto here{scan(input, end, pos)}, next{scan(input, end, here)}; + here < end - 1; here = next, next = scan(input, end, here)) + { + // A backslash here is always an escape. So is a double-quote, since we're + // inside the double-quoted string. In either case, we can just ignore the + // escape character and use the next character. This is the one redeeming + // feature of SQL's escaping system. + if ((next - here == 1) and (input[here] == '\\' or input[here] == '"')) + { + // Skip escape. + here = next; + next = scan(input, end, here); + } + output.append(input + here, input + next); + } + return output; +} + + +/// Find the end of an unquoted string in an array or composite-type value. +/** Stops when it gets to the end of the input; or when it sees any of the + * characters in STOP which has not been escaped. + * + * For array values, STOP is a comma, a semicolon, or a closing brace. For + * a value of a composite type, STOP is a comma or a closing parenthesis. + */ +template +inline std::size_t scan_unquoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + bool at_backslash{false}; + auto next{scan(input, size, pos)}; + while ((pos < size) and + ((next - pos) > 1 or at_backslash or ((input[pos] != STOP) and ...))) + { + pos = next; + next = scan(input, size, pos); + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + } + return pos; +} + + +/// Parse an unquoted array entry or cfield of a composite-type field. +inline std::string parse_unquoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + bool at_backslash{false}; + output.reserve(end - pos); + for (auto next{scan(input, end, pos)}; pos < end; + pos = next, next = scan(input, end, pos)) + { + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + if (not at_backslash) + output.append(input + pos, next - pos); + } + return output; +} + + +/// Parse a field of a composite-type value. +/** `T` is the C++ type of the field we're parsing, and `index` is its + * zero-based number. + * + * Strip off the leading parenthesis or bracket yourself before parsing. + * However, this function will parse the lcosing parenthesis or bracket. + * + * After a successful parse, `pos` will point at `std::end(text)`. + * + * For the purposes of parsing, ranges and arrays count as compositve values, + * so this function supports parsing those. If you specifically need a closing + * parenthesis, check afterwards that `text` did not end in a bracket instead. + * + * @param index Index of the current field, zero-based. It will increment for + * the next field. + * @param input Full input text for the entire composite-type value. + * @param pos Starting position (in `input`) of the field that we're parsing. + * After parsing, this will point at the beginning of the next field if + * there is one, or one position past the last character otherwise. + * @param field Destination for the parsed value. + * @param scan Glyph scanning function for the relevant encoding type. + * @param last_field Number of the last field in the value (zero-based). When + * parsing the last field, this will equal `index`. + */ +template +inline void parse_composite_field( + std::size_t &index, std::string_view input, std::size_t &pos, T &field, + glyph_scanner_func *scan, std::size_t last_field) +{ + assert(index <= last_field); + auto next{scan(std::data(input), std::size(input), pos)}; + if ((next - pos) != 1) + throw conversion_error{"Non-ASCII character in composite-type syntax."}; + + // Expect a field. + switch (input[pos]) + { + case ',': + case ')': + case ']': + // The field is empty, i.e, null. + if constexpr (nullness::has_null) + field = nullness::null(); + else + throw conversion_error{ + "Can't read composite field " + to_string(index) + ": C++ type " + + type_name + " does not support nulls."}; + break; + + case '"': { + auto const stop{scan_double_quoted_string( + std::data(input), std::size(input), pos, scan)}; + auto const text{ + parse_double_quoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + + default: { + auto const stop{scan_unquoted_string<',', ')', ']'>( + std::data(input), std::size(input), pos, scan)}; + auto const text{parse_unquoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + } + + // Expect a comma or a closing parenthesis. + next = scan(std::data(input), std::size(input), pos); + + if ((next - pos) != 1) + throw conversion_error{ + "Unexpected non-ASCII character after composite field: " + + std::string{input}}; + + if (index < last_field) + { + if (input[pos] != ',') + throw conversion_error{ + "Found '" + std::string{input[pos]} + + "' in composite value where comma was expected: " + std::data(input)}; + } + else + { + if (input[pos] == ',') + throw conversion_error{ + "Composite value contained more fields than the expected " + + to_string(last_field) + ": " + std::data(input)}; + if (input[pos] != ')' and input[pos] != ']') + throw conversion_error{ + "Composite value has unexpected characters where closing parenthesis " + "was expected: " + + std::string{input}}; + if (next != std::size(input)) + throw conversion_error{ + "Composite value has unexpected text after closing parenthesis: " + + std::string{input}}; + } + + pos = next; + ++index; +} + + +/// Conservatively estimate buffer size needed for a composite field. +template +inline std::size_t size_composite_field_buffer(T const &field) +{ + if constexpr (is_unquoted_safe) + { + // Safe to copy, without quotes or escaping. Drop the terminating zero. + return size_buffer(field) - 1; + } + else + { + // + Opening quote. + // + Field budget. + // - Terminating zero. + // + Escaping for each byte in the field's string representation. + // - Escaping for terminating zero. + // + Closing quote. + return 1 + 2 * (size_buffer(field) - 1) + 1; + } +} + + +template +inline void write_composite_field(char *&pos, char *end, T const &field) +{ + if constexpr (is_unquoted_safe) + { + // No need for quoting or escaping. Convert it straight into its final + // place in the buffer, and "backspace" the trailing zero. + pos = string_traits::into_buf(pos, end, field) - 1; + } + else + { + // The field may need escaping, which means we need an intermediate buffer. + // To avoid allocating that at run time, we use the end of the buffer that + // we have. + auto const budget{size_buffer(field)}; + *pos++ = '"'; + + // Now escape buf into its final position. + for (char const c : string_traits::to_buf(end - budget, end, field)) + { + if ((c == '"') or (c == '\\')) + *pos++ = '\\'; + + *pos++ = c; + } + + *pos++ = '"'; + } + + *pos++ = ','; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/callgate.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/callgate.hxx new file mode 100644 index 0000000..42f7703 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/callgate.hxx @@ -0,0 +1,70 @@ +#ifndef PQXX_H_CALLGATE +#define PQXX_H_CALLGATE + +/* +Here's what a typical gate class definition looks like: + +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE @gateclass@ : callgate<@host@> +{ + friend class @client@; + + @gateclass@(reference x) : super(x) {} + + // Methods here. Use home() to access the host-class object. +}; +} // namespace pqxx::internal::gate +*/ + +namespace pqxx::internal +{ +/// Base class for call gates. +/** + * A call gate defines a limited, private interface on the host class that + * specified client classes can access. + * + * The metaphor works as follows: the gate stands in front of a "home," which + * is really a class, and only lets specific friends in. + * + * To implement a call gate that gives client C access to host H, + * * derive a gate class from callgate; + * * make the gate class a friend of H; + * * make C a friend of the gate class; and + * * implement "stuff C can do with H" as private members in the gate class. + * + * This special kind of "gated" friendship gives C private access to H, but + * only through an expressly limited interface. The gate class can access its + * host object as home(). + * + * Keep gate classes entirely stateless. They should be ultra-lightweight + * wrappers for their host classes, and be optimized away as much as possible + * by the compiler. Once you start adding state, you're on a slippery slope + * away from the pure, clean, limited interface pattern that gate classes are + * meant to implement. + * + * Ideally, all member functions of the gate class should be one-liners passing + * calls straight on to the host class. It can be useful however to break this + * rule temporarily during inter-class refactoring. + */ +template class PQXX_PRIVATE callgate +{ +protected: + /// This class, to keep constructors easy. + using super = callgate; + /// A reference to the host class. Helps keep constructors easy. + using reference = HOME &; + + callgate(reference x) : m_home(x) {} + + /// The home object. The gate class has full "private" access. + reference home() const noexcept { return m_home; } + +private: + reference m_home; +}; +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/concat.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/concat.hxx new file mode 100644 index 0000000..cd28bde --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/concat.hxx @@ -0,0 +1,45 @@ +#if !defined(PQXX_CONCAT_HXX) +# define PQXX_CONCAT_HXX + +# include +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +/// Convert item to a string, write it into [here, end). +template +void render_item(TYPE const &item, char *&here, char *end) +{ + here = string_traits::into_buf(here, end, item) - 1; +} + + +// C++20: Support non-random_access_range ranges. +/// Efficiently combine a bunch of items into one big string. +/** Use this as an optimised version of string concatentation. It takes just + * about any type; it will represent each item as a string according to its + * @ref string_traits. + * + * This is a simpler, more specialised version of @ref separated_list for a + * statically known series of items, possibly of different types. + */ +template +[[nodiscard]] inline std::string concat(TYPE... item) +{ + std::string buf; + // Size to accommodate string representations of all inputs, minus their + // terminating zero bytes. + buf.resize(size_buffer(item...)); + + char *const data{buf.data()}; + char *here = data; + char *end = data + std::size(buf); + (render_item(item, here, end), ...); + + buf.resize(static_cast(here - data)); + return buf; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/conversions.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/conversions.hxx new file mode 100644 index 0000000..1df4fde --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/conversions.hxx @@ -0,0 +1,1188 @@ +#include +#include +#include +#include +#include +#include + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include +#include +#include + +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" + + +/* Internal helpers for string conversion, and conversion implementations. + * + * Do not include this header directly. The libpqxx headers do it for you. + */ +namespace pqxx::internal +{ +/// Convert a number in [0, 9] to its ASCII digit. +inline constexpr char number_to_digit(int i) noexcept +{ + return static_cast(i + '0'); +} + + +/// Compute numeric value of given textual digit (assuming that it is a digit). +constexpr int digit_to_number(char c) noexcept +{ + return c - '0'; +} + + +/// Summarize buffer overrun. +/** Don't worry about the exact parameter types: the sizes will be reasonably + * small, and nonnegative. + */ +std::string PQXX_LIBEXPORT +state_buffer_overrun(int have_bytes, int need_bytes); + + +template +inline std::string state_buffer_overrun(HAVE have_bytes, NEED need_bytes) +{ + return state_buffer_overrun( + static_cast(have_bytes), static_cast(need_bytes)); +} + + +/// Throw exception for attempt to convert null to given type. +[[noreturn]] PQXX_LIBEXPORT void +throw_null_conversion(std::string const &type); + + +/// Deliberately nonfunctional conversion traits for `char` types. +/** There are no string conversions for `char` and its signed and unsigned + * variants. Such a conversion would be dangerously ambiguous: should we treat + * it as text, or as a small integer? It'd be an open invitation for bugs. + * + * But the error message when you get this wrong is very cryptic. So, we + * derive dummy @ref string_traits implementations from this dummy type, and + * ensure that the compiler disallows their use. The compiler error message + * will at least contain a hint of the root of the problem. + */ +template struct disallowed_ambiguous_char_conversion +{ + static char *into_buf(char *, char *, CHAR_TYPE) = delete; + static constexpr zview + to_buf(char *, char *, CHAR_TYPE const &) noexcept = delete; + + static constexpr std::size_t + size_buffer(CHAR_TYPE const &) noexcept = delete; + static CHAR_TYPE from_string(std::string_view) = delete; +}; + + +template PQXX_LIBEXPORT extern std::string to_string_float(T); + + +/// Generic implementation for into_buf, on top of to_buf. +template +inline char *generic_into_buf(char *begin, char *end, T const &value) +{ + zview const text{string_traits::to_buf(begin, end, value)}; + auto const space{end - begin}; + // Include the trailing zero. + auto const len = std::size(text) + 1; + if (internal::cmp_greater(len, space)) + throw conversion_overrun{ + "Not enough buffer space to insert " + type_name + ". " + + state_buffer_overrun(space, len)}; + std::memmove(begin, text.data(), len); + return begin + len; +} + + +/// String traits for builtin integral types (though not bool). +template struct integral_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + static constexpr std::size_t size_buffer(T const &) noexcept + { + /** Includes a sign if needed; the number of base-10 digits which the type + * can reliably represent; the one extra base-10 digit which the type can + * only partially represent; and the terminating zero. + */ + return std::is_signed_v + std::numeric_limits::digits10 + 1 + 1; + } +}; + + +/// String traits for builtin floating-point types. +template struct float_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + // Return a nonnegative integral value's number of decimal digits. + static constexpr std::size_t digits10(std::size_t value) noexcept + { + if (value < 10) + return 1; + else + return 1 + digits10(value / 10); + } + + static constexpr std::size_t size_buffer(T const &) noexcept + { + using lims = std::numeric_limits; + // See #328 for a detailed discussion on the maximum number of digits. + // + // In a nutshell: for the big cases, the scientific notation is always + // the shortest one, and therefore the one that to_chars will pick. + // + // So... How long can the scientific notation get? 1 (for sign) + 1 (for + // decimal point) + 1 (for 'e') + 1 (for exponent sign) + max_digits10 + + // max number of digits in the exponent + 1 (terminating zero). + // + // What's the max number of digits in the exponent? It's the max number of + // digits out of the most negative exponent and the most positive one. + // + // The longest positive exponent is easy: 1 + ceil(log10(max_exponent10)). + // (The extra 1 is because 10^n takes up 1 + n digits, not n.) + // + // The longest negative exponent is a bit harder: min_exponent10 gives us + // the smallest power of 10 which a normalised version of T can represent. + // But the smallest denormalised power of 10 that T can represent is + // another max_digits10 powers of 10 below that. + // needs a minus sign. + // + // All this stuff messes with my head a bit because it's on the order of + // log10(log10(n)). It's easy to get the number of logs wrong. + auto const max_pos_exp{digits10(lims::max_exponent10)}; + // Really want std::abs(lims::min_exponent10), but MSVC 2017 apparently has + // problems with std::abs. So we use -lims::min_exponent10 instead. + auto const max_neg_exp{ + digits10(lims::max_digits10 - lims::min_exponent10)}; + return 1 + // Sign. + 1 + // Decimal point. + std::numeric_limits::max_digits10 + // Mantissa digits. + 1 + // Exponent "e". + 1 + // Exponent sign. + // Spell this weirdly to stop Windows compilers from reading this as + // a call to their "max" macro when NOMINMAX is not defined. + (std::max)(max_pos_exp, max_neg_exp) + // Exponent digits. + 1; // Terminating zero. + } +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// The built-in arithmetic types do not have inherent null values. +template +struct nullness>> : no_null +{}; + + +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct string_traits +{ + static PQXX_LIBEXPORT bool from_string(std::string_view text); + + static constexpr zview to_buf(char *, char *, bool const &value) noexcept + { + return value ? "true"_zv : "false"_zv; + } + + static char *into_buf(char *begin, char *end, bool const &value) + { + return pqxx::internal::generic_into_buf(begin, end, value); + } + + static constexpr std::size_t size_buffer(bool const &) noexcept { return 6; } +}; + + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + /// Technically, you could have an optional of an always-null type. + static constexpr bool always_null = nullness::always_null; + static constexpr bool is_null(std::optional const &v) noexcept + { + return ((not v.has_value()) or pqxx::is_null(*v)); + } + static constexpr std::optional null() { return {}; } +}; + + +template +inline constexpr format param_format(std::optional const &value) +{ + return param_format(*value); +} + + +template struct string_traits> +{ + static char *into_buf(char *begin, char *end, std::optional const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview to_buf(char *begin, char *end, std::optional const &value) + { + if (value.has_value()) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::optional from_string(std::string_view text) + { + return std::optional{ + std::in_place, string_traits::from_string(text)}; + } + + static std::size_t size_buffer(std::optional const &value) noexcept + { + return pqxx::size_buffer(value.value()); + } +}; + + +template +inline constexpr bool is_unquoted_safe>{is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = (nullness::has_null or ...); + static constexpr bool always_null = (nullness::always_null and ...); + static constexpr bool is_null(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { + return nullness>::is_null(i); + }, + value); + } + + // We don't support `null()` for `std::variant`. + /** It would be technically possible to have a `null` in the case where just + * one of the types has a null, but it gets complicated and arbitrary. + */ + static constexpr std::variant null() = delete; +}; + + +template struct string_traits> +{ + static char * + into_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::into_buf(begin, end, i); + }, + value); + } + static zview to_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::to_buf(begin, end, i); + }, + value); + } + static std::size_t size_buffer(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { return pqxx::size_buffer(i); }, value); + } + + /** There's no from_string for std::variant. We could have one with a rule + * like "pick the first type which fits the value," but we'd have to look + * into how natural that API feels to users. + */ + static std::variant from_string(std::string_view) = delete; +}; + + +template +inline constexpr format param_format(std::variant const &value) +{ + return std::visit([](auto &v) { return param_format(v); }, value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + (is_unquoted_safe and ...)}; + + +template inline T from_string(std::stringstream const &text) +{ + return from_string(text.str()); +} + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullptr_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullptr_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullptr_t = nullptr) noexcept + { + return 0; + } + static std::nullptr_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullopt_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullopt_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullopt_t) noexcept + { + return 0; + } + static std::nullopt_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::monostate) = delete; + + static constexpr zview + to_buf(char *, char *, std::monostate const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::monostate) noexcept + { + return 0; + } + static std::monostate from_string(std::string_view) = delete; +}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() noexcept { return nullptr; } +}; + + +/// String traits for C-style string ("pointer to char const"). +template<> struct string_traits +{ + static char const *from_string(std::string_view text) { return text.data(); } + + static zview to_buf(char *begin, char *end, char const *const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, char const *const &value) + { + auto const space{end - begin}; + // Count the trailing zero, even though std::strlen() and friends don't. + auto const len{std::strlen(value) + 1}; + if (space < ptrdiff_t(len)) + throw conversion_overrun{ + "Could not copy string: buffer too small. " + + pqxx::internal::state_buffer_overrun(space, len)}; + std::memmove(begin, value, len); + return begin + len; + } + + static std::size_t size_buffer(char const *const &value) noexcept + { + return std::strlen(value) + 1; + } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() { return nullptr; } +}; + + +/// String traits for non-const C-style string ("pointer to char"). +template<> struct string_traits +{ + static char *into_buf(char *begin, char *end, char *const &value) + { + return string_traits::into_buf(begin, end, value); + } + static zview to_buf(char *begin, char *end, char *const &value) + { + return string_traits::to_buf(begin, end, value); + } + static std::size_t size_buffer(char *const &value) noexcept + { + return string_traits::size_buffer(value); + } + + /// Don't allow conversion to this type since it breaks const-safety. + static char *from_string(std::string_view) = delete; +}; + + +template struct nullness : no_null +{}; + + +/// String traits for C-style string constant ("array of char"). +/** @warning This assumes that every array-of-char is a C-style string literal. + * So, it must include a trailing zero. and it must have static duration. + */ +template struct string_traits +{ + static constexpr zview + to_buf(char *, char *, char const (&value)[N]) noexcept + { + return zview{value, N - 1}; + } + + static char *into_buf(char *begin, char *end, char const (&value)[N]) + { + if (internal::cmp_less(end - begin, size_buffer(value))) + throw conversion_overrun{ + "Could not convert char[] to string: too long for buffer."}; + std::memcpy(begin, value, N); + return begin + N; + } + static constexpr std::size_t size_buffer(char const (&)[N]) noexcept + { + return N; + } + + /// Don't allow conversion to this type. + static void from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::string from_string(std::string_view text) + { + return std::string{text}; + } + + static char *into_buf(char *begin, char *end, std::string const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not convert string to string: too long for buffer."}; + // Include the trailing zero. + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + static zview to_buf(char *begin, char *end, std::string const &value) + { + return generic_to_buf(begin, end, value); + } + + static std::size_t size_buffer(std::string const &value) noexcept + { + return std::size(value) + 1; + } +}; + + +/// There's no real null for `std::string_view`. +/** I'm not sure how clear-cut this is: a `string_view` may have a null + * data pointer, which is analogous to a null `char` pointer. + */ +template<> struct nullness : no_null +{}; + + +/// String traits for `string_view`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, std::string_view const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not store string_view: too long for buffer."}; + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static std::string_view from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +/// String traits for `zview`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, zview const &value) + { + auto const size{std::size(value)}; + if (internal::cmp_less_equal(end - begin, std::size(value))) + throw conversion_overrun{"Not enough buffer space to store this zview."}; + value.copy(begin, size); + begin[size] = '\0'; + return begin + size + 1; + } + + static std::string_view to_buf(char *begin, char *end, zview const &value) + { + return {into_buf(begin, end, value), std::size(value)}; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static zview from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::size_t size_buffer(std::stringstream const &) = delete; + + static std::stringstream from_string(std::string_view text) + { + std::stringstream stream; + stream.write(text.data(), std::streamsize(std::size(text))); + return stream; + } + + static char *into_buf(char *, char *, std::stringstream const &) = delete; + static std::string_view + to_buf(char *, char *, std::stringstream const &) = delete; +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullptr_t const &) noexcept + { + return true; + } + static constexpr std::nullptr_t null() noexcept { return nullptr; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullopt_t const &) noexcept + { + return true; + } + static constexpr std::nullopt_t null() noexcept { return std::nullopt; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::monostate const &) noexcept + { + return true; + } + static constexpr std::monostate null() noexcept { return {}; } +}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::unique_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::unique_ptr null() { return {}; } +}; + + +template +struct string_traits> +{ + static std::unique_ptr from_string(std::string_view text) + { + return std::make_unique(string_traits::from_string(text)); + } + + static char * + into_buf(char *begin, char *end, std::unique_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview + to_buf(char *begin, char *end, std::unique_ptr const &value) + { + if (value) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::size_t + size_buffer(std::unique_ptr const &value) noexcept + { + return pqxx::size_buffer(*value.get()); + } +}; + + +template +inline format param_format(std::unique_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::shared_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::shared_ptr null() { return {}; } +}; + + +template struct string_traits> +{ + static std::shared_ptr from_string(std::string_view text) + { + return std::make_shared(string_traits::from_string(text)); + } + + static zview to_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::to_buf(begin, end, *value); + } + static char * + into_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + static std::size_t size_buffer(std::shared_ptr const &value) noexcept + { + return pqxx::size_buffer(*value); + } +}; + + +template format param_format(std::shared_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template<> +struct nullness> + : no_null> +{}; + + +#if defined(PQXX_HAVE_CONCEPTS) +template struct nullness : no_null +{}; + + +template inline constexpr format param_format(DATA const &) +{ + return format::binary; +} + + +template struct string_traits +{ + static std::size_t size_buffer(DATA const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, DATA const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, DATA const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static DATA from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; +#endif // PQXX_HAVE_CONCEPTS + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview + to_buf(char *begin, char *end, std::basic_string const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::basic_string const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static std::basic_string from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; + + +template<> +inline constexpr format param_format(std::basic_string const &) +{ + return format::binary; +} + + +template<> +struct nullness> + : no_null> +{}; + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string_view const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf( + char *begin, char *end, std::basic_string_view const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf( + char *begin, char *end, std::basic_string_view const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + // There's no from_string, because there's nobody to hold the data. +}; + +template<> +inline constexpr format param_format(std::basic_string_view const &) +{ + return format::binary; +} +} // namespace pqxx + + +namespace pqxx::internal +{ +/// String traits for SQL arrays. +template struct array_string_traits +{ +private: + using elt_type = strip_t>; + using elt_traits = string_traits; + static constexpr zview s_null{"NULL"}; + +public: + static zview to_buf(char *begin, char *end, Container const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, Container const &value) + { + std::size_t const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to convert array to string."}; + + char *here = begin; + *here++ = '{'; + + bool nonempty{false}; + for (auto const &elt : value) + { + if (is_null(elt)) + { + s_null.copy(here, std::size(s_null)); + here += std::size(s_null); + } + else if constexpr (is_sql_array) + { + // Render nested array in-place. Then erase the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else if constexpr (is_unquoted_safe) + { + // No need to quote or escape. Just convert the value straight into + // its place in the array, and "backspace" the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else + { + *here++ = '"'; + + // Use the tail end of the destination buffer as an intermediate + // buffer. + auto const elt_budget{pqxx::size_buffer(elt)}; + for (char const c : elt_traits::to_buf(end - elt_budget, end, elt)) + { + if (c == '\\' or c == '"') + *here++ = '\\'; + *here++ = c; + } + *here++ = '"'; + } + *here++ = array_separator; + nonempty = true; + } + + // Erase that last comma, if present. + if (nonempty) + here--; + + *here++ = '}'; + *here++ = '\0'; + + return here; + } + + static std::size_t size_buffer(Container const &value) noexcept + { + if constexpr (is_unquoted_safe) + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + return acc + + (pqxx::is_null(elt) ? + std::size(s_null) : + elt_traits::size_buffer(elt)) - + 1; + }); + else + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + // Opening and closing quotes, plus worst-case escaping, + // but don't count the trailing zeroes. + std::size_t const elt_size{ + pqxx::is_null(elt) ? std::size(s_null) : + elt_traits::size_buffer(elt) - 1}; + return acc + 2 * elt_size + 2; + }); + } + + // We don't yet support parsing of array types using from_string. Doing so + // would require a reference to the connection. +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::vector const &) +{ + return format::text; +} + + +/// A `std::vector` is a binary string. Other vectors are not. +template +inline constexpr format param_format(std::vector const &) +{ + return format::binary; +} + + +template inline constexpr bool is_sql_array>{true}; + + +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::array const &) +{ + return format::text; +} + + +/// An array of `std::byte` is a binary string. +template +inline constexpr format param_format(std::array const &) +{ + return format::binary; +} + + +template +inline constexpr bool is_sql_array>{true}; +} // namespace pqxx + + +namespace pqxx +{ +template inline std::string to_string(T const &value) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + std::string buf; + // We can't just reserve() space; modifying the terminating zero leads to + // undefined behaviour. + buf.resize(size_buffer(value)); + auto const data{buf.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(buf), value)}; + buf.resize(static_cast(end - data - 1)); + return buf; +} + + +template<> inline std::string to_string(float const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(long double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(std::stringstream const &value) +{ + return value.str(); +} + + +template inline void into_string(T const &value, std::string &out) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + // We can't just reserve() data; modifying the terminating zero leads to + // undefined behaviour. + out.resize(size_buffer(value) + 1); + auto const data{out.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(out), value)}; + out.resize(static_cast(end - data - 1)); +} +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encoding_group.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encoding_group.hxx new file mode 100644 index 0000000..e17736e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encoding_group.hxx @@ -0,0 +1,60 @@ +/** Enum type for supporting encodings in libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODING_GROUP +#define PQXX_H_ENCODING_GROUP + +#include + +namespace pqxx::internal +{ +// Types of encodings supported by PostgreSQL, see +// https://www.postgresql.org/docs/current/static/multibyte.html#CHARSET-TABLE +enum class encoding_group +{ + // Handles all single-byte fixed-width encodings + MONOBYTE, + + // Multibyte encodings. + // Many of these can embed ASCII-like bytes inside multibyte characters, + // notably Big5, SJIS, SHIFT_JIS_2004, GP18030, GBK, JOHAB, UHC. + BIG5, + EUC_CN, + // TODO: Merge EUC_JP and EUC_JIS_2004? + EUC_JP, + EUC_JIS_2004, + EUC_KR, + EUC_TW, + GB18030, + GBK, + JOHAB, + MULE_INTERNAL, + // TODO: Merge SJIS and SHIFT_JIS_2004? + SJIS, + SHIFT_JIS_2004, + UHC, + UTF8, +}; + + +// TODO:: Can we just use string_view now? +/// Function type: "find the end of the current glyph." +/** This type of function takes a text buffer, and a location in that buffer, + * and returns the location one byte past the end of the current glyph. + * + * The start offset marks the beginning of the current glyph. It must fall + * within the buffer. + * + * There are multiple different glyph scanner implementations, for different + * kinds of encodings. + */ +using glyph_scanner_func = + std::size_t(char const buffer[], std::size_t buffer_len, std::size_t start); +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encodings.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encodings.hxx new file mode 100644 index 0000000..ba7fecc --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/encodings.hxx @@ -0,0 +1,90 @@ +/** Internal string encodings support for libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODINGS +#define PQXX_H_ENCODINGS + +#include "pqxx/internal/encoding_group.hxx" + +#include +#include + + +namespace pqxx::internal +{ +char const *name_encoding(int encoding_id); + +/// Convert libpq encoding enum or encoding name to its libpqxx group. +encoding_group enc_group(int /* libpq encoding ID */); +encoding_group enc_group(std::string_view); + + +/// Look up the glyph scanner function for a given encoding group. +/** To identify the glyph boundaries in a buffer, call this to obtain the + * scanner function appropriate for the buffer's encoding. Then, repeatedly + * call the scanner function to find the glyphs. + */ +PQXX_LIBEXPORT glyph_scanner_func *get_glyph_scanner(encoding_group); + + +// TODO: For ASCII search, treat UTF8/EUC_*/MULE_INTERNAL as MONOBYTE. + +/// Find any of the ASCII characters `NEEDLE` in `haystack`. +/** Scans through `haystack` until it finds a single-byte character that + * matches any value in `NEEDLE`. + * + * If it finds one, returns its offset. If not, returns the end of the + * haystack. + */ +template +inline std::size_t find_char( + glyph_scanner_func *scanner, std::string_view haystack, + std::size_t here = 0u) +{ + auto const sz{std::size(haystack)}; + auto const data{std::data(haystack)}; + while (here < sz) + { + auto next{scanner(data, sz, here)}; + // (For some reason gcc had a problem with a right-fold here. But clang + // was fine.) + if ((... or (data[here] == NEEDLE))) + { + // Also check against a multibyte character starting with a bytes which + // just happens to match one of the ASCII bytes we're looking for. It'd + // be cleaner to check that first, but either works. So, let's apply the + // most selective filter first and skip this check in almost all cases. + if (next == here + 1) + return here; + } + + // Nope, no hit. Move on. + here = next; + } + return sz; +} + + +/// Iterate over the glyphs in a buffer. +/** Scans the glyphs in the buffer, and for each, passes its begin and its + * one-past-end pointers to `callback`. + */ +template +inline void for_glyphs( + encoding_group enc, CALLABLE callback, char const buffer[], + std::size_t buffer_len, std::size_t start = 0) +{ + auto const scan{get_glyph_scanner(enc)}; + for (std::size_t here = start, next; here < buffer_len; here = next) + { + next = scan(buffer, buffer_len, here); + callback(buffer + here, buffer + next); + } +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-errorhandler.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-errorhandler.hxx new file mode 100644 index 0000000..ffc12a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-errorhandler.hxx @@ -0,0 +1,26 @@ +#include + +namespace pqxx +{ +class connection; +class errorhandler; +} // namespace pqxx + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_errorhandler : callgate +{ + friend class pqxx::errorhandler; + + connection_errorhandler(reference x) : super(x) {} + + void register_errorhandler(errorhandler *h) + { + home().register_errorhandler(h); + } + void unregister_errorhandler(errorhandler *h) + { + home().unregister_errorhandler(h); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-largeobject.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-largeobject.hxx new file mode 100644 index 0000000..49feaf9 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-largeobject.hxx @@ -0,0 +1,35 @@ +#include + +#include +#include + +namespace pqxx +{ +class blob; +class largeobject; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + connection_largeobject(reference x) : super(x) {} + + pq::PGconn *raw_connection() const { return home().raw_connection(); } +}; + + +class PQXX_PRIVATE const_connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + const_connection_largeobject(reference x) : super(x) {} + + std::string error_message() const { return home().err_msg(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-notification_receiver.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-notification_receiver.hxx new file mode 100644 index 0000000..0bcb2db --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-notification_receiver.hxx @@ -0,0 +1,29 @@ +#include + +#include "pqxx/connection.hxx" + + +namespace pqxx +{ +class notification_receiver; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_notification_receiver : callgate +{ + friend class pqxx::notification_receiver; + + connection_notification_receiver(reference x) : super(x) {} + + void add_receiver(notification_receiver *receiver) + { + home().add_receiver(receiver); + } + void remove_receiver(notification_receiver *receiver) noexcept + { + home().remove_receiver(receiver); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-pipeline.hxx new file mode 100644 index 0000000..c6ae6e1 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-pipeline.hxx @@ -0,0 +1,23 @@ +#include "pqxx/internal/libpq-forward.hxx" +#include + +#include "pqxx/pipeline.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_pipeline : callgate +{ + friend class pqxx::pipeline; + + connection_pipeline(reference x) : super(x) {} + + void start_exec(char const query[]) { home().start_exec(query); } + pqxx::internal::pq::PGresult *get_result() { return home().get_result(); } + void cancel_query() { home().cancel_query(); } + + bool consume_input() noexcept { return home().consume_input(); } + bool is_busy() const noexcept { return home().is_busy(); } + + int encoding_id() { return home().encoding_id(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-sql_cursor.hxx new file mode 100644 index 0000000..51a8898 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-sql_cursor.hxx @@ -0,0 +1,19 @@ +#include + +namespace pqxx::internal +{ +class sql_cursor; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + connection_sql_cursor(reference x) : super(x) {} + + result exec(char const query[]) { return home().exec(query); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_from.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_from.hxx new file mode 100644 index 0000000..8961e71 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_from.hxx @@ -0,0 +1,15 @@ +#include + +#include "pqxx/connection.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_from : callgate +{ + friend class pqxx::stream_from; + + connection_stream_from(reference x) : super{x} {} + + auto read_copy_line() { return home().read_copy_line(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_to.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_to.hxx new file mode 100644 index 0000000..a6974fb --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-stream_to.hxx @@ -0,0 +1,17 @@ +#include + +#include "pqxx/stream_to.hxx" + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_to : callgate +{ + friend class pqxx::stream_to; + + connection_stream_to(reference x) : super(x) {} + + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-transaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-transaction.hxx new file mode 100644 index 0000000..74d6592 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/connection-transaction.hxx @@ -0,0 +1,44 @@ +#include + +namespace pqxx +{ +class connection; +} + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_transaction : callgate +{ + friend class pqxx::transaction_base; + + connection_transaction(reference x) : super(x) {} + + template result exec(STRING query, std::string_view desc) + { + return home().exec(query, desc); + } + + void register_transaction(transaction_base *t) + { + home().register_transaction(t); + } + void unregister_transaction(transaction_base *t) noexcept + { + home().unregister_transaction(t); + } + + auto read_copy_line() { return home().read_copy_line(); } + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } + + result exec_prepared(zview statement, internal::c_params const &args) + { + return home().exec_prepared(statement, args); + } + + result exec_params(zview query, internal::c_params const &args) + { + return home().exec_params(query, args); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/errorhandler-connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/errorhandler-connection.hxx new file mode 100644 index 0000000..5560ced --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/errorhandler-connection.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE errorhandler_connection : callgate +{ + friend class pqxx::connection; + + errorhandler_connection(reference x) : super(x) {} + + void unregister() noexcept { home().unregister(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx new file mode 100644 index 0000000..296d221 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursor_iterator_icursorstream : callgate +{ + friend class pqxx::icursorstream; + + icursor_iterator_icursorstream(reference x) : super(x) {} + + icursor_iterator::difference_type pos() const noexcept + { + return home().pos(); + } + + icursor_iterator *get_prev() { return home().m_prev; } + void set_prev(icursor_iterator *i) { home().m_prev = i; } + + icursor_iterator *get_next() { return home().m_next; } + void set_next(icursor_iterator *i) { home().m_next = i; } + + void fill(result const &r) { home().fill(r); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx new file mode 100644 index 0000000..56056d5 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx @@ -0,0 +1,32 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursorstream_icursor_iterator : callgate +{ + friend class pqxx::icursor_iterator; + + icursorstream_icursor_iterator(reference x) : super(x) {} + + void insert_iterator(icursor_iterator *i) noexcept + { + home().insert_iterator(i); + } + + void remove_iterator(icursor_iterator *i) const noexcept + { + home().remove_iterator(i); + } + + icursorstream::size_type forward() { return home().forward(); } + icursorstream::size_type forward(icursorstream::size_type n) + { + return home().forward(n); + } + + void service_iterators(icursorstream::difference_type p) + { + home().service_iterators(p); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-connection.hxx new file mode 100644 index 0000000..daa0808 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-connection.hxx @@ -0,0 +1,14 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_connection : callgate +{ + friend class pqxx::connection; + + result_connection(reference x) : super(x) {} + + operator bool() const { return bool(home()); } + bool operator!() const { return not home(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-creation.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-creation.hxx new file mode 100644 index 0000000..3d9205f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-creation.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_creation : callgate +{ + friend class pqxx::connection; + friend class pqxx::pipeline; + + result_creation(reference x) : super(x) {} + + static result create( + internal::pq::PGresult *rhs, std::shared_ptr const &query, + encoding_group enc) + { + return result(rhs, query, enc); + } + + void check_status(std::string_view desc = ""sv) const + { + return home().check_status(desc); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-pipeline.hxx new file mode 100644 index 0000000..3ebe436 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-pipeline.hxx @@ -0,0 +1,16 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_pipeline : callgate +{ + friend class pqxx::pipeline; + + result_pipeline(reference x) : super(x) {} + + std::shared_ptr query_ptr() const + { + return home().query_ptr(); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-sql_cursor.hxx new file mode 100644 index 0000000..78b4507 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/result-sql_cursor.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + result_sql_cursor(reference x) : super(x) {} + + char const *cmd_status() const noexcept { return home().cmd_status(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-sql_cursor.hxx new file mode 100644 index 0000000..4ed78dc --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-sql_cursor.hxx @@ -0,0 +1,10 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + transaction_sql_cursor(reference x) : super(x) {} +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-transaction_focus.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-transaction_focus.hxx new file mode 100644 index 0000000..ca7939a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/gates/transaction-transaction_focus.hxx @@ -0,0 +1,30 @@ +#include + +#include "pqxx/transaction_base.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_transaction_focus : callgate +{ + friend class pqxx::transaction_focus; + + transaction_transaction_focus(reference x) : super(x) {} + + void register_focus(transaction_focus *focus) + { + home().register_focus(focus); + } + void unregister_focus(transaction_focus *focus) noexcept + { + home().unregister_focus(focus); + } + void register_pending_error(zview error) + { + home().register_pending_error(error); + } + void register_pending_error(std::string &&error) + { + home().register_pending_error(std::move(error)); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-post.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-post.hxx new file mode 100644 index 0000000..ff6bf89 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-post.hxx @@ -0,0 +1,22 @@ +/* Compiler deficiency workarounds for compiling libpqxx headers. + * + * To be included at the end of each libpqxx header, in order to restore the + * client program's settings. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +// NO GUARDS HERE! This code should be executed every time! + +#if defined(_MSC_VER) +# pragma warning(pop) // Restore compiler's warning state +#endif + +#if !defined(PQXX_HEADER_PRE) +# error "Include pqxx/internal/header-post.hxx AFTER its 'pre' counterpart." +#endif + +#undef PQXX_HEADER_PRE diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-pre.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-pre.hxx new file mode 100644 index 0000000..abc1a39 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/header-pre.hxx @@ -0,0 +1,169 @@ +/* Compiler settings for compiling libpqxx headers, and workarounds for all. + * + * Include this before including any other libpqxx headers from within libpqxx. + * And to balance it out, also include header-post.hxx at the end of the batch + * of headers. + * + * The public libpqxx headers (e.g. ``) include this already; + * there's no need to do this from within an application. + * + * Include this file at the highest aggregation level possible to avoid nesting + * and to keep things simple. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ + +// NO GUARD HERE! This part should be included every time this file is. +#if defined(_MSC_VER) + +// Save compiler's warning state, and set warning level 4 for maximum +// sensitivity to warnings. +# pragma warning(push, 4) + +// Visual C++ generates some entirely unreasonable warnings. Disable them. +// Copy constructor could not be generated. +# pragma warning(disable : 4511) +// Assignment operator could not be generated. +# pragma warning(disable : 4512) +// Can't expose outside classes without exporting them. Except the MSVC docs +// say please ignore the warning if it's a standard library class. +# pragma warning(disable : 4251) +// Can't derive library classes from outside classes without exporting them. +// Except the MSVC docs say please ignore the warning if the parent class is +// in the standard library. +# pragma warning(disable : 4275) +// Can't inherit from non-exported class. +# pragma warning(disable : 4275) + +#endif // _MSC_VER + + +#if defined(PQXX_HEADER_PRE) +# error "Avoid nesting #include of pqxx/internal/header-pre.hxx." +#endif + +#define PQXX_HEADER_PRE + + +// Workarounds & definitions that need to be included even in library's headers +#include "pqxx/config-public-compiler.h" + +// Enable ISO-646 alternative operaotr representations: "and" instead of "&&" +// etc. on older compilers. C++20 removes this header. +#if __has_include() +# include +#endif + + +#if defined(PQXX_HAVE_GCC_PURE) +/// Declare function "pure": no side effects, only reads globals and its args. +# define PQXX_PURE __attribute__((pure)) +#else +# define PQXX_PURE /* pure */ +#endif + + +#if defined(__GNUC__) +/// Tell the compiler to optimise a function for size, not speed. +# define PQXX_COLD __attribute__((cold)) +#else +# define PQXX_COLD /* cold */ +#endif + + +// Workarounds for Windows +#ifdef _WIN32 + +/* For now, export DLL symbols if _DLL is defined. This is done automatically + * by the compiler when linking to the dynamic version of the runtime library, + * according to "gzh" + */ +# if defined(PQXX_SHARED) && !defined(PQXX_LIBEXPORT) +# define PQXX_LIBEXPORT __declspec(dllimport) +# endif // PQXX_SHARED && !PQXX_LIBEXPORT + + +// Workarounds for Microsoft Visual C++ +# ifdef _MSC_VER + +// Suppress vtables on abstract classes. +# define PQXX_NOVTABLE __declspec(novtable) + +// Automatically link with the appropriate libpq (static or dynamic, debug or +// release). The default is to use the release DLL. Define PQXX_PQ_STATIC to +// link to a static version of libpq, and _DEBUG to link to a debug version. +// The two may be combined. +# if defined(PQXX_AUTOLINK) +# if defined(PQXX_PQ_STATIC) +# ifdef _DEBUG +# pragma comment(lib, "libpqd") +# else +# pragma comment(lib, "libpq") +# endif +# else +# ifdef _DEBUG +# pragma comment(lib, "libpqddll") +# else +# pragma comment(lib, "libpqdll") +# endif +# endif +# endif + +// If we're not compiling libpqxx itself, automatically link with the +// appropriate libpqxx library. To link with the libpqxx DLL, define +// PQXX_SHARED; the default is to link with the static library. A static link +// is the recommended practice. +// +// The preprocessor macro PQXX_INTERNAL is used to detect whether we +// are compiling the libpqxx library itself. When you compile the library +// yourself using your own project file, make sure to include this macro. +# if defined(PQXX_AUTOLINK) && !defined(PQXX_INTERNAL) +# ifdef PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxxD") +# else +# pragma comment(lib, "libpqxx") +# endif +# else // !PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxx_staticD") +# else +# pragma comment(lib, "libpqxx_static") +# endif +# endif +# endif + +# endif // _MSC_VER + +#elif defined(PQXX_HAVE_GCC_VISIBILITY) // !_WIN32 + +# define PQXX_LIBEXPORT __attribute__((visibility("default"))) +# define PQXX_PRIVATE __attribute__((visibility("hidden"))) + +#endif // PQXX_HAVE_GCC_VISIBILITY + + +#ifndef PQXX_LIBEXPORT +# define PQXX_LIBEXPORT /* libexport */ +#endif + +#ifndef PQXX_PRIVATE +# define PQXX_PRIVATE /* private */ +#endif + +#ifndef PQXX_NOVTABLE +# define PQXX_NOVTABLE /* novtable */ +#endif + +// C++20: Assume support. +#if defined(PQXX_HAVE_LIKELY) +# define PQXX_LIKELY [[likely]] +# define PQXX_UNLIKELY [[unlikely]] +#else +# define PQXX_LIKELY /* [[likely]] */ +# define PQXX_UNLIKELY /* [[unlikely]] */ +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-post.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-post.hxx new file mode 100644 index 0000000..cebcf05 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-post.hxx @@ -0,0 +1,15 @@ +/// End a code block started by "ignore-deprecated-pre.hxx". + +#if !defined(PQXX_IGNORING_DEPRECATED) +# error "Ended an 'ignore-deprecated' block while none was active." +#endif + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#undef PQXX_IGNORING_DEPRECATED diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-pre.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-pre.hxx new file mode 100644 index 0000000..8ac57af --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/ignore-deprecated-pre.hxx @@ -0,0 +1,28 @@ +/** Start a block of deprecated code which may call other deprecated code. + * + * Most compilers will emit warnings when deprecated code is invoked from + * non-deprecated code. But some compilers (notably gcc) will always emit the + * warning even when the calling code is also deprecated. + * + * This header starts a block where those warnings are suppressed. It can be + * included inside a code block. + * + * Always match the #include with a closing #include of + * "ignore-deprecated-post.hxx". To avoid mistakes, keep the enclosed area as + * small as possible. + */ +#if defined(PQXX_IGNORING_DEPRECATED) +# error "Started an 'ignore-deprecated' block inside another." +#endif + +#define PQXX_IGNORING_DEPRECATED + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4996) +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/libpq-forward.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/libpq-forward.hxx new file mode 100644 index 0000000..9e74f79 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/libpq-forward.hxx @@ -0,0 +1,31 @@ +/** Minimal forward declarations of libpq types needed in libpqxx headers. + * + * DO NOT INCLUDE THIS FILE when building client programs. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +extern "C" +{ + struct pg_conn; + struct pg_result; + struct pgNotify; +} + +/// Forward declarations of libpq types as needed in libpqxx headers. +namespace pqxx::internal::pq +{ +using PGconn = pg_conn; +using PGresult = pg_result; +using PGnotify = pgNotify; +using PQnoticeProcessor = void (*)(void *, char const *); +} // namespace pqxx::internal::pq + +namespace pqxx +{ +/// PostgreSQL database row identifier. +using oid = unsigned int; +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iter.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iter.hxx new file mode 100644 index 0000000..1fa1f7d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iter.hxx @@ -0,0 +1,124 @@ +/** Result loops. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITER +#define PQXX_H_RESULT_ITER + +#include + +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class result; +} // namespace pqxx + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Iterator for looped unpacking of a result. +template class result_iter +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + result_iter() = default; + + explicit result_iter(result const &home) : + m_home{&home}, m_size{std::size(home)} + { + if (not std::empty(home)) + read(); + } + result_iter(result_iter const &) = default; + + result_iter &operator++() + { + m_index++; + if (m_index >= m_size) + m_home = nullptr; + else + read(); + return *this; + } + + /// Comparison only works for comparing to end(). + bool operator==(result_iter const &rhs) const + { + return m_home == rhs.m_home; + } + bool operator!=(result_iter const &rhs) const { return not(*this == rhs); } + + value_type const &operator*() const { return m_value; } + +private: + void read() { (*m_home)[m_index].convert(m_value); } + + result const *m_home{nullptr}; + result::size_type m_index{0}; + result::size_type m_size; + value_type m_value; +}; + + +template class result_iteration +{ +public: + using iterator = result_iter; + explicit result_iteration(result const &home) : m_home{home} + { + constexpr auto tup_size{sizeof...(TYPE)}; + if (home.columns() != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", to_string(tup_size), + " field(s) from a result with ", to_string(home.columns()), + " column(s).")}; + } + iterator begin() const + { + if (std::size(m_home) == 0) + return end(); + else + return iterator{m_home}; + } + iterator end() const { return {}; } + +private: + pqxx::result const &m_home; +}; +} // namespace pqxx::internal + + +template inline auto pqxx::result::iter() const +{ + return pqxx::internal::result_iteration{*this}; +} + + +template +inline void pqxx::result::for_each(CALLABLE &&func) const +{ + using args_tuple = internal::args_t; + constexpr auto sz{std::tuple_size_v}; + static_assert( + sz > 0, + "Callback for for_each must take parameters, one for each column in the " + "result."); + + auto const cols{this->columns()}; + if (sz != cols) + throw usage_error{internal::concat( + "Callback to for_each takes ", sz, "parameter", (sz == 1) ? "" : "s", + ", but result set has ", cols, "field", (cols == 1) ? "" : "s", ".")}; + + using pass_tuple = pqxx::internal::strip_types_t; + for (auto const r : *this) std::apply(func, r.as_tuple()); +} +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iterator.hxx new file mode 100644 index 0000000..3f27a1d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/result_iterator.hxx @@ -0,0 +1,389 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITERATOR +#define PQXX_H_RESULT_ITERATOR + +#include "pqxx/row.hxx" + + +/* Result iterator. + * + * Don't include this header from your own application; it is included for you + * by other libpqxx headers. + */ + +namespace pqxx +{ +/// Iterator for rows in a result. Use as result::const_iterator. +/** A result, once obtained, cannot be modified. Therefore there is no + * plain iterator type for result. However its const_iterator type can be + * used to inspect its rows without changing them. + */ +class PQXX_LIBEXPORT const_result_iterator : public row +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = row const; + using pointer = row const *; + using reference = row; + using size_type = result_size_type; + using difference_type = result_difference_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create an iterator, but in an unusable state. + const_result_iterator() noexcept = default; + /// Copy an iterator. + const_result_iterator(const_result_iterator const &) noexcept = default; + /// Move an iterator. + const_result_iterator(const_result_iterator &&) noexcept = default; + + /// Begin iterating a @ref row. + const_result_iterator(row const &t) noexcept : row{t} {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /** + * @name Dereferencing operators + * + * An iterator "points to" its own row, which is also itself. This makes it + * easy to address a @ref result as a two-dimensional container, without + * going through the intermediate step of dereferencing the iterator. It + * makes the interface similar to C pointer/array semantics. + * + * IIRC Alex Stepanov, the inventor of the STL, once remarked that having + * this as standard behaviour for pointers would be useful in some + * algorithms. So even if this makes me look foolish, I would seem to be in + * distinguished company. + */ + //@{ + /// Dereference the iterator. + [[nodiscard]] pointer operator->() const { return this; } + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Dereference the iterator. + [[nodiscard]] reference operator*() const { return *this; } +#include "pqxx/internal/ignore-deprecated-post.hxx" + //@} + + /** + * @name Field access + */ + //@{ + using row::back; + using row::front; + using row::operator[]; + using row::at; + using row::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_result_iterator &operator=(const_result_iterator const &rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(rhs); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator &operator=(const_result_iterator &&rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(std::move(rhs)); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator operator++(int); + const_result_iterator &operator++() + { + ++m_index; + return *this; + } + const_result_iterator operator--(int); + const_result_iterator &operator--() + { + --m_index; + return *this; + } + + const_result_iterator &operator+=(difference_type i) + { + m_index += i; + return *this; + } + const_result_iterator &operator-=(difference_type i) + { + m_index -= i; + return *this; + } + + /// Interchange two iterators in an exception-safe manner. + void swap(const_result_iterator &other) noexcept + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::swap(other); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool operator==(const_result_iterator const &i) const + { + return m_index == i.m_index; + } + [[nodiscard]] bool operator!=(const_result_iterator const &i) const + { + return m_index != i.m_index; + } + [[nodiscard]] bool operator<(const_result_iterator const &i) const + { + return m_index < i.m_index; + } + [[nodiscard]] bool operator<=(const_result_iterator const &i) const + { + return m_index <= i.m_index; + } + [[nodiscard]] bool operator>(const_result_iterator const &i) const + { + return m_index > i.m_index; + } + [[nodiscard]] bool operator>=(const_result_iterator const &i) const + { + return m_index >= i.m_index; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_result_iterator operator+(difference_type) const; + friend const_result_iterator + operator+(difference_type, const_result_iterator const &); + [[nodiscard]] inline const_result_iterator operator-(difference_type) const; + [[nodiscard]] inline difference_type + operator-(const_result_iterator const &) const; + //@} + +private: + friend class pqxx::result; + const_result_iterator(pqxx::result const *r, result_size_type i) noexcept : + row{*r, i, r->columns()} + {} +}; + + +/// Reverse iterator for result. Use as result::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_result_iterator + : private const_result_iterator +{ +public: + using super = const_result_iterator; + using iterator_type = const_result_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + /// Create an iterator, but in an unusable state. + const_reverse_result_iterator() = default; + /// Copy an iterator. + const_reverse_result_iterator(const_reverse_result_iterator const &rhs) = + default; + /// Copy a reverse iterator from a regular iterator. + explicit const_reverse_result_iterator(const_result_iterator const &rhs) : + const_result_iterator{rhs} + { + super::operator--(); + } + + /// Move a regular iterator into a reverse iterator. + explicit const_reverse_result_iterator(const_result_iterator const &&rhs) : + const_result_iterator{std::move(rhs)} + { + super::operator--(); + } + + /// Return the underlying "regular" iterator (as per standard library). + [[nodiscard]] PQXX_PURE const_result_iterator base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + /// Dereference iterator. + using const_result_iterator::operator->; + /// Dereference iterator. + using const_result_iterator::operator*; + //@} + + /** + * @name Field access + */ + //@{ + using const_result_iterator::back; + using const_result_iterator::front; + using const_result_iterator::operator[]; + using const_result_iterator::at; + using const_result_iterator::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_result_iterator & + operator=(const_reverse_result_iterator const &r) + { + iterator_type::operator=(r); + return *this; + } + const_reverse_result_iterator &operator=(const_reverse_result_iterator &&r) + { + iterator_type::operator=(std::move(r)); + return *this; + } + const_reverse_result_iterator &operator++() + { + iterator_type::operator--(); + return *this; + } + const_reverse_result_iterator operator++(int); + const_reverse_result_iterator &operator--() + { + iterator_type::operator++(); + return *this; + } + const_reverse_result_iterator operator--(int); + const_reverse_result_iterator &operator+=(difference_type i) + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_result_iterator &operator-=(difference_type i) + { + iterator_type::operator+=(i); + return *this; + } + + void swap(const_reverse_result_iterator &other) noexcept + { + const_result_iterator::swap(other); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_result_iterator + operator+(difference_type i) const + { + return const_reverse_result_iterator(base() - i); + } + [[nodiscard]] const_reverse_result_iterator operator-(difference_type i) + { + return const_reverse_result_iterator(base() + i); + } + [[nodiscard]] difference_type + operator-(const_reverse_result_iterator const &rhs) const + { + return rhs.const_result_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_result_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_result_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + + [[nodiscard]] bool operator<(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] bool operator<=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] bool operator>(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] bool operator>=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +inline const_result_iterator +const_result_iterator::operator+(result::difference_type o) const +{ + return {&m_result, size_type(result::difference_type(m_index) + o)}; +} + +inline const_result_iterator +operator+(result::difference_type o, const_result_iterator const &i) +{ + return i + o; +} + +inline const_result_iterator +const_result_iterator::operator-(result::difference_type o) const +{ + return {&m_result, result_size_type(result::difference_type(m_index) - o)}; +} + +inline result::difference_type +const_result_iterator::operator-(const const_result_iterator &i) const +{ + return result::difference_type(num() - i.num()); +} + +inline const_result_iterator result::end() const noexcept +{ + return {this, size()}; +} + + +inline const_result_iterator result::cend() const noexcept +{ + return end(); +} + + +inline const_reverse_result_iterator +operator+(result::difference_type n, const_reverse_result_iterator const &i) +{ + return const_reverse_result_iterator{i.base() - n}; +} + +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/sql_cursor.hxx new file mode 100644 index 0000000..a26d063 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/sql_cursor.hxx @@ -0,0 +1,118 @@ +/** Internal wrapper for SQL cursors. Supports higher-level cursor classes. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SQL_CURSOR +#define PQXX_H_SQL_CURSOR + +namespace pqxx::internal +{ +/// Cursor with SQL positioning semantics. +/** Thin wrapper around an SQL cursor, with SQL's ideas of positioning. + * + * SQL cursors have pre-increment/pre-decrement semantics, with on either end + * of the result set a special position that does not repesent a row. This + * class models SQL cursors for the purpose of implementing more C++-like + * semantics on top. + * + * Positions of actual rows are numbered starting at 1. Position 0 exists but + * does not refer to a row. There is a similar non-row position at the end of + * the result set. + * + * Don't use this at home. You deserve better. Use the stateles_cursor + * instead. + */ +class PQXX_LIBEXPORT sql_cursor : public cursor_base +{ +public: + sql_cursor( + transaction_base &t, std::string_view query, std::string_view cname, + cursor_base::access_policy ap, cursor_base::update_policy up, + cursor_base::ownership_policy op, bool hold); + + sql_cursor( + transaction_base &t, std::string_view cname, + cursor_base::ownership_policy op); + + ~sql_cursor() noexcept { close(); } + + result fetch(difference_type rows, difference_type &displacement); + result fetch(difference_type rows) + { + difference_type d = 0; + return fetch(rows, d); + } + difference_type move(difference_type rows, difference_type &displacement); + difference_type move(difference_type rows) + { + difference_type d = 0; + return move(rows, d); + } + + /// Current position, or -1 for unknown + /** + * The starting position, just before the first row, counts as position zero. + * + * Position may be unknown if (and only if) this cursor was adopted, and has + * never hit its starting position (position zero). + */ + difference_type pos() const noexcept { return m_pos; } + + /// End position, or -1 for unknown + /** + * Returns the final position, just after the last row in the result set. The + * starting position, just before the first row, counts as position zero. + * + * End position is unknown until it is encountered during use. + */ + difference_type endpos() const noexcept { return m_endpos; } + + /// Return zero-row result for this cursor. + result const &empty_result() const noexcept { return m_empty_result; } + + void close() noexcept; + +private: + difference_type adjust(difference_type hoped, difference_type actual); + static std::string stridestring(difference_type); + /// Initialize cached empty result. Call only at beginning or end! + void init_empty_result(transaction_base &); + + /// Connection in which this cursor lives. + connection &m_home; + + /// Zero-row result from this cursor (or plain empty one if cursor is + /// adopted) + result m_empty_result; + + result m_cached_current_row; + + /// Is this cursor adopted (as opposed to created by this cursor object)? + bool m_adopted; + + /// Will this cursor object destroy its SQL cursor when it dies? + cursor_base::ownership_policy m_ownership; + + /// At starting position (-1), somewhere in the middle (0), or past end (1) + int m_at_end; + + /// Position, or -1 for unknown + difference_type m_pos; + + /// End position, or -1 for unknown + difference_type m_endpos = -1; +}; + + +PQXX_LIBEXPORT result_size_type obtain_stateless_cursor_size(sql_cursor &); +PQXX_LIBEXPORT result stateless_cursor_retrieve( + sql_cursor &, result::difference_type size, + result::difference_type begin_pos, result::difference_type end_pos); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/statement_parameters.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/statement_parameters.hxx new file mode 100644 index 0000000..b078bf6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/statement_parameters.hxx @@ -0,0 +1,131 @@ +/** Common implementation for statement parameter lists. + * + * These are used for both prepared statements and parameterized statements. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STATEMENT_PARAMETER +#define PQXX_H_STATEMENT_PARAMETER + +#include +#include +#include +#include +#include + +#include "pqxx/binarystring.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/util.hxx" + + +namespace pqxx::internal +{ +template +constexpr inline auto const iterator_identity{ + [](decltype(*std::declval()) x) { return x; }}; + + +/// Marker type: pass a dynamically-determined number of statement parameters. +/** @deprecated Use @ref params instead. + * + * Normally when invoking a prepared or parameterised statement, the number + * of parameters is known at compile time. For instance, + * `t.exec_prepared("foo", 1, "x");` executes statement `foo` with two + * parameters, an `int` and a C string. + * + * But sometimes you may want to pass a number of parameters known only at run + * time. In those cases, a @ref dynamic_params encodes a dynamically + * determined number of parameters. You can mix these with regular, static + * parameter lists, and you can re-use them for multiple statement invocations. + * + * A dynamic_params object does not store copies of its parameters, so make + * sure they remain accessible until you've executed the statement. + * + * The ACCESSOR is an optional callable (such as a lambda). If you pass an + * accessor `a`, then each parameter `p` goes into your statement as `a(p)`. + */ +template)> +class dynamic_params +{ +public: + /// Wrap a sequence of pointers or iterators. + constexpr dynamic_params(IT begin, IT end) : + m_begin(begin), m_end(end), m_accessor(iterator_identity) + {} + + /// Wrap a sequence of pointers or iterators. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + constexpr dynamic_params(IT begin, IT end, ACCESSOR &acc) : + m_begin(begin), m_end(end), m_accessor(acc) + {} + + /// Wrap a container. + template + explicit constexpr dynamic_params(C &container) : + dynamic_params(std::begin(container), std::end(container)) + {} + + /// Wrap a container. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + template + explicit constexpr dynamic_params(C &container, ACCESSOR &acc) : + dynamic_params(std::begin(container), std::end(container), acc) + {} + + constexpr IT begin() const noexcept { return m_begin; } + constexpr IT end() const noexcept { return m_end; } + + constexpr auto access(decltype(*std::declval()) value) const + -> decltype(std::declval()(value)) + { + return m_accessor(value); + } + +private: + IT const m_begin, m_end; + ACCESSOR m_accessor = iterator_identity; +}; + + +/// Internal type: encode statement parameters. +/** Compiles arguments for prepared statements and parameterised queries into + * a format that can be passed into libpq. + * + * Objects of this type are meant to be short-lived: a `c_params` lives and + * dies entirely within the call to execute. So, for example, if you pass in a + * non-null pointer as a parameter, @ref params may simply use that pointer as + * a parameter value, without arranging longer-term storage for the data to + * which it points. All values referenced by parameters must remain "live" + * until the parameterised or prepared statement has been executed. + */ +struct PQXX_LIBEXPORT c_params +{ + c_params() = default; + /// Copying these objects is pointless and expensive. Don't do it. + c_params(c_params const &) = delete; + c_params(c_params &&) = default; + + /// Pre-allocate storage for `n` parameters. + void reserve(std::size_t n) &; + + /// As used by libpq: pointers to parameter values. + std::vector values; + /// As used by libpq: lengths of non-null arguments, in bytes. + std::vector lengths; + /// As used by libpq: effectively boolean "is this a binary parameter?" + std::vector formats; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/stream_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/stream_iterator.hxx new file mode 100644 index 0000000..f240dcf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/stream_iterator.hxx @@ -0,0 +1,105 @@ +/** Stream iterators. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_ITERATOR +#define PQXX_H_STREAM_ITERATOR + +#include + +namespace pqxx +{ +class stream_from; +} + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Input iterator for stream_from. +/** Just barely enough to support range-based "for" loops. Don't assume that + * any of the usual behaviour works beyond that. + */ +template class stream_input_iterator +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + stream_input_iterator() = default; + + explicit stream_input_iterator(stream_from &home) : m_home(&home) + { + advance(); + } + stream_input_iterator(stream_input_iterator const &) = default; + + stream_input_iterator &operator++() + { + advance(); + return *this; + } + + value_type const &operator*() const { return m_value; } + + /// Comparison only works for comparing to end(). + bool operator==(stream_input_iterator const &rhs) const + { + return m_home == rhs.m_home; + } + /// Comparison only works for comparing to end(). + bool operator!=(stream_input_iterator const &rhs) const + { + return not(*this == rhs); + } + +private: + void advance() + { + if (m_home == nullptr) + throw usage_error{"Moving stream_from iterator beyond end()."}; + if (not((*m_home) >> m_value)) + m_home = nullptr; + } + + stream_from *m_home{nullptr}; + value_type m_value; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from. +template class stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit stream_input_iteration(stream_from &home) : m_home{home} {} + iterator begin() const { return iterator{m_home}; } + iterator end() const { return {}; } + +private: + stream_from &m_home; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from, deleting it once done. +template class owning_stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit owning_stream_input_iteration(std::unique_ptr &&home) : + m_home{std::move(home)} + {} + iterator begin() const { return iterator{*m_home.get()}; } + iterator end() const { return {}; } + +private: + std::unique_ptr m_home; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/wait.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/wait.hxx new file mode 100644 index 0000000..7a82e65 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/internal/wait.hxx @@ -0,0 +1,18 @@ +#if !defined(PQXX_WAIT_HXX) +# define PQXX_WAIT_HXX + +namespace pqxx::internal +{ +/// Wait. +/** This is normally `std::this_thread::sleep_for()`. But MinGW's `thread` + * header doesn't work, so we must be careful about including it. + */ +void PQXX_LIBEXPORT wait_for(unsigned int microseconds); + + +/// Wait for a socket to be ready for reading/writing, or timeout. +PQXX_LIBEXPORT void wait_fd( + int fd, bool for_read, bool for_write, unsigned seconds = 1, + unsigned microseconds = 0); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation new file mode 100644 index 0000000..1b80132 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation @@ -0,0 +1,8 @@ +/** Transaction isolation levels. + * + * Policies and traits describing SQL transaction isolation levels + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation.hxx new file mode 100644 index 0000000..0698c6a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/isolation.hxx @@ -0,0 +1,75 @@ +/* Definitions for transaction isolation levels, and such. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/isolation instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ISOLATION +#define PQXX_H_ISOLATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Should a transaction be read-only, or read-write? +/** No, this is not an isolation level. So it really doesn't belong here. + * But it's not really worth a separate header. + */ +enum class write_policy +{ + read_only, + read_write +}; + + +/// Transaction isolation levels. +/** These are as defined in the SQL standard. But there are a few notes + * specific to PostgreSQL. + * + * First, postgres does not support "read uncommitted." The lowest level you + * can get is "read committed," which is better. PostgreSQL is built on the + * MVCC paradigm, which guarantees "read committed" isolation without any + * additional performance overhead, so there was no point in providing the + * lower level. + * + * Second, "repeatable read" also makes more isolation guarantees than the + * standard requires. According to the standard, this level prevents "dirty + * reads" and "nonrepeatable reads," but not "phantom reads." In postgres, + * it actually prevents all three. + * + * Third, "serializable" is only properly supported starting at postgres 9.1. + * If you request "serializable" isolation on an older backend, you will get + * the same isolation as in "repeatable read." It's better than the + * "repeatable read" defined in the SQL standard, but not a complete + * implementation of the standard's "serializable" isolation level. + * + * In general, a lower isolation level will allow more surprising interactions + * between ongoing transactions, but improve performance. A higher level + * gives you more protection from subtle concurrency bugs, but sometimes it + * may not be possible to complete your transaction without avoiding paradoxes + * in the data. In that case a transaction may fail, and the application will + * have to re-do the whole thing based on the latest state of the database. + * (If you want to retry your code in that situation, have a look at the + * transactor framework.) + * + * Study the levels and design your application with the right level in mind. + */ +enum isolation_level +{ + // PostgreSQL only has the better isolation levels. + // read_uncommitted, + + read_committed, + repeatable_read, + serializable, +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject new file mode 100644 index 0000000..1f2f947 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject @@ -0,0 +1,8 @@ +/** Large Objects interface. + * + * Supports direct access to large objects, as well as through I/O streams + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject.hxx new file mode 100644 index 0000000..ebafc51 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/largeobject.hxx @@ -0,0 +1,735 @@ +/* Large Objects interface. Deprecated; use blob instead. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_LARGEOBJECT +#define PQXX_H_LARGEOBJECT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/// Identity of a large object. +/** @deprecated Use the @ref blob class instead. + * + * Encapsulates the identity of a large object. + * + * A largeobject must be accessed only from within a backend transaction, but + * the object's identity remains valid as long as the object exists. + */ +class PQXX_LIBEXPORT largeobject +{ +public: + using size_type = large_object_size_type; + + /// Refer to a nonexistent large object (similar to what a null pointer + /// does). + [[deprecated("Use blob instead.")]] largeobject() noexcept = default; + + /// Create new large object. + /** @param t Backend transaction in which the object is to be created. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(dbtransaction &t); + + /// Wrap object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param o Object identifier for the given object. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(oid o) noexcept : + m_id{o} + {} + + /// Import large object from a local file. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + */ + [[deprecated("Use blob instead.")]] largeobject( + dbtransaction &t, std::string_view file); + + /// Take identity of an opened large object. + /** Copy identity of already opened large object. Note that this may be done + * as an implicit conversion. + * @param o Already opened large object to copy identity from. + */ + [[deprecated("Use blob instead.")]] largeobject( + largeobjectaccess const &o) noexcept; + + /// Object identifier. + /** The number returned by this function identifies the large object in the + * database we're connected to (or oid_none is returned if we refer to the + * null object). + */ + [[nodiscard]] oid id() const noexcept { return m_id; } + + /** + * @name Identity comparisons + * + * These operators compare the object identifiers of large objects. This has + * nothing to do with the objects' actual contents; use them only for keeping + * track of containers of references to large objects and such. + */ + //@{ + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator==(largeobject const &other) const + { + return m_id == other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator!=(largeobject const &other) const + { + return m_id != other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<=(largeobject const &other) const + { + return m_id <= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>=(largeobject const &other) const + { + return m_id >= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<(largeobject const &other) const + { + return m_id < other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>(largeobject const &other) const + { + return m_id > other.m_id; + } + //@} + + /// Export large object's contents to a local file + /** Writes the data stored in the large object to the given file. + * @param t Transaction in which the object is to be accessed + * @param file A filename on the client's filesystem + */ + void to_file(dbtransaction &t, std::string_view file) const; + + /// Delete large object from database + /** Unlike its low-level equivalent cunlink, this will throw an exception if + * deletion fails. + * @param t Transaction in which the object is to be deleted + */ + void remove(dbtransaction &t) const; + +protected: + PQXX_PURE static internal::pq::PGconn * + raw_connection(dbtransaction const &T); + + PQXX_PRIVATE std::string reason(connection const &, int err) const; + +private: + oid m_id = oid_none; +}; + + +/// Accessor for large object's contents. +/** @deprecated Use the `blob` class instead. + */ +class PQXX_LIBEXPORT largeobjectaccess : private largeobject +{ +public: + using largeobject::size_type; + using off_type = size_type; + using pos_type = size_type; + + /// Open mode: `in`, `out` (can be combined using "bitwise or"). + /** According to the C++ standard, these should be in `std::ios_base`. We + * take them from derived class `std::ios` instead, which is easier on the + * eyes. + * + * Historical note: taking it from std::ios was originally a workaround for a + * problem with gcc 2.95. + */ + using openmode = std::ios::openmode; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + + /// Seek direction: `beg`, `cur`, `end`. + using seekdir = std::ios::seekdir; + + /// Create new large object and open it. + /** + * @param t Backend transaction in which the object is to be created. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] explicit largeobjectaccess( + dbtransaction &t, openmode mode = default_mode); + + /// Open large object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param t Transaction in which the object is to be accessed. + * @param o Object identifier for the given object. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, oid o, openmode mode = default_mode); + + /// Open given large object. + /** Open a large object with the given identity for reading and/or writing. + * @param t Transaction in which the object is to be accessed. + * @param o Identity for the large object to be accessed. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, largeobject o, openmode mode = default_mode); + + /// Import large object from a local file and open it. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + * @param mode Access mode, defaults to ios_base::in | ios_base::out. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, std::string_view file, openmode mode = default_mode); + + ~largeobjectaccess() noexcept { close(); } + + /// Object identifier. + /** The number returned by this function uniquely identifies the large object + * in the context of the database we're connected to. + */ + using largeobject::id; + + /// Export large object's contents to a local file. + /** Writes the data stored in the large object to the given file. + * @param file A filename on the client's filesystem. + */ + void to_file(std::string_view file) const + { + largeobject::to_file(m_trans, file); + } + + using largeobject::to_file; + + /** + * @name High-level access to object contents. + */ + //@{ + /// Write data to large object. + /** @warning The size of a write is currently limited to 2GB. + * + * @param buf Data to write. + * @param len Number of bytes from Buf to write. + */ + void write(char const buf[], std::size_t len); + + /// Write string to large object. + /** If not all bytes could be written, an exception is thrown. + * @param buf Data to write; no terminating zero is written. + */ + void write(std::string_view buf) { write(std::data(buf), std::size(buf)); } + + /// Read data from large object. + /** Throws an exception if an error occurs while reading. + * @param buf Location to store the read data in. + * @param len Number of bytes to try and read. + * @return Number of bytes read, which may be less than the number requested + * if the end of the large object is reached. + */ + size_type read(char buf[], std::size_t len); + + /// Seek in large object's data stream. + /** Throws an exception if an error occurs. + * @return The new position in the large object + */ + size_type seek(size_type dest, seekdir dir); + + /// Report current position in large object's data stream. + /** Throws an exception if an error occurs. + * @return The current position in the large object. + */ + [[nodiscard]] size_type tell() const; + //@} + + /** + * @name Low-level access to object contents. + * + * These functions provide a more "C-like" access interface, returning + * special values instead of throwing exceptions on error. These functions + * are generally best avoided in favour of the high-level access functions, + * which behave more like C++ functions should. + * + * Due to libpq's underlying API, some operations are limited to "int" + * sizes, typically 2 GB, even though a large object can grow much larger. + */ + //@{ + /// Seek in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param dest Offset to go to. + * @param dir Origin to which dest is relative: ios_base::beg (from beginning + * of the object), ios_base::cur (from current access position), or + * ios_base;:end (from end of object). + * @return New position in large object, or -1 if an error occurred. + */ + pos_type cseek(off_type dest, seekdir dir) noexcept; + + /// Write to large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Data to write. + * @param len Number of bytes to write. + * @return Number of bytes actually written, or -1 if an error occurred. + */ + off_type cwrite(char const buf[], std::size_t len) noexcept; + + /// Read from large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Area where incoming bytes should be stored. + * @param len Number of bytes to read. + * @return Number of bytes actually read, or -1 if an error occurred.. + */ + off_type cread(char buf[], std::size_t len) noexcept; + + /// Report current position in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @return Current position in large object, of -1 if an error occurred. + */ + [[nodiscard]] pos_type ctell() const noexcept; + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Issue message to transaction's notice processor. + void process_notice(zview) noexcept; + //@} + + using largeobject::remove; + + using largeobject::operator==; + using largeobject::operator!=; + using largeobject::operator<; + using largeobject::operator<=; + using largeobject::operator>; + using largeobject::operator>=; + + largeobjectaccess() = delete; + largeobjectaccess(largeobjectaccess const &) = delete; + largeobjectaccess operator=(largeobjectaccess const &) = delete; + +private: + PQXX_PRIVATE std::string reason(int err) const; + internal::pq::PGconn *raw_connection() const + { + return largeobject::raw_connection(m_trans); + } + + PQXX_PRIVATE void open(openmode mode); + void close() noexcept; + + dbtransaction &m_trans; + int m_fd = -1; +}; + + +/// Streambuf to use large objects in standard I/O streams. +/** @deprecated Access large objects directly using the @ref blob class. + * + * The standard streambuf classes provide uniform access to data storage such + * as files or string buffers, so they can be accessed using standard input or + * output streams. This streambuf implementation provided similar access to + * large objects, so they could be read and written using the same stream + * classes. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class largeobject_streambuf : public std::basic_streambuf +{ + using size_type = largeobject::size_type; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = largeobjectaccess::openmode; + using seekdir = largeobjectaccess::seekdir; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, largeobject o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, oid o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } + + virtual ~largeobject_streambuf() noexcept + { + delete[] m_p; + delete[] m_g; + } + + /// For use by large object stream classes. + void process_notice(zview const &s) { m_obj.process_notice(s); } + +protected: + virtual int sync() override + { + // setg() sets eback, gptr, egptr. + this->setg(this->eback(), this->eback(), this->egptr()); + return overflow(eof()); + } + + virtual pos_type seekoff(off_type offset, seekdir dir, openmode) override + { + return adjust_eof(m_obj.cseek(largeobjectaccess::off_type(offset), dir)); + } + + virtual pos_type seekpos(pos_type pos, openmode) override + { + largeobjectaccess::pos_type const newpos{ + m_obj.cseek(largeobjectaccess::off_type(pos), std::ios::beg)}; + return adjust_eof(newpos); + } + + virtual int_type overflow(int_type ch) override + { + auto *const pp{this->pptr()}; + if (pp == nullptr) + return eof(); + auto *const pb{this->pbase()}; + int_type res{0}; + + if (pp > pb) + { + auto const write_sz{pp - pb}; + auto const written_sz{ + m_obj.cwrite(pb, static_cast(pp - pb))}; + if (internal::cmp_less_equal(written_sz, 0)) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + "libpq reports error"}; + else if (write_sz != written_sz) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + + std::to_string(written_sz) + "/" + std::to_string(write_sz) + + " bytes written"}; + auto const out{adjust_eof(written_sz)}; + + if constexpr (std::is_arithmetic_v) + res = check_cast(out, "largeobject position"sv); + else + res = int_type(out); + } + this->setp(m_p, m_p + m_bufsize); + + // Write that one more character, if it's there. + if (ch != eof()) + { + *this->pptr() = static_cast(ch); + this->pbump(1); + } + return res; + } + + virtual int_type overflow() { return overflow(eof()); } + + virtual int_type underflow() override + { + if (this->gptr() == nullptr) + return eof(); + auto *const eb{this->eback()}; + auto const res{adjust_eof( + m_obj.cread(this->eback(), static_cast(m_bufsize)))}; + this->setg( + eb, eb, eb + (res == eof() ? 0 : static_cast(res))); + return (res == eof() or res == 0) ? eof() : traits_type::to_int_type(*eb); + } + +private: + /// Shortcut for traits_type::eof(). + static int_type eof() { return traits_type::eof(); } + + /// Helper: change error position of -1 to EOF (probably a no-op). + template static std::streampos adjust_eof(INTYPE pos) + { + bool const at_eof{pos == -1}; + if constexpr (std::is_arithmetic_v) + { + return check_cast( + (at_eof ? eof() : pos), "large object seek"sv); + } + else + { + return std::streampos(at_eof ? eof() : pos); + } + } + + void initialize(openmode mode) + { + if ((mode & std::ios::in) != 0) + { + m_g = new char_type[unsigned(m_bufsize)]; + this->setg(m_g, m_g, m_g); + } + if ((mode & std::ios::out) != 0) + { + m_p = new char_type[unsigned(m_bufsize)]; + this->setp(m_p, m_p + m_bufsize); + } + } + + size_type const m_bufsize; + largeobjectaccess m_obj; + + /// Get & put buffers. + char_type *m_g, *m_p; +}; + + +/// Input stream that gets its data from a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This class worked like any other istream, but to read data from a large + * object. It supported all formatting and streaming operations of + * `std::istream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_ilostream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Identifier of a large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + +private: + largeobject_streambuf m_buf; +}; + +using ilostream = basic_ilostream; + + +/// Output stream that writes data back to a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like any other ostream, but to write data to a large object. + * It supported all formatting and streaming operations of `std::ostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_olostream : public std::basic_ostream +{ + using super = std::basic_ostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_olostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using olostream = basic_olostream; + + +/// Stream that reads and writes a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like a std::iostream, but to read data from, or write data to, a + * large object. It supported all formatting and streaming operations of + * `std::iostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_lostream : public std::basic_iostream +{ + using super = std::basic_iostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_lostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using lostream = basic_lostream; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction new file mode 100644 index 0000000..bb5b797 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction @@ -0,0 +1,8 @@ +/** pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction.hxx new file mode 100644 index 0000000..c507155 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/nontransaction.hxx @@ -0,0 +1,76 @@ +/* Definition of the pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/nontransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NONTRANSACTION +#define PQXX_H_NONTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/connection.hxx" +#include "pqxx/result.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +using namespace std::literals; + +/// Simple "transaction" class offering no transactional integrity. +/** + * @ingroup transactions + * + * nontransaction, like transaction or any other transaction_base-derived + * class, provides access to a database through a connection. Unlike its + * siblings, however, nontransaction does not maintain any kind of + * transactional integrity. This may be useful eg. for read-only access to the + * database that does not require a consistent, atomic view on its data; or for + * operations that are not allowed within a backend transaction, such as + * creating tables. + * + * For queries that update the database, however, a real transaction is likely + * to be faster unless the transaction consists of only a single record update. + * + * Also, you can keep a nontransaction open for as long as you like. Actual + * back-end transactions are limited in lifespan, and will sometimes fail just + * because they took too long to execute or were left idle for too long. This + * will not happen with a nontransaction (although the connection may still + * time out, e.g. when the network is unavailable for a very long time). + * + * Any query executed in a nontransaction is committed immediately, and neither + * commit() nor abort() has any effect. + * + * Database features that require a backend transaction, such as cursors or + * large objects, will not work in a nontransaction. + */ +class PQXX_LIBEXPORT nontransaction final : public transaction_base +{ +public: + /// Constructor. + /** Create a "dummy" transaction. + * @param c Connection in which this "transaction" will operate. + * @param tname Optional tname for the transaction, beginning with a letter + * and containing only letters and digits. + */ + nontransaction(connection &c, std::string_view tname = ""sv) : + transaction_base{c, tname, std::shared_ptr{}} + { + register_transaction(); + } + + virtual ~nontransaction() override { close(); } + +private: + virtual void do_commit() override {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification new file mode 100644 index 0000000..a0bd1c7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification @@ -0,0 +1,8 @@ +/** pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification.hxx new file mode 100644 index 0000000..b59b856 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/notification.hxx @@ -0,0 +1,94 @@ +/* Definition of the pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/notification instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NOTIFICATION +#define PQXX_H_NOTIFICATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// "Observer" base class for notifications. +/** @addtogroup notification Notifications and Receivers + * + * To listen on a notification issued using the NOTIFY command, derive your own + * class from notification_receiver and define its function-call operator to + * perform whatever action you wish to take when the given notification + * arrives. Then create an object of that class and pass it to your connection. + * DO NOT use raw SQL to listen for notifications, or your attempts to listen + * won't be resumed when a connection fails--and you'll have no way to notice. + * + * Notifications never arrive inside a transaction, not even in a + * nontransaction. Therefore, you are free to open a transaction of your own + * inside your receiver's function invocation operator. + * + * Notifications you are listening for may arrive anywhere within libpqxx code, + * but be aware that **PostgreSQL defers notifications occurring inside + * transactions.** (This was done for excellent reasons; just think about what + * happens if the transaction where you happen to handle an incoming + * notification is later rolled back for other reasons). So if you're keeping + * a transaction open, don't expect any of your receivers on the same + * connection to be notified. + * + * (For very similar reasons, outgoing notifications are also not sent until + * the transaction that sends them commits.) + * + * Multiple receivers on the same connection may listen on a notification of + * the same name. An incoming notification is processed by invoking all + * receivers (zero or more) of the same name. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE notification_receiver +{ +public: + /// Register the receiver with a connection. + /** + * @param c Connnection to operate on. + * @param channel Name of the notification to listen for. + */ + notification_receiver(connection &c, std::string_view channel); + /// Register the receiver with a connection. + notification_receiver(notification_receiver const &) = delete; + /// Register the receiver with a connection. + notification_receiver &operator=(notification_receiver const &) = delete; + /// Deregister the receiver. + virtual ~notification_receiver(); + + /// The channel that this receiver listens on. + [[nodiscard]] std::string const &channel() const & { return m_channel; } + + // TODO: Change API to take payload as zview instead of string ref. + /// Overridable: action to invoke when notification arrives. + /** + * @param payload An optional string that may have been passed to the NOTIFY + * command. + * @param backend_pid Process ID of the database backend process that served + * our connection when the notification arrived. The actual process ID + * behind the connection may have changed by the time this method is called. + */ + virtual void operator()(std::string const &payload, int backend_pid) = 0; + +protected: + connection &conn() const noexcept { return m_conn; } + +private: + connection &m_conn; + std::string m_channel; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params new file mode 100644 index 0000000..4098782 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params @@ -0,0 +1,8 @@ +/** Helper classes for passing statement parameters. + * + * Use these for prepared statements and parameterised statements. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/params.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params.hxx new file mode 100644 index 0000000..2d29cdf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/params.hxx @@ -0,0 +1,383 @@ +/* Helpers for prepared statements and parameterised statements. + * + * See the connection class for more about such statements. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PARAMS +#define PQXX_H_PARAMS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/statement_parameters.hxx" +#include "pqxx/types.hxx" + + +/// @deprecated The new @ref params class replaces all of this. +namespace pqxx::prepare +{ +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * sequence ranging from `begin` to `end` exclusively. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic sequences. + * + * @param begin A pointer or iterator for iterating parameters. + * @param end A pointer or iterator for iterating parameters. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(IT begin, IT end) +{ + return pqxx::internal::dynamic_params(begin, end); +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C const &container) +{ + using IT = typename C::const_iterator; +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @param accessor For each parameter `p`, pass `accessor(p)`. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C &container, ACCESSOR accessor) +{ + using IT = decltype(std::begin(container)); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container, accessor}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} +} // namespace pqxx::prepare + + +namespace pqxx +{ +/// Generate parameter placeholders for use in an SQL statement. +/** When you want to pass parameters to a prepared statement or a parameterised + * statement, you insert placeholders into the SQL. During invocation, the + * database replaces those with the respective parameter values you passed. + * + * The placeholders look like `$1` (for the first parameter value), `$2` (for + * the second), and so on. You can just write those directly in your + * statement. But for those rare cases where it becomes difficult to track + * which number a placeholder should have, you can use a `placeholders` object + * to count and generate them in order. + */ +template class placeholders +{ +public: + /// Maximum number of parameters we support. + static inline constexpr unsigned int max_params{ + (std::numeric_limits::max)()}; + + placeholders() + { + static constexpr auto initial{"$1\0"sv}; + initial.copy(std::data(m_buf), std::size(initial)); + } + + /// Read an ephemeral version of the current placeholder text. + /** @warning Changing the current placeholder number will overwrite this. + * Use the view immediately, or lose it. + */ + constexpr zview view() const &noexcept + { + return zview{std::data(m_buf), m_len}; + } + + /// Read the current placeholder text, as a `std::string`. + /** This will be slightly slower than converting to a `zview`. With most + * C++ implementations however, until you get into ridiculous numbers of + * parameters, the string will benefit from the Short String Optimization, or + * SSO. + */ + std::string get() const { return std::string(std::data(m_buf), m_len); } + + /// Move on to the next parameter. + void next() & + { + if (m_current >= max_params) + throw range_error{pqxx::internal::concat( + "Too many parameters in one statement: limit is ", max_params, ".")}; + ++m_current; + if (m_current % 10 == 0) + { + // Carry the 1. Don't get too clever for this relatively rare + // case, just rewrite the entire number. Leave the $ in place + // though. + char *const data{std::data(m_buf)}; + char *const end{string_traits::into_buf( + data + 1, data + std::size(m_buf), m_current)}; + // (Subtract because we don't include the trailing zero.) + m_len = check_cast(end - data, "placeholders counter") - 1; + } + else + { + PQXX_LIKELY + // Shortcut for the common case: just increment that last digit. + ++m_buf[m_len - 1]; + } + } + + /// Return the current placeholder number. The initial placeholder is 1. + COUNTER count() const noexcept { return m_current; } + +private: + /// Current placeholder number. Starts at 1. + COUNTER m_current = 1; + + /// Length of the current placeholder string, not including trailing zero. + COUNTER m_len = 2; + + /// Text buffer where we render the placeholders, with a trailing zero. + /** We keep reusing this for every subsequent placeholder, just because we + * don't like string allocations. + * + * Maximum length is the maximum base-10 digits that COUNTER can fully + * represent, plus 1 more for the extra digit that it can only partially + * fill up, plus room for the dollar sign and the trailing zero. + */ + std::array::digits10 + 3> m_buf; +}; + + +/// Build a parameter list for a parameterised or prepared statement. +/** When calling a parameterised statement or a prepared statement, you can + * pass parameters into the statement directly in the invocation, as + * additional arguments to `exec_prepared` or `exec_params`. But in + * complex cases, sometimes that's just not convenient. + * + * In those situations, you can create a `params` and append your parameters + * into that, one by one. Then you pass the `params` to `exec_prepared` or + * `exec_params`. + * + * Combinations also work: if you have a `params` containing a string + * parameter, and you call `exec_params` with an `int` argument followed by + * your `params`, you'll be passing the `int` as the first parameter and + * the string as the second. You can even insert a `params` in a `params`, + * or pass two `params` objects to a statement. + */ +class PQXX_LIBEXPORT params +{ +public: + params() = default; + + /// Pre-populate a `params` with `args`. Feel free to add more later. + template constexpr params(Args &&...args) + { + reserve(sizeof...(args)); + append_pack(std::forward(args)...); + } + + /// Pre-allocate room for at least `n` parameters. + /** This is not needed, but it may improve efficiency. + * + * Reserve space if you're going to add parameters individually, and you've + * got some idea of how many there are going to be. It may save some + * memory re-allocations. + */ + void reserve(std::size_t n) &; + + // C++20: constexpr. + /// Get the number of parameters currently in this `params`. + [[nodiscard]] auto size() const noexcept { return m_params.size(); } + + // C++20: Use the vector's ssize() directly and go noexcept+constexpr. + /// Get the number of parameters (signed). + /** Unlike `size()`, this is not yet `noexcept`. That's because C++17's + * `std::vector` does not have a `ssize()` member function. These member + * functions are `noexcept`, but `std::size()` and `std::ssize()` are + * not. + */ + [[nodiscard]] auto ssize() const { return pqxx::internal::ssize(m_params); } + + /// Append a null value. + void append() &; + + /// Append a non-null zview parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(zview) &; + + /// Append a non-null string parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the @ref zview variant if you can, or `std::move()` + */ + void append(std::string const &) &; + + /// Append a non-null string parameter. + void append(std::string &&) &; + + /// Append a non-null binary parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(std::basic_string_view) &; + + /// Append a non-null binary parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the `std::basic_string_view` variant if you can, or + * `std::move()`. + */ + void append(std::basic_string const &) &; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Append a non-null binary parameter. + /** The `data` object must stay in place and unchanged, for as long as the + * `params` remains active. + */ + template void append(DATA const &data) & + { + append( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Append a non-null binary parameter. + void append(std::basic_string &&) &; + + /// @deprecated Append binarystring parameter. + /** The binarystring must stay valid for as long as the `params` remains + * active. + */ + void append(binarystring const &value) &; + + /// Append all parameters from value. + template + void append(pqxx::internal::dynamic_params const &value) & + { + for (auto ¶m : value) append(value.access(param)); + } + + void append(params const &value) &; + + void append(params &&value) &; + + /// Append a non-null parameter, converting it to its string + /// representation. + template void append(TYPE const &value) & + { + // TODO: Pool storage for multiple string conversions in one buffer? + if constexpr (nullness>::always_null) + { + ignore_unused(value); + m_params.emplace_back(); + } + else if (is_null(value)) + { + m_params.emplace_back(); + } + else + { + m_params.emplace_back(entry{to_string(value)}); + } + } + + /// Append all elements of `range` as parameters. + template void append_multi(RANGE const &range) & + { +#if defined(PQXX_HAVE_CONCEPTS) + if constexpr (std::ranges::sized_range) + reserve(std::size(*this) + std::size(range)); +#endif + for (auto &value : range) append(value); + } + + /// For internal use: Generate a `params` object for use in calls. + /** The params object encapsulates the pointers which we will need to pass + * to libpq when calling a parameterised or prepared statement. + * + * The pointers in the params will refer to storage owned by either the + * params object, or the caller. This is not a problem because a + * `c_params` object is guaranteed to live only while the call is going on. + * As soon as we climb back out of that call tree, we're done with that + * data. + */ + pqxx::internal::c_params make_c_params() const; + +private: + /// Recursively append a pack of params. + template + void append_pack(Arg &&arg, More &&...args) + { + this->append(std::forward(arg)); + // Recurse for remaining args. + append_pack(std::forward(args)...); + } + + /// Terminating case: append an empty parameter pack. It's not hard BTW. + constexpr void append_pack() noexcept {} + + // The way we store a parameter depends on whether it's binary or text + // (most types are text), and whether we're responsible for storing the + // contents. + using entry = std::variant< + std::nullptr_t, zview, std::string, std::basic_string_view, + std::basic_string>; + std::vector m_params; + + static constexpr std::string_view s_overflow{ + "Statement parameter length overflow."sv}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline new file mode 100644 index 0000000..bf82884 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline @@ -0,0 +1,8 @@ +/** pqxx::pipeline class. + * + * Throughput-optimized query interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline.hxx new file mode 100644 index 0000000..049dcdd --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pipeline.hxx @@ -0,0 +1,237 @@ +/* Definition of the pqxx::pipeline class. + * + * Throughput-optimized mechanism for executing queries. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PIPELINE +#define PQXX_H_PIPELINE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +// TODO: libpq 14 introduced a similar "pipeline mode." Can we use that? + +/// Processes several queries in FIFO manner, optimized for high throughput. +/** Use a pipeline if you want to keep doing useful work while your queries are + * executing. Result retrieval is decoupled from execution request; queries + * "go in at the front" and results "come out the back." + * + * Actually, you can retrieve the results in any order if you want, but it may + * lead to surprising "time travel" effects if any of the queries fails. In + * particular, syntax errors in the queries can confuse things and show up too + * early in the stream of results. + * + * Generally, if any of the queries fails, it will throw an exception at the + * point where you request its result. But it may happen earlier, especially + * if you request results out of chronological order. + * + * @warning While a pipeline is active, you cannot execute queries, open + * streams, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT pipeline : public transaction_focus +{ +public: + /// Identifying numbers for queries. + using query_id = long; + + pipeline(pipeline const &) = delete; + pipeline &operator=(pipeline const &) = delete; + + /// Start a pipeline. + explicit pipeline(transaction_base &t) : transaction_focus{t, s_classname} + { + init(); + } + /// Start a pipeline. Assign it a name, for more helpful error messages. + pipeline(transaction_base &t, std::string_view tname) : + transaction_focus{t, s_classname, tname} + { + init(); + } + + /// Close the pipeline. + ~pipeline() noexcept; + + /// Add query to the pipeline. + /** Queries accumulate in the pipeline, which sends them to the backend in a + * batch separated by semicolons. The queries you insert must not use this + * trick themselves, or the pipeline will get hopelessly confused! + * + * @return Identifier for this query, unique only within this pipeline. + */ + query_id insert(std::string_view) &; + + /// Wait for all ongoing or pending operations to complete, and detach. + /** Detaches from the transaction when done. + * + * This does not produce the queries' results, so it may not report any + * errors which may have occurred in their execution. To be sure that your + * statements succeeded, call @ref retrieve until the pipeline is empty. + */ + void complete(); + + /// Forget all ongoing or pending operations and retrieved results. + /** Queries already sent to the backend may still be completed, depending + * on implementation and timing. + * + * Any error state (unless caused by an internal error) will also be cleared. + * This is mostly useful in a nontransaction, since a backend transaction is + * aborted automatically when an error occurs. + * + * Detaches from the transaction when done. + */ + void flush(); + + /// Cancel ongoing query, if any. + /** May cancel any or all of the queries that have been inserted at this + * point whose results have not yet been retrieved. If the pipeline lives in + * a backend transaction, that transaction may be left in a nonfunctional + * state in which it can only be aborted. + * + * Therefore, either use this function in a nontransaction, or abort the + * transaction after calling it. + */ + void cancel(); + + /// Is result for given query available? + [[nodiscard]] bool is_finished(query_id) const; + + /// Retrieve result for given query. + /** If the query failed for whatever reason, this will throw an exception. + * The function will block if the query has not finished yet. + * @warning If results are retrieved out-of-order, i.e. in a different order + * than the one in which their queries were inserted, errors may "propagate" + * to subsequent queries. + */ + result retrieve(query_id qid) + { + return retrieve(m_queries.find(qid)).second; + } + + /// Retrieve oldest unretrieved result (possibly wait for one). + /** @return The query's identifier and its result set. */ + std::pair retrieve(); + + [[nodiscard]] bool empty() const noexcept { return std::empty(m_queries); } + + /// Set maximum number of queries to retain before issuing them to the + /// backend. + /** The pipeline will perform better if multiple queries are issued at once, + * but retaining queries until the results are needed (as opposed to issuing + * them to the backend immediately) may negate any performance benefits the + * pipeline can offer. + * + * Recommended practice is to set this value no higher than the number of + * queries you intend to insert at a time. + * @param retain_max A nonnegative "retention capacity;" passing zero will + * cause queries to be issued immediately + * @return Old retention capacity + */ + int retain(int retain_max = 2) &; + + + /// Resume retained query emission. Harmless when not needed. + void resume() &; + +private: + struct PQXX_PRIVATE Query + { + explicit Query(std::string_view q) : + query{std::make_shared(q)} + {} + + std::shared_ptr query; + result res; + }; + + using QueryMap = std::map; + + void init(); + void attach(); + void detach(); + + /// Upper bound to query id's. + static constexpr query_id qid_limit() noexcept + { + // Parenthesise this to work around an eternal Visual C++ problem: + // Without the extra parentheses, unless NOMINMAX is defined, the + // preprocessor will mistake this "max" for its annoying built-in macro + // of the same name. + return (std::numeric_limits::max)(); + } + + /// Create new query_id. + PQXX_PRIVATE query_id generate_id(); + + bool have_pending() const noexcept + { + return m_issuedrange.second != m_issuedrange.first; + } + + PQXX_PRIVATE void issue(); + + /// The given query failed; never issue anything beyond that. + void set_error_at(query_id qid) noexcept + { + PQXX_UNLIKELY + if (qid < m_error) + m_error = qid; + } + + /// Throw pqxx::internal_error. + [[noreturn]] PQXX_PRIVATE void internal_error(std::string const &err); + + PQXX_PRIVATE bool obtain_result(bool expect_none = false); + + PQXX_PRIVATE void obtain_dummy(); + PQXX_PRIVATE void get_further_available_results(); + PQXX_PRIVATE void check_end_results(); + + /// Receive any results that happen to be available; it's not urgent. + PQXX_PRIVATE void receive_if_available(); + + /// Receive results, up to stop if possible. + PQXX_PRIVATE void receive(pipeline::QueryMap::const_iterator stop); + std::pair retrieve(pipeline::QueryMap::iterator); + + QueryMap m_queries; + std::pair m_issuedrange; + int m_retain = 0; + int m_num_waiting = 0; + query_id m_q_id = 0; + + /// Is there a "dummy query" pending? + bool m_dummy_pending = false; + + /// Point at which an error occurred; no results beyond it will be available + query_id m_error = qid_limit(); + + /// Encoding. + /** We store this in the object to avoid the risk of exceptions at awkward + * moments. + */ + internal::encoding_group m_encoding; + + static constexpr std::string_view s_classname{"pipeline"}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pqxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pqxx new file mode 100644 index 0000000..17a8eaa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/pqxx @@ -0,0 +1,28 @@ +/// Convenience header: include all libpqxx definitions. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/array.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/params.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/prepared_statement.hxx" +#include "pqxx/result.hxx" +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/internal/result_iter.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/transactor.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement new file mode 100644 index 0000000..674be70 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement.hxx new file mode 100644 index 0000000..674be70 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/prepared_statement.hxx @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range new file mode 100644 index 0000000..11985ec --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range @@ -0,0 +1,6 @@ +/** Client-side support for SQL range types. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/range.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range.hxx new file mode 100644 index 0000000..dc480e4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/range.hxx @@ -0,0 +1,515 @@ +#ifndef PQXX_H_RANGE +#define PQXX_H_RANGE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" + +namespace pqxx +{ +/// An _unlimited_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should extend + * to infinity on that side. + * + * An unlimited boundary is always inclusive of "infinity" values, if the + * range's value type supports them. + */ +struct no_bound +{ + template constexpr bool extends_down_to(TYPE const &) const + { + return true; + } + template constexpr bool extends_up_to(TYPE const &) const + { + return true; + } +}; + + +/// An _inclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should include + * the value. + */ +template class inclusive_bound +{ +public: + inclusive_bound() = delete; + explicit inclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an inclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return not(value < m_value); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return not(m_value < value); + } + +private: + TYPE m_value; +}; + + +/// An _exclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should _not_ + * include the value. + */ +template class exclusive_bound +{ +public: + exclusive_bound() = delete; + explicit exclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an exclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return m_value < value; + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return value < m_value; + } + +private: + TYPE m_value; +}; + + +/// A range boundary value. +/** A range bound is either no bound at all; or an inclusive bound; or an + * exclusive bound. Pass one of the three to the constructor. + */ +template class range_bound +{ +public: + range_bound() = delete; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(no_bound) : m_bound{} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(inclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(exclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound const &) = default; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound &&) = default; + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range_bound const &rhs) const + { + if (this->is_limited()) + return ( + rhs.is_limited() and (this->is_inclusive() == rhs.is_inclusive()) and + (*this->value() == *rhs.value())); + else + return not rhs.is_limited(); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range_bound const &rhs) const { return not(*this == rhs); } + range_bound &operator=(range_bound const &) = default; + range_bound &operator=(range_bound &&) = default; + + /// Is this a finite bound? + constexpr bool is_limited() const noexcept + { + return not std::holds_alternative(m_bound); + } + + /// Is this boundary an inclusive one? + constexpr bool is_inclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + /// Is this boundary an exclusive one? + constexpr bool is_exclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as a lower bound, include `value`? + bool extends_down_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_down_to(value); }, + m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as an upper bound, include `value`? + bool extends_up_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_up_to(value); }, + m_bound); + } + + /// Return bound value, or `nullptr` if it's not limited. + [[nodiscard]] constexpr TYPE const *value() const &noexcept + { + return std::visit( + [](auto const &bound) noexcept { + using bound_t = std::decay_t; + if constexpr (std::is_same_v) + return static_cast(nullptr); + else + return &bound.get(); + }, + m_bound); + } + +private: + std::variant, exclusive_bound> m_bound; +}; + + +// C++20: Concepts for comparisons, construction, etc. +/// A C++ equivalent to PostgreSQL's range types. +/** You can use this as a client-side representation of a "range" in SQL. + * + * PostgreSQL defines several range types, differing in the data type over + * which they range. You can also define your own range types. + * + * Usually you'll want the server to deal with ranges. But on occasions where + * you need to work with them client-side, you may want to use @ref + * pqxx::range. (In cases where all you do is pass them along to the server + * though, it's not worth the complexity. In that case you might as well treat + * ranges as just strings.) + * + * For documentation on PostgreSQL's range types, see: + * https://www.postgresql.org/docs/current/rangetypes.html + * + * The value type must be copyable and default-constructible, and support the + * less-than (`<`) and equals (`==`) comparisons. Value initialisation must + * produce a consistent value. + */ +template class range +{ +public: + /// Create a range. + /** For each of the two bounds, pass a @ref no_bound, @ref inclusive_bound, + * or + * @ref exclusive_bound. + */ + range(range_bound lower, range_bound upper) : + m_lower{lower}, m_upper{upper} + { + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + throw range_error{internal::concat( + "Range's lower bound (", *lower.value(), + ") is greater than its upper bound (", *upper.value(), ").")}; + } + + // TODO: constexpr and/or noexcept if underlying constructor supports it. + /// Create an empty range. + /** SQL has a separate literal to denote an empty range, but any range which + * encompasses no values is an empty range. + */ + range() : + m_lower{exclusive_bound{TYPE{}}}, + m_upper{exclusive_bound{TYPE{}}} + {} + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range const &rhs) const + { + return (this->lower_bound() == rhs.lower_bound() and + this->upper_bound() == rhs.upper_bound()) or + (this->empty() and rhs.empty()); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range const &rhs) const { return !(*this == rhs); } + + range(range const &) = default; + range(range &&) = default; + range &operator=(range const &) = default; + range &operator=(range &&) = default; + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Is this range clearly empty? + /** An empty range encompasses no values. + * + * It is possible to "fool" this. For example, if your range is of an + * integer type and has exclusive bounds of 0 and 1, it encompasses no values + * but its `empty()` will return false. The PostgreSQL implementation, by + * contrast, will notice that it is empty. Similar things can happen for + * floating-point types, but with more subtleties and edge cases. + */ + bool empty() const + { + return (m_lower.is_exclusive() or m_upper.is_exclusive()) and + m_lower.is_limited() and m_upper.is_limited() and + not(*m_lower.value() < *m_upper.value()); + } + + // TODO: constexpr and/or noexcept if underlying functions support it. + /// Does this range encompass `value`? + bool contains(TYPE value) const + { + return m_lower.extends_down_to(value) and m_upper.extends_up_to(value); + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Does this range encompass all of `other`? + /** This function is not particularly smart. It does not know, for example, + * that integer ranges `[0,9]` and `[0,10)` contain the same values. + */ + bool contains(range const &other) const + { + return (*this & other) == other; + } + + [[nodiscard]] constexpr range_bound const & + lower_bound() const &noexcept + { + return m_lower; + } + [[nodiscard]] constexpr range_bound const & + upper_bound() const &noexcept + { + return m_upper; + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Intersection of two ranges. + /** Returns a range describing those values which are in both ranges. + */ + range operator&(range const &other) const + { + range_bound lower{no_bound{}}; + if (not this->lower_bound().is_limited()) + lower = other.lower_bound(); + else if (not other.lower_bound().is_limited()) + lower = this->lower_bound(); + else if (*this->lower_bound().value() < *other.lower_bound().value()) + lower = other.lower_bound(); + else if (*other.lower_bound().value() < *this->lower_bound().value()) + lower = this->lower_bound(); + else if (this->lower_bound().is_exclusive()) + lower = this->lower_bound(); + else + lower = other.lower_bound(); + + range_bound upper{no_bound{}}; + if (not this->upper_bound().is_limited()) + upper = other.upper_bound(); + else if (not other.upper_bound().is_limited()) + upper = this->upper_bound(); + else if (*other.upper_bound().value() < *this->upper_bound().value()) + upper = other.upper_bound(); + else if (*this->upper_bound().value() < *other.upper_bound().value()) + upper = this->upper_bound(); + else if (this->upper_bound().is_exclusive()) + upper = this->upper_bound(); + else + upper = other.upper_bound(); + + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + return {}; + else + return {lower, upper}; + } + + /// Convert to another base type. + template operator range() const + { + range_bound lower{no_bound{}}, upper{no_bound{}}; + if (lower_bound().is_inclusive()) + lower = inclusive_bound{*lower_bound().value()}; + else if (lower_bound().is_exclusive()) + lower = exclusive_bound{*lower_bound().value()}; + + if (upper_bound().is_inclusive()) + upper = inclusive_bound{*upper_bound().value()}; + else if (upper_bound().is_exclusive()) + upper = exclusive_bound{*upper_bound().value()}; + + return {lower, upper}; + } + +private: + range_bound m_lower, m_upper; +}; + + +/// String conversions for a @ref range type. +/** Conversion assumes that either your client encoding is UTF-8, or the values + * are pure ASCII. + */ +template struct string_traits> +{ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, range const &value) + { + return generic_to_buf(begin, end, value); + } + + static inline char * + into_buf(char *begin, char *end, range const &value) + { + if (value.empty()) + { + if ((end - begin) <= internal::ssize(s_empty)) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin + s_empty.copy(begin, std::size(s_empty)); + *here++ = '\0'; + return here; + } + else + { + if (end - begin < 4) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin; + *here++ = + (static_cast(value.lower_bound().is_inclusive() ? '[' : '(')); + TYPE const *lower{value.lower_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (lower != nullptr) + here = string_traits::into_buf(here, end, *lower) - 1; + *here++ = ','; + TYPE const *upper{value.upper_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (upper != nullptr) + here = string_traits::into_buf(here, end, *upper) - 1; + if ((end - here) < 2) + throw conversion_overrun{s_overrun.c_str()}; + *here++ = + static_cast(value.upper_bound().is_inclusive() ? ']' : ')'); + *here++ = '\0'; + return here; + } + } + + [[nodiscard]] static inline range from_string(std::string_view text) + { + if (std::size(text) < 3) + throw pqxx::conversion_error{err_bad_input(text)}; + bool left_inc{false}; + switch (text[0]) + { + case '[': left_inc = true; break; + + case '(': break; + + case 'e': + case 'E': + if ( + (std::size(text) != std::size(s_empty)) or + (text[1] != 'm' and text[1] != 'M') or + (text[2] != 'p' and text[2] != 'P') or + (text[3] != 't' and text[3] != 'T') or + (text[4] != 'y' and text[4] != 'Y')) + throw pqxx::conversion_error{err_bad_input(text)}; + return {}; + break; + + default: throw pqxx::conversion_error{err_bad_input(text)}; + } + + auto scan{internal::get_glyph_scanner(internal::encoding_group::UTF8)}; + // The field parser uses this to track which field it's parsing, and + // when not to expect a field separator. + std::size_t index{0}; + // The last field we expect to see. + static constexpr std::size_t last{1}; + // Current parsing position. We skip the opening parenthesis or bracket. + std::size_t pos{1}; + // The string may leave out either bound to indicate that it's unlimited. + std::optional lower, upper; + // We reuse the same field parser we use for composite values and arrays. + internal::parse_composite_field(index, text, pos, lower, scan, last); + internal::parse_composite_field(index, text, pos, upper, scan, last); + + // We need one more character: the closing parenthesis or bracket. + if (pos != std::size(text)) + throw pqxx::conversion_error{err_bad_input(text)}; + char const closing{text[pos - 1]}; + if (closing != ')' and closing != ']') + throw pqxx::conversion_error{err_bad_input(text)}; + bool const right_inc{closing == ']'}; + + range_bound lower_bound{no_bound{}}, upper_bound{no_bound{}}; + if (lower) + { + if (left_inc) + lower_bound = inclusive_bound{*lower}; + else + lower_bound = exclusive_bound{*lower}; + } + if (upper) + { + if (right_inc) + upper_bound = inclusive_bound{*upper}; + else + upper_bound = exclusive_bound{*upper}; + } + + return {lower_bound, upper_bound}; + } + + [[nodiscard]] static inline constexpr std::size_t + size_buffer(range const &value) noexcept + { + TYPE const *lower{value.lower_bound().value()}, + *upper{value.upper_bound().value()}; + std::size_t const lsz{ + lower == nullptr ? 0 : string_traits::size_buffer(*lower) - 1}, + usz{upper == nullptr ? 0 : string_traits::size_buffer(*upper) - 1}; + + if (value.empty()) + return std::size(s_empty) + 1; + else + return 1 + lsz + 1 + usz + 2; + } + +private: + static constexpr zview s_empty{"empty"_zv}; + static constexpr auto s_overrun{"Not enough space in buffer for range."_zv}; + + /// Compose error message for invalid range input. + static std::string err_bad_input(std::string_view text) + { + return internal::concat("Invalid range input: '", text, "'"); + } +}; + + +/// A range type does not have an innate null value. +template struct nullness> : no_null> +{}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result new file mode 100644 index 0000000..523394b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result @@ -0,0 +1,16 @@ +/** pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" + +// Now include some types which depend on result, but which the user will +// expect to see defined after including this header. +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/result_iter.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result.hxx new file mode 100644 index 0000000..6c41cc0 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/result.hxx @@ -0,0 +1,335 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT +#define PQXX_H_RESULT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include + +#include "pqxx/except.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx::internal +{ +// TODO: Make noexcept (but breaks ABI). +PQXX_LIBEXPORT void clear_result(pq::PGresult const *); +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class result_connection; +class result_creation; +class result_pipeline; +class result_row; +class result_sql_cursor; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Result set containing data returned by a query or command. +/** This behaves as a container (as defined by the C++ standard library) and + * provides random access const iterators to iterate over its rows. You can + * also access a row by indexing a `result R` by the row's zero-based + * number: + * + * + * for (result::size_type i=0; i < std::size(R); ++i) Process(R[i]); + * + * + * Result sets in libpqxx are lightweight, reference-counted wrapper objects + * which are relatively small and cheap to copy. Think of a result object as + * a "smart pointer" to an underlying result set. + * + * @warning The result set that a result object points to is not thread-safe. + * If you copy a result object, it still refers to the same underlying result + * set. So never copy, destroy, query, or otherwise access a result while + * another thread may be copying, destroying, querying, or otherwise accessing + * the same result set--even if it is doing so through a different result + * object! + */ +class PQXX_LIBEXPORT result +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + using reference = row; + using const_iterator = const_result_iterator; + using pointer = const_iterator; + using iterator = const_iterator; + using const_reverse_iterator = const_reverse_result_iterator; + using reverse_iterator = const_reverse_iterator; + + result() noexcept : + m_data{make_data_pointer()}, + m_query{}, + m_encoding{internal::encoding_group::MONOBYTE} + {} + + result(result const &rhs) noexcept = default; + result(result &&rhs) noexcept = default; + + /// Assign one result to another. + /** Copying results is cheap: it copies only smart pointers, but the actual + * data stays in the same place. + */ + result &operator=(result const &rhs) noexcept = default; + + /// Assign one result to another, invaliding the old one. + result &operator=(result &&rhs) noexcept = default; + + /** + * @name Comparisons + * + * You can compare results for equality. Beware: this is a very strict, + * dumb comparison. The smallest difference between two results (such as a + * string "Foo" versus a string "foo") will make them unequal. + */ + //@{ + /// Compare two results for equality. + [[nodiscard]] bool operator==(result const &) const noexcept; + /// Compare two results for inequality. + [[nodiscard]] bool operator!=(result const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /// Iterate rows, reading them directly into a tuple of "TYPE...". + /** Converts the fields to values of the given respective types. + * + * Use this only with a ranged "for" loop. The iteration produces + * std::tuple which you can "unpack" to a series of `auto` + * variables. + */ + template auto iter() const; + + [[nodiscard]] const_reverse_iterator rbegin() const; + [[nodiscard]] const_reverse_iterator crbegin() const; + [[nodiscard]] const_reverse_iterator rend() const; + [[nodiscard]] const_reverse_iterator crend() const; + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] inline const_iterator end() const noexcept; + [[nodiscard]] inline const_iterator cend() const noexcept; + + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + [[nodiscard]] PQXX_PURE bool empty() const noexcept; + [[nodiscard]] size_type capacity() const noexcept { return size(); } + + /// Exchange two `result` values in an exception-safe manner. + /** If the swap fails, the two values will be exactly as they were before. + * + * The swap is not necessarily thread-safe. + */ + void swap(result &) noexcept; + + /// Index a row by number. + /** This returns a @ref row object. Generally you should not keep the row + * around as a variable, but if you do, make sure that your variable is a + * `row`, not a `row&`. + */ + [[nodiscard]] row operator[](size_type i) const noexcept; + +#if defined(PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT) + // TODO: If C++23 will let us, also accept string for the column. + [[nodiscard]] field + operator[](size_type row_num, row_size_type col_num) const noexcept; +#endif + + /// Index a row by number, but check that the row number is valid. + row at(size_type) const; + + /// Index a field by row number and column number. + field at(size_type, row_size_type) const; + + /// Let go of the result's data. + /** Use this if you need to deallocate the result data earlier than you can + * destroy the `result` object itself. + * + * Multiple `result` objects can refer to the same set of underlying data. + * The underlying data will be deallocated once all `result` objects that + * refer to it are cleared or destroyed. + */ + void clear() noexcept + { + m_data.reset(); + m_query = nullptr; + } + + /** + * @name Column information + */ + //@{ + /// Number of columns in result. + [[nodiscard]] PQXX_PURE row_size_type columns() const noexcept; + + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] row_size_type column_number(zview name) const; + + /// Name of column with this number (throws exception if it doesn't exist) + [[nodiscard]] char const *column_name(row_size_type number) const &; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(row_size_type col_num) const; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(row_size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(row_size_type col_num) const; + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + /// Query that produced this result, if available (empty string otherwise) + [[nodiscard]] PQXX_PURE std::string const &query() const &noexcept; + + /// If command was an `INSERT` of 1 row, return oid of the inserted row. + /** @return Identifier of inserted row if exactly one row was inserted, or + * @ref oid_none otherwise. + */ + [[nodiscard]] PQXX_PURE oid inserted_oid() const; + + /// If command was `INSERT`, `UPDATE`, or `DELETE`: number of affected rows. + /** @return Number of affected rows if last command was `INSERT`, `UPDATE`, + * or `DELETE`; zero for all other commands. + */ + [[nodiscard]] PQXX_PURE size_type affected_rows() const; + + // C++20: Concept like std::invocable, but without specifying param types. + /// Run `func` on each row, passing the row's fields as parameters. + /** Goes through the rows from first to last. You provide a callable `func`. + * + * For each row in the `result`, `for_each` will call `func`. It converts + * the row's fields to the types of `func`'s parameters, and pass them to + * `func`. + * + * (Therefore `func` must have a _single_ signature. It can't be a generic + * lambda, or an object of a class with multiple overloaded function call + * operators. Otherwise, `for_each` will have no way to detect a parameter + * list without ambiguity.) + * + * If any of your parameter types is `std::string_view`, it refers to the + * underlying storage of this `result`. + * + * If any of your parameter types is a reference type, its argument will + * refer to a temporary value which only lives for the duration of that + * single invocation to `func`. If the reference is an lvalue reference, it + * must be `const`. + * + * For example, this queries employee names and salaries from the database + * and prints how much each would like to earn instead: + * ```cxx + * tx.exec("SELECT name, salary FROM employee").for_each( + * [](std::string_view name, float salary){ + * std::cout << name << " would like " << salary * 2 << ".\n"; + * }) + * ``` + * + * If `func` throws an exception, processing stops at that point and + * propagates the exception. + * + * @throws usage_error if `func`'s number of parameters does not match the + * number of columns in this result. + */ + template inline void for_each(CALLABLE &&func) const; + +private: + using data_pointer = std::shared_ptr; + + /// Underlying libpq result set. + data_pointer m_data; + + /// Factory for data_pointer. + static data_pointer + make_data_pointer(internal::pq::PGresult const *res = nullptr) noexcept + { + return {res, internal::clear_result}; + } + + friend class pqxx::internal::gate::result_pipeline; + PQXX_PURE std::shared_ptr query_ptr() const noexcept + { + return m_query; + } + + /// Query string. + std::shared_ptr m_query; + + internal::encoding_group m_encoding; + + static std::string const s_empty_string; + + friend class pqxx::field; + // TODO: noexcept. Breaks ABI. + PQXX_PURE char const *get_value(size_type row, row_size_type col) const; + // TODO: noexcept. Breaks ABI. + PQXX_PURE bool get_is_null(size_type row, row_size_type col) const; + PQXX_PURE + field_size_type get_length(size_type, row_size_type) const noexcept; + + friend class pqxx::internal::gate::result_creation; + result( + internal::pq::PGresult *rhs, std::shared_ptr query, + internal::encoding_group enc); + + PQXX_PRIVATE void check_status(std::string_view desc = ""sv) const; + + friend class pqxx::internal::gate::result_connection; + friend class pqxx::internal::gate::result_row; + bool operator!() const noexcept { return m_data.get() == nullptr; } + operator bool() const noexcept { return m_data.get() != nullptr; } + + [[noreturn]] PQXX_PRIVATE void + throw_sql_error(std::string const &Err, std::string const &Query) const; + PQXX_PRIVATE PQXX_PURE int errorposition() const; + PQXX_PRIVATE std::string status_error() const; + + friend class pqxx::internal::gate::result_sql_cursor; + PQXX_PURE char const *cmd_status() const noexcept; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction new file mode 100644 index 0000000..04b71d7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction @@ -0,0 +1,8 @@ +/** pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction.hxx new file mode 100644 index 0000000..faf6dbf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/robusttransaction.hxx @@ -0,0 +1,120 @@ +/* Definition of the pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/robusttransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROBUSTTRANSACTION +#define PQXX_H_ROBUSTTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref robusttransaction class template. +class PQXX_LIBEXPORT PQXX_NOVTABLE basic_robusttransaction + : public dbtransaction +{ +public: + virtual ~basic_robusttransaction() override = 0; + +protected: + basic_robusttransaction( + connection &c, zview begin_command, std::string_view tname); + basic_robusttransaction(connection &c, zview begin_command); + +private: + using IDType = unsigned long; + + std::string m_conn_string; + std::string m_xid; + int m_backendpid = -1; + + void init(zview begin_command); + + // @warning This function will become `final`. + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + * + * @{ + */ + +/// Slightly slower, better-fortified version of transaction. +/** Requires PostgreSQL 10 or better. + * + * robusttransaction is similar to transaction, but spends more time and effort + * to deal with the hopefully rare case that the connection to the backend is + * lost just while it's trying to commit. In such cases, the client does not + * know whether the backend (on the other side of the broken connection) + * managed to commit the transaction. + * + * When this happens, robusttransaction tries to reconnect to the database and + * figure out what happened. + * + * This service level was made optional since you may not want to pay the + * overhead where it is not necessary. Certainly the use of this class makes + * no sense for local connections, or for transactions that read the database + * but never modify it, or for noncritical database manipulations. + * + * Besides being slower, it's also more complex. Which means that in practice + * a robusttransaction could actually fail more instead of less often than a + * normal transaction. What robusttransaction tries to achieve is to give you + * certainty, not just be more successful per se. + */ +template +class robusttransaction final : public internal::basic_robusttransaction +{ +public: + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string_view tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + tname} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string &&tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + std::move(tname)} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + */ + explicit robusttransaction(connection &c) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd} + {} + + virtual ~robusttransaction() noexcept override { close(); } +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row new file mode 100644 index 0000000..62a950a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row @@ -0,0 +1,11 @@ +/** pqxx::row class. + * + * pqxx::row refers to a row in a result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row.hxx new file mode 100644 index 0000000..5be5132 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/row.hxx @@ -0,0 +1,561 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROW +#define PQXX_H_ROW + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/except.hxx" +#include "pqxx/field.hxx" +#include "pqxx/result.hxx" + +#include "pqxx/internal/concat.hxx" + +namespace pqxx::internal +{ +template class result_iter; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Reference to one row in a result. +/** A row represents one row (also called a row) in a query result set. + * It also acts as a container mapping column numbers or names to field + * values (see below): + * + * ```cxx + * cout << row["date"].c_str() << ": " << row["name"].c_str() << endl; + * ``` + * + * The row itself acts like a (non-modifyable) container, complete with its + * own const_iterator and const_reverse_iterator. + */ +class PQXX_LIBEXPORT row +{ +public: + using size_type = row_size_type; + using difference_type = row_difference_type; + using const_iterator = const_row_iterator; + using iterator = const_iterator; + using reference = field; + using pointer = const_row_iterator; + using const_reverse_iterator = const_reverse_row_iterator; + using reverse_iterator = const_reverse_iterator; + + row() noexcept = default; + row(row &&) noexcept = default; + row(row const &) noexcept = default; + row &operator=(row const &) noexcept = default; + row &operator=(row &&) noexcept = default; + + /** + * @name Comparison + */ + //@{ + [[nodiscard]] PQXX_PURE bool operator==(row const &) const noexcept; + [[nodiscard]] bool operator!=(row const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] const_iterator end() const noexcept; + [[nodiscard]] const_iterator cend() const noexcept; + + /** + * @name Field access + */ + //@{ + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rend() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crend() const; + + [[nodiscard]] reference operator[](size_type) const noexcept; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + [[nodiscard]] reference operator[](zview col_name) const; + + reference at(size_type) const; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + reference at(zview col_name) const; + + [[nodiscard]] constexpr size_type size() const noexcept + { + return m_end - m_begin; + } + + [[deprecated("Swap iterators, not rows.")]] void swap(row &) noexcept; + + /// Row number, assuming this is a real row and not end()/rend(). + [[nodiscard]] constexpr result::size_type rownumber() const noexcept + { + return m_index; + } + + /** + * @name Column information + */ + //@{ + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] size_type column_number(zview col_name) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(size_type) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column number in its table did this result column come from? + /** A meaningful answer can be given only if the column in question comes + * directly from a column in a table. If the column is computed in any + * other way, a logic_error will be thrown. + * + * @param col_num a zero-based column number in this result set + * @return a zero-based column number in originating table + */ + [[nodiscard]] size_type table_column(size_type) const; + + /// What column number in its table did this result column come from? + [[nodiscard]] size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + [[nodiscard]] constexpr result::size_type num() const noexcept + { + return rownumber(); + } + + /** Produce a slice of this row, containing the given range of columns. + * + * @deprecated I haven't heard of anyone caring about row slicing at all in + * at least the last 15 years. Yet it adds complexity, so unless anyone + * files a bug explaining why they really need this feature, I'm going to + * remove it. Even if they do, the feature may need an update. + * + * The slice runs from the range's starting column to the range's end + * column, exclusive. It looks just like a normal result row, except + * slices can be empty. + */ + [[deprecated("Row slicing is going away. File a bug if you need it.")]] row + slice(size_type sbegin, size_type send) const; + + /// Is this a row without fields? Can only happen to a slice. + [[nodiscard, deprecated("Row slicing is going away.")]] PQXX_PURE bool + empty() const noexcept; + + /// Extract entire row's values into a tuple. + /** Converts to the types of the tuple's respective fields. + */ + template void to(Tuple &t) const + { + check_size(std::tuple_size_v); + convert(t); + } + + template std::tuple as() const + { + check_size(sizeof...(TYPE)); + using seq = std::make_index_sequence; + return get_tuple>(seq{}); + } + +protected: + friend class const_row_iterator; + friend class result; + row(result const &r, result_size_type index, size_type cols) noexcept; + + /// Throw @ref usage_error if row size is not `expected`. + void check_size(size_type expected) const + { + if (size() != expected) + throw usage_error{internal::concat( + "Tried to extract ", expected, " field(s) from a row of ", size(), + ".")}; + } + + /// Convert to a given tuple of values, don't check sizes. + /** We need this for cases where we have a full tuple of field types, but + * not a parameter pack. + */ + template TUPLE as_tuple() const + { + using seq = std::make_index_sequence>; + return get_tuple(seq{}); + } + + template friend class pqxx::internal::result_iter; + /// Convert entire row to tuple fields, without checking row size. + template void convert(Tuple &t) const + { + extract_fields(t, std::make_index_sequence>{}); + } + + friend class field; + + /// Result set of which this is one row. + result m_result; + + /// Row number. + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + result::size_type m_index = 0; + + // TODO: Remove m_begin and (if possible) m_end when we remove slice(). + /// First column in slice. This row ignores lower-numbered columns. + size_type m_begin = 0; + /// End column in slice. This row only sees lower-numbered columns. + size_type m_end = 0; + +private: + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + template + void extract_value(Tuple &t) const; + + /// Convert row's values as a new tuple. + template + auto get_tuple(std::index_sequence) const + { + return std::make_tuple(get_field()...); + } + + /// Extract and convert a field. + template auto get_field() const + { + return (*this)[index].as>(); + } +}; + + +/// Iterator for fields in a row. Use as row::const_iterator. +class PQXX_LIBEXPORT const_row_iterator : public field +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = field const; + using pointer = field const *; + using size_type = row_size_type; + using difference_type = row_difference_type; + using reference = field; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + const_row_iterator() = default; +#include "pqxx/internal/ignore-deprecated-post.hxx" + const_row_iterator(row const &t, row_size_type c) noexcept : + field{t.m_result, t.m_index, c} + {} + const_row_iterator(field const &F) noexcept : field{F} {} + const_row_iterator(const_row_iterator const &) noexcept = default; + const_row_iterator(const_row_iterator &&) noexcept = default; + + /** + * @name Dereferencing operators + */ + //@{ + [[nodiscard]] constexpr pointer operator->() const noexcept { return this; } + [[nodiscard]] reference operator*() const noexcept { return {*this}; } + //@} + + /** + * @name Manipulations + */ + //@{ + const_row_iterator &operator=(const_row_iterator const &) noexcept = default; + const_row_iterator &operator=(const_row_iterator &&) noexcept = default; + + // TODO: noexcept. Breaks ABI. + const_row_iterator operator++(int); + const_row_iterator &operator++() noexcept + { + ++m_col; + return *this; + } + // TODO: noexcept. Breaks ABI. + const_row_iterator operator--(int); + const_row_iterator &operator--() noexcept + { + --m_col; + return *this; + } + + const_row_iterator &operator+=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) + i); + return *this; + } + const_row_iterator &operator-=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) - i); + return *this; + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] constexpr bool + operator==(const_row_iterator const &i) const noexcept + { + return col() == i.col(); + } + [[nodiscard]] constexpr bool + operator!=(const_row_iterator const &i) const noexcept + { + return col() != i.col(); + } + [[nodiscard]] constexpr bool + operator<(const_row_iterator const &i) const noexcept + { + return col() < i.col(); + } + [[nodiscard]] constexpr bool + operator<=(const_row_iterator const &i) const noexcept + { + return col() <= i.col(); + } + [[nodiscard]] constexpr bool + operator>(const_row_iterator const &i) const noexcept + { + return col() > i.col(); + } + [[nodiscard]] constexpr bool + operator>=(const_row_iterator const &i) const noexcept + { + return col() >= i.col(); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_row_iterator + operator+(difference_type) const noexcept; + + friend const_row_iterator + operator+(difference_type, const_row_iterator const &) noexcept; + + [[nodiscard]] inline const_row_iterator + operator-(difference_type) const noexcept; + [[nodiscard]] inline difference_type + operator-(const_row_iterator const &) const noexcept; + //@} +}; + + +/// Reverse iterator for a row. Use as row::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator +{ +public: + using super = const_row_iterator; + using iterator_type = const_row_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + const_reverse_row_iterator() noexcept = default; + const_reverse_row_iterator(const_reverse_row_iterator const &) noexcept = + default; + const_reverse_row_iterator(const_reverse_row_iterator &&) noexcept = default; + + explicit const_reverse_row_iterator(super const &rhs) noexcept : + const_row_iterator{rhs} + { + super::operator--(); + } + + [[nodiscard]] PQXX_PURE iterator_type base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + using iterator_type::operator->; + using iterator_type::operator*; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_row_iterator & + operator=(const_reverse_row_iterator const &r) noexcept + { + iterator_type::operator=(r); + return *this; + } + const_reverse_row_iterator operator++() noexcept + { + iterator_type::operator--(); + return *this; + } + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator operator++(int); + const_reverse_row_iterator &operator--() noexcept + { + iterator_type::operator++(); + return *this; + } + const_reverse_row_iterator operator--(int); + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator &operator+=(difference_type i) noexcept + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_row_iterator &operator-=(difference_type i) noexcept + { + iterator_type::operator+=(i); + return *this; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_row_iterator + operator+(difference_type i) const noexcept + { + return const_reverse_row_iterator{base() - i}; + } + [[nodiscard]] const_reverse_row_iterator + operator-(difference_type i) noexcept + { + return const_reverse_row_iterator{base() + i}; + } + [[nodiscard]] difference_type + operator-(const_reverse_row_iterator const &rhs) const noexcept + { + return rhs.const_row_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_row_iterator const &rhs) const noexcept + { + return !operator==(rhs); + } + + [[nodiscard]] constexpr bool + operator<(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] constexpr bool + operator<=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] constexpr bool + operator>(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] constexpr bool + operator>=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +const_row_iterator +const_row_iterator::operator+(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) + o)}; +} + +inline const_row_iterator operator+( + const_row_iterator::difference_type o, const_row_iterator const &i) noexcept +{ + return i + o; +} + +inline const_row_iterator +const_row_iterator::operator-(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) - o)}; +} + +inline const_row_iterator::difference_type +const_row_iterator::operator-(const_row_iterator const &i) const noexcept +{ + return difference_type(num() - i.num()); +} + + +template +inline void row::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + field const f{m_result, m_index, index}; + std::get(t) = from_string(f); +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list new file mode 100644 index 0000000..1bdf51c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list @@ -0,0 +1,6 @@ +/** Helper similar to Python's @c str.join(). + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list.hxx new file mode 100644 index 0000000..d4230ea --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/separated_list.hxx @@ -0,0 +1,142 @@ +/* Helper similar to Python's `str.join()`. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/separated_list instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SEPARATED_LIST +#define PQXX_H_SEPARATED_LIST + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/strconv.hxx" + +// C++20: Simplify using std::ranges::range. +// C++20: Optimise buffer allocation using random_access_range/iterator. +namespace pqxx +{ +/** + * @defgroup utility Utility functions + */ +//@{ + +/// Represent sequence of values as a string, joined by a given separator. +/** + * Use this to turn e.g. the numbers 1, 2, and 3 into a string "1, 2, 3". + * + * @param sep separator string (to be placed between items) + * @param begin beginning of items sequence + * @param end end of items sequence + * @param access functor defining how to dereference sequence elements + */ +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access) +{ + if (end == begin) + return {}; + auto next{begin}; + ++next; + if (next == end) + return to_string(access(begin)); + + // From here on, we've got at least 2 elements -- meaning that we need sep. + using elt_type = strip_t; + using traits = string_traits; + + std::size_t budget{0}; + for (ITER cnt{begin}; cnt != end; ++cnt) + budget += traits::size_buffer(access(cnt)); + budget += + static_cast(std::distance(begin, end)) * std::size(sep); + + std::string result; + result.resize(budget); + + char *const data{result.data()}; + char *here{data}; + char *stop{data + budget}; + here = traits::into_buf(here, stop, access(begin)) - 1; + for (++begin; begin != end; ++begin) + { + here += sep.copy(here, std::size(sep)); + here = traits::into_buf(here, stop, access(begin)) - 1; + } + result.resize(static_cast(here - data)); + return result; +} + + +/// Render sequence as a string, using given separator between items. +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end) +{ + return separated_list(sep, begin, end, [](ITER i) { return *i; }); +} + + +/// Render items in a container as a string, using given separator. +template +[[nodiscard]] inline auto +separated_list(std::string_view sep, CONTAINER const &c) + /* + Always std::string; necessary because SFINAE doesn't work with the + contents of function bodies, so the check for iterability has to be in + the signature. + */ + -> typename std::enable_if< + (not std::is_void::value and + not std::is_void::value), + std::string>::type +{ + return separated_list(sep, std::begin(c), std::end(c)); +} + + +/// Render items in a tuple as a string, using given separator. +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX == std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string separated_list( + std::string_view /* sep */, TUPLE const &t, ACCESS const &access) +{ + return to_string(access(&std::get(t))); +} + +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX < std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t, ACCESS const &access) +{ + std::string out{to_string(access(&std::get(t)))}; + out.append(sep); + out.append(separated_list(sep, t, access)); + return out; +} + +template< + typename TUPLE, std::size_t INDEX = 0, + typename std::enable_if< + (INDEX <= std::tuple_size::value), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t) +{ + // TODO: Optimise allocation. + return separated_list(sep, t, [](TUPLE const &tup) { return *tup; }); +} +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv new file mode 100644 index 0000000..aa2c40e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv @@ -0,0 +1,6 @@ +/** String conversion definitions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv.hxx new file mode 100644 index 0000000..8637112 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/strconv.hxx @@ -0,0 +1,468 @@ +/* String conversion definitions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STRCONV +#define PQXX_H_STRCONV + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +namespace pqxx::internal +{ +/// Attempt to demangle @c std::type_info::name() to something human-readable. +PQXX_LIBEXPORT std::string demangle_type_name(char const[]); +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @defgroup stringconversion String conversion + * + * The PostgreSQL server accepts and represents data in string form. It has + * its own formats for various data types. The string conversions define how + * various C++ types translate to and from their respective PostgreSQL text + * representations. + * + * Each conversion is defined by a specialisations of @c string_traits. It + * gets complicated if you want top performance, but until you do, all you + * really need to care about when converting values between C++ in-memory + * representations such as @c int and the postgres string representations is + * the @c pqxx::to_string and @c pqxx::from_string functions. + * + * If you need to convert a type which is not supported out of the box, you'll + * need to define your own specialisations for these templates, similar to the + * ones defined here and in `pqxx/conversions.hxx`. Any conversion code which + * "sees" your specialisation will now support your conversion. In particular, + * you'll be able to read result fields into a variable of the new type. + * + * There is a macro to help you define conversions for individual enumeration + * types. The conversion will represent enumeration values as numeric strings. + */ +//@{ + +/// A human-readable name for a type, used in error messages and such. +/** Actually this may not always be very user-friendly. It uses + * @c std::type_info::name(). On gcc-like compilers we try to demangle its + * output. Visual Studio produces human-friendly names out of the box. + * + * This variable is not inline. Inlining it gives rise to "memory leak" + * warnings from asan, the address sanitizer, possibly from use of + * @c std::type_info::name. + */ +template +std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())}; + + +/// Traits describing a type's "null value," if any. +/** Some C++ types have a special value or state which correspond directly to + * SQL's NULL. + * + * The @c nullness traits describe whether it exists, and whether a particular + * value is null. + */ +template struct nullness +{ + /// Does this type have a null value? + static bool has_null; + + /// Is this type always null? + static bool always_null; + + /// Is @c value a null? + static bool is_null(TYPE const &value); + + /// Return a null value. + /** Don't use this in generic code to compare a value and see whether it is + * null. Some types may have multiple null values which do not compare as + * equal, or may define a null value which is not equal to anything including + * itself, like in SQL. + */ + [[nodiscard]] static TYPE null(); +}; + + +/// Nullness traits describing a type which does not have a null value. +template struct no_null +{ + /// Does @c TYPE have a "built-in null value"? + /** For example, a pointer can equal @c nullptr, which makes a very natural + * representation of an SQL null value. For such types, the code sometimes + * needs to make special allowances. + * + * for most types, such as @c int or @c std::string, there is no built-in + * null. If you want to represent an SQL null value for such a type, you + * would have to wrap it in something that does have a null value. For + * example, you could use @c std::optional for "either an @c int or a + * null value." + */ + static constexpr bool has_null = false; + + /// Are all values of this type null? + /** There are a few special C++ types which are always null - mainly + * @c std::nullptr_t. + */ + static constexpr bool always_null = false; + + /// Does a given value correspond to an SQL null value? + /** Most C++ types, such as @c int or @c std::string, have no inherent null + * value. But some types such as C-style string pointers do have a natural + * equivalent to an SQL null. + */ + [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept + { + return false; + } +}; + + +/// Traits class for use in string conversions. +/** Specialize this template for a type for which you wish to add to_string + * and from_string support. + * + * String conversions are not meant to work for nulls. Check for null before + * converting a value of @c TYPE to a string, or vice versa. + */ +template struct string_traits +{ + /// Return a @c string_view representing value, plus terminating zero. + /** Produces a @c string_view containing the PostgreSQL string representation + * for @c value. + * + * Uses the space from @c begin to @c end as a buffer, if needed. The + * returned string may lie somewhere in that buffer, or it may be a + * compile-time constant, or it may be null if value was a null value. Even + * if the string is stored in the buffer, its @c begin() may or may not be + * the same as @c begin. + * + * The @c string_view is guaranteed to be valid as long as the buffer from + * @c begin to @c end remains accessible and unmodified. + * + * @throws pqxx::conversion_overrun if the provided buffer space may not be + * enough. For maximum performance, this is a conservative estimate. It may + * complain about a buffer which is actually large enough for your value, if + * an exact check gets too expensive. + */ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, TYPE const &value); + + /// Write value's string representation into buffer at @c begin. + /** Assumes that value is non-null. + * + * Writes value's string representation into the buffer, starting exactly at + * @c begin, and ensuring a trailing zero. Returns the address just beyond + * the trailing zero, so the caller could use it as the @c begin for another + * call to @c into_buf writing a next value. + */ + static inline char *into_buf(char *begin, char *end, TYPE const &value); + + /// Parse a string representation of a @c TYPE value. + /** Throws @c conversion_error if @c value does not meet the expected format + * for a value of this type. + */ + [[nodiscard]] static inline TYPE from_string(std::string_view text); + + // C++20: Can we make these all constexpr? + /// Estimate how much buffer space is needed to represent value. + /** The estimate may be a little pessimistic, if it saves time. + * + * The estimate includes the terminating zero. + */ + [[nodiscard]] static inline std::size_t + size_buffer(TYPE const &value) noexcept; +}; + + +/// Nullness: Enums do not have an inherent null value. +template +struct nullness>> : no_null +{}; +} // namespace pqxx + + +namespace pqxx::internal +{ +/// Helper class for defining enum conversions. +/** The conversion will convert enum values to numeric strings, and vice versa. + * + * To define a string conversion for an enum type, derive a @c string_traits + * specialisation for the enum from this struct. + * + * There's usually an easier way though: the @c PQXX_DECLARE_ENUM_CONVERSION + * macro. Use @c enum_traits manually only if you need to customise your + * traits type in more detail. + */ +template struct enum_traits +{ + using impl_type = std::underlying_type_t; + using impl_traits = string_traits; + + [[nodiscard]] static constexpr zview + to_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::to_buf(begin, end, to_underlying(value)); + } + + static constexpr char *into_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::into_buf(begin, end, to_underlying(value)); + } + + [[nodiscard]] static ENUM from_string(std::string_view text) + { + return static_cast(impl_traits::from_string(text)); + } + + [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept + { + return impl_traits::size_buffer(to_underlying(value)); + } + +private: + // C++23: Replace with std::to_underlying. + static constexpr impl_type to_underlying(ENUM const &value) noexcept + { + return static_cast(value); + } +}; +} // namespace pqxx::internal + + +/// Macro: Define a string conversion for an enum type. +/** This specialises the @c pqxx::string_traits template, so use it in the + * @c ::pqxx namespace. + * + * For example: + * + * #include + * #include + * enum X { xa, xb }; + * namespace pqxx { PQXX_DECLARE_ENUM_CONVERSION(x); } + * int main() { std::cout << pqxx::to_string(xa) << std::endl; } + */ +#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \ + template<> struct string_traits : pqxx::internal::enum_traits \ + {}; \ + template<> inline std::string const type_name { #ENUM } + + +namespace pqxx +{ +/// Parse a value in postgres' text format as a TYPE. +/** If the form of the value found in the string does not match the expected + * type, e.g. if a decimal point is found when converting to an integer type, + * the conversion fails. Overflows (e.g. converting "9999999999" to a 16-bit + * C++ type) are also treated as errors. If in some cases this behaviour + * should be inappropriate, convert to something bigger such as @c long @c int + * first and then truncate the resulting value. + * + * Only the simplest possible conversions are supported. Fancy features like + * hexadecimal or octal, spurious signs, or exponent notation won't work. + * Whitespace is not stripped away. Only the kinds of strings that come out of + * PostgreSQL and out of to_string() can be converted. + */ +template +[[nodiscard]] inline TYPE from_string(std::string_view text) +{ + return string_traits::from_string(text); +} + + +/// "Convert" a std::string_view to a std::string_view. +/** Just returns its input. + * + * @warning Of course the result is only valid for as long as the original + * string remains valid! Never access the string referenced by the return + * value after the original has been destroyed. + */ +template<> +[[nodiscard]] inline std::string_view from_string(std::string_view text) +{ + return text; +} + + +/// Attempt to convert postgres-generated string to given built-in object. +/** This is like the single-argument form of the function, except instead of + * returning the value, it sets @c value. + * + * You may find this more convenient in that it infers the type you want from + * the argument you pass. But there are disadvantages: it requires an + * assignment operator, and it may be less efficient. + */ +template inline void from_string(std::string_view text, T &value) +{ + value = from_string(text); +} + + +/// Convert a value to a readable string that PostgreSQL will understand. +/** The conversion does no special formatting, and ignores any locale settings. + * The resulting string will be human-readable and in a format suitable for use + * in SQL queries. It won't have niceties such as "thousands separators" + * though. + */ +template inline std::string to_string(TYPE const &value); + + +/// Convert multiple values to strings inside a single buffer. +/** There must be enough room for all values, or this will throw + * @c conversion_overrun. You can obtain a conservative estimate of the buffer + * space required by calling @c size_buffer() on the values. + * + * The @c std::string_view results may point into the buffer, so don't assume + * that they will remain valid after you destruct or move the buffer. + */ +template +[[nodiscard]] inline std::vector +to_buf(char *here, char const *end, TYPE... value) +{ + return {[&here, end](auto v) { + auto begin = here; + here = string_traits::into_buf(begin, end, v); + // Exclude the trailing zero out of the string_view. + auto len{static_cast(here - begin) - 1}; + return std::string_view{begin, len}; + }(value)...}; +} + +/// Convert a value to a readable string that PostgreSQL will understand. +/** This variant of to_string can sometimes save a bit of time in loops, by + * re-using a std::string for multiple conversions. + */ +template +inline void into_string(TYPE const &value, std::string &out); + + +/// Is @c value null? +template +[[nodiscard]] inline constexpr bool is_null(TYPE const &value) noexcept +{ + return nullness>::is_null(value); +} + + +/// Estimate how much buffer space is needed to represent values as a string. +/** The estimate may be a little pessimistic, if it saves time. It also + * includes room for a terminating zero after each value. + */ +template +[[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept +{ + return (string_traits>::size_buffer(value) + ...); +} + + +/// Does this type translate to an SQL array? +/** Specialisations may override this to be true for container types. + * + * This may not always be a black-and-white choice. For instance, a + * @c std::string is a container, but normally it translates to an SQL string, + * not an SQL array. + */ +template inline constexpr bool is_sql_array{false}; + + +/// Can we use this type in arrays and composite types without quoting them? +/** Define this as @c true only if values of @c TYPE can never contain any + * special characters that might need escaping or confuse the parsing of array + * or composite * types, such as commas, quotes, parentheses, braces, newlines, + * and so on. + * + * When converting a value of such a type to a string in an array or a field in + * a composite type, we do not need to add quotes, nor escape any special + * characters. + * + * This is just an optimisation, so it defaults to @c false to err on the side + * of slow correctness. + */ +template inline constexpr bool is_unquoted_safe{false}; + + +/// Element separator between SQL array elements of this type. +template inline constexpr char array_separator{','}; + + +/// What's the preferred format for passing non-null parameters of this type? +/** This affects how we pass parameters of @c TYPE when calling parameterised + * statements or prepared statements. + * + * Generally we pass parameters in text format, but binary strings are the + * exception. We also pass nulls in binary format, so this function need not + * handle null values. + */ +template inline constexpr format param_format(TYPE const &) +{ + return format::text; +} + + +/// Implement @c string_traits::to_buf by calling @c into_buf. +/** When you specialise @c string_traits for a new type, most of the time its + * @c to_buf implementation has no special optimisation tricks and just writes + * its text into the buffer it receives from the caller, starting at the + * beginning. + * + * In that common situation, you can implement @c to_buf as just a call to + * @c generic_to_buf. It will call @c into_buf and return the right result for + * @c to_buf. + */ +template +inline zview generic_to_buf(char *begin, char *end, TYPE const &value) +{ + using traits = string_traits; + // The trailing zero does not count towards the zview's size, so subtract 1 + // from the result we get from into_buf(). + if (is_null(value)) + return {}; + else + return {begin, traits::into_buf(begin, end, value) - begin - 1}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Binary string, akin to @c std::string for binary data. +/** Any type that satisfies this concept can represent an SQL BYTEA value. + * + * A @c binary has a @c begin(), @c end(), @c size(), and @data(). Each byte + * is a @c std::byte, and they must all be laid out contiguously in memory so + * we can reference them by a pointer. + */ +template +concept binary = std::ranges::contiguous_range and + std::is_same_v>, std::byte>; +#endif +//@} +} // namespace pqxx + + +#include "pqxx/internal/conversions.hxx" +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from new file mode 100644 index 0000000..9727624 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from @@ -0,0 +1,8 @@ +/** pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from.hxx new file mode 100644 index 0000000..ff4a93d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_from.hxx @@ -0,0 +1,361 @@ +/* Definition of the pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_from instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_FROM +#define PQXX_H_STREAM_FROM + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/stream_iterator.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_focus.hxx" + + +namespace pqxx +{ +class transaction_base; + + +/// Pass this to a `stream_from` constructor to stream table contents. +/** @deprecated Use @ref stream_from::table() instead. + */ +constexpr from_table_t from_table; +/// Pass this to a `stream_from` constructor to stream query results. +/** @deprecated Use stream_from::query() instead. + */ +constexpr from_query_t from_query; + + +/// Stream data from the database. +/** For larger data sets, retrieving data this way is likely to be faster than + * executing a query and then iterating and converting the rows fields. You + * will also be able to start processing before all of the data has come in. + * + * There are also downsides. Not all kinds of query will work in a stream. + * But straightforward `SELECT` and `UPDATE ... RETURNING` queries should work. + * This function makes use of @ref pqxx::stream_from, which in turn uses + * PostgreSQL's `COPY` command, so see the documentation for those to get the + * full details. + * + * There are other downsides. If there stream encounters an error, it may + * leave the entire connection in an unusable state, so you'll have to give the + * whole thing up. Finally, opening a stream puts the connection in a special + * state, so you won't be able to do many other things with the connection or + * the transaction while the stream is open. + * + * There are two ways of starting a stream: you stream either all rows in a + * table (using one of the factories, `table()` or `raw_table()`), or the + * results of a query (using the `query()` factory). + * + * Usually you'll want the `stream` convenience wrapper in + * @ref transaction_base, * so you don't need to deal with this class directly. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_from : transaction_focus +{ +public: + using raw_line = + std::pair>, std::size_t>; + + /// Factory: Execute query, and stream the results. + /** The query can be a SELECT query or a VALUES query; or it can be an + * UPDATE, INSERT, or DELETE with a RETURNING clause. + * + * The query is executed as part of a COPY statement, so there are additional + * restrictions on what kind of query you can use here. See the PostgreSQL + * documentation for the COPY command: + * + * https://www.postgresql.org/docs/current/sql-copy.html + */ + static stream_from query(transaction_base &tx, std::string_view q) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return {tx, from_query, q}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /** + * @name Streaming data from tables + * + * You can use `stream_from` to read a table's contents. This is a quick + * and easy way to read a table, but it comes with limitations. It cannot + * stream from a view, only from a table. It does not support conditions. + * And there are no guarantees about ordering. If you need any of those + * things, consider streaming from a query instead. + */ + //@{ + + /// Factory: Stream data from a pre-quoted table and columns. + /** Use this factory if you need to create multiple streams using the same + * table path and/or columns list, and you want to save a bit of work on + * composing the internal SQL statement for starting the stream. It lets you + * compose the string representations for the table path and the columns + * list, so you can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns which the stream will read. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will read all columns in the table, in schema order. + */ + static stream_from raw_table( + transaction_base &tx, std::string_view path, + std::string_view columns = ""sv); + + /// Factory: Stream data from a given table. + /** This is the convenient way to stream from a table. + */ + static stream_from table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}); + //@} + + /// Execute query, and stream over the results. + /** @deprecated Use factory function @ref query instead. + */ + [[deprecated("Use query() factory instead.")]] stream_from( + transaction_base &, from_query_t, std::string_view query); + + /// Stream all rows in table, all columns. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table); + + /// Stream given columns from all rows in table. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end); + + /// Stream given columns from all rows in table. + /** @deprecated Use factory function @ref query instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Columns const &columns); + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// @deprecated Use factories @ref table or @ref raw_table instead. + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table) : + stream_from{tx, from_table, table} + {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table, Columns const &columns) : + stream_from{tx, from_table, table, columns} + {} + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &, std::string_view table, Iter columns_begin, + Iter columns_end); + + ~stream_from() noexcept; + + /// May this stream still produce more data? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream produced all the data it is going to produce? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Finish this stream. Call this before continuing to use the connection. + /** Consumes all remaining lines, and closes the stream. + * + * This may take a while if you're abandoning the stream before it's done, so + * skip it in error scenarios where you're not planning to use the connection + * again afterwards. + */ + void complete(); + + /// Read one row into a tuple. + /** Converts the row's fields into the fields making up the tuple. + * + * For a column which can contain nulls, be sure to give the corresponding + * tuple field a type which can be null. For example, to read a field as + * `int` when it may contain nulls, read it as `std::optional`. + * Using `std::shared_ptr` or `std::unique_ptr` will also work. + */ + template stream_from &operator>>(Tuple &); + + /// Doing this with a `std::variant` is going to be horrifically borked. + template + stream_from &operator>>(std::variant &) = delete; + + /// Iterate over this stream. Supports range-based "for" loops. + /** Produces an input iterator over the stream. + * + * Do not call this yourself. Use it like "for (auto data : stream.iter())". + */ + template [[nodiscard]] auto iter() & + { + return pqxx::internal::stream_input_iteration{*this}; + } + + /// Read a row. Return fields as views, valid until you read the next row. + /** Returns `nullptr` when there are no more rows to read. Do not attempt + * to read any further rows after that. + * + * Do not access the vector, or the storage referenced by the views, after + * closing or completing the stream, or after attempting to read a next row. + * + * A @ref pqxx::zview is like a `std::string_view`, but with the added + * guarantee that if its data pointer is non-null, the string is followed by + * a terminating zero (which falls just outside the view itself). + * + * If any of the views' data pointer is null, that means that the + * corresponding SQL field is null. + * + * @warning The return type may change in the future, to support C++20 + * coroutine-based usage. + */ + std::vector const *read_row() &; + + /// Read a raw line of text from the COPY command. + /** @warning Do not use this unless you really know what you're doing. */ + raw_line get_raw_line(); + +private: + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &tx, std::string_view table, std::string_view columns, + from_table_t); + + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &, std::string_view unquoted_table, + std::string_view columns, from_table_t, int); + + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + pqxx::internal::glyph_scanner_func *m_glyph_scanner; + + /// Current row's fields' text, combined into one reusable string. + std::string m_row; + + /// The current row's fields. + std::vector m_fields; + + bool m_finished = false; + + void close(); + + template + void extract_value(Tuple &) const; + + /// Read a line of COPY data, write `m_row` and `m_fields`. + void parse_line(); +}; + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table_name, + Columns const &columns) : + stream_from{ + tx, from_table, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end) : + stream_from{ + tx, table, separated_list(",", columns_begin, columns_end), + from_table, 1} +{} + + +template inline stream_from &stream_from::operator>>(Tuple &t) +{ + if (m_finished) + return *this; + static constexpr auto tup_size{std::tuple_size_v}; + m_fields.reserve(tup_size); + parse_line(); + if (m_finished) + return *this; + + if (std::size(m_fields) != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", tup_size, " field(s) from a stream of ", + std::size(m_fields), ".")}; + + extract_fields(t, std::make_index_sequence{}); + return *this; +} + + +template +inline void stream_from::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + using nullity = nullness; + assert(index < std::size(m_fields)); + if constexpr (nullity::always_null) + { + if (std::data(m_fields[index]) != nullptr) + throw conversion_error{"Streaming non-null value into null field."}; + } + else if (std::data(m_fields[index]) == nullptr) + { + if constexpr (nullity::has_null) + std::get(t) = nullity::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + // Don't ever try to convert a non-null value to nullptr_t! + std::get(t) = from_string(m_fields[index]); + } +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to new file mode 100644 index 0000000..8760cf1 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to @@ -0,0 +1,8 @@ +/** pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to.hxx new file mode 100644 index 0000000..2a49d8f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/stream_to.hxx @@ -0,0 +1,455 @@ +/* Definition of the pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_to.hxx instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_TO +#define PQXX_H_STREAM_TO + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Efficiently write data directly to a database table. +/** If you wish to insert rows of data into a table, you can compose INSERT + * statements and execute them. But it's slow and tedious, and you need to + * worry about quoting and escaping the data. + * + * If you're just inserting a single row, it probably won't matter much. You + * can use prepared or parameterised statements to take care of the escaping + * for you. But if you're inserting large numbers of rows you will want + * something better. + * + * Inserting rows one by one using INSERT statements involves a lot of + * pointless overhead, especially when you are working with a remote database + * server over the network. You may end up sending each row over the network + * as a separate query, and waiting for a reply. Do it "in bulk" using + * `stream_to`, and you may find that it goes many times faster. Sometimes + * you gain orders of magnitude in speed. + * + * Here's how it works: you create a `stream_to` stream to start writing to + * your table. You will probably want to specify the columns. Then, you + * feed your data into the stream one row at a time. And finally, you call the + * stream's @ref complete function to tell it to finalise the operation, wait + * for completion, and check for errors. + * + * (You _must_ complete the stream before committing or aborting the + * transaction. The connection is in a special state while the stream is + * active, where it can't process commands, and can't commit or abort a + * transaction.) + * + * So how do you feed a row of data into the stream? There's several ways, but + * the preferred one is to call its @ref write_values. Pass the field values + * as arguments. Doesn't matter what type they are, as long as libpqxx knows + * how to convert them to PostgreSQL's text format: `int`, `std::string` or + * `std:string_view`, `float` and `double`, `bool`... lots of basic types + * are supported. If some of the values are null, feel free to use + * `std::optional`, `std::shared_ptr`, or `std::unique_ptr`. + * + * The arguments' types don't even have to match the fields' SQL types. If you + * want to insert an `int` into a `DECIMAL` column, that's your choice -- it + * will produce a `DECIMAL` value which happens to be integral. Insert a + * `float` into a `VARCHAR` column? That's fine, you'll get a string whose + * contents happen to read like a number. And so on. You can even insert + * different types of value in the same column on different rows. If you have + * a code path where a particular field is always null, just insert `nullptr`. + * + * There is another way to insert rows: the `<<` ("shift-left") operator. + * It's not as fast and it doesn't support variable arguments: each row must be + * either a `std::tuple` or something iterable, such as a `std::vector`, or + * anything else with a `begin()` and `end()`. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_to : transaction_focus +{ +public: + /// Stream data to a pre-quoted table and columns. + /** This factory can be useful when it's not convenient to provide the + * columns list in the form of a `std::initializer_list`, or when the list + * of columns is simply not known at compile time. + * + * Also use this if you need to create multiple streams using the same table + * path and/or columns list, and you want to save a bit of work on composing + * the internal SQL statement for starting the stream. It lets you compose + * the string representations for the table path and the columns list, so you + * can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns to which the stream will write. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will write all columns in the table, in schema order. + */ + static stream_to raw_table( + transaction_base &tx, std::string_view path, std::string_view columns = "") + { + return {tx, path, columns}; + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this to stream data to a table, where the list of columns is known at + * compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns Optionally, the columns to which the stream should write. + * If you do not pass this, the stream will write to all columns in the + * table, in schema order. + */ + static stream_to table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}) + { + auto const &conn{tx.conn()}; + return raw_table(tx, conn.quote_table(path), conn.quote_columns(columns)); + } + +#if defined(PQXX_HAVE_CONCEPTS) + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, table_path path, COLUMNS const &columns) + { + auto const &conn{tx.conn()}; + return stream_to::raw_table( + tx, conn.quote_table(path), tx.conn().quote_columns(columns)); + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, std::string_view path, COLUMNS const &columns) + { + return stream_to::raw_table(tx, path, tx.conn().quote_columns(columns)); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Create a stream, without specifying columns. + /** @deprecated Use @ref table or @ref raw_table as a factory. + * + * Fields will be inserted in whatever order the columns have in the + * database. + * + * You'll probably want to specify the columns, so that the mapping between + * your data fields and the table is explicit in your code, and not hidden + * in an "implicit contract" between your code and your schema. + */ + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &tx, std::string_view table_name) : + stream_to{tx, table_name, ""sv} + {} + + /// Create a stream, specifying column names as a container of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Columns const &columns); + + /// Create a stream, specifying column names as a sequence of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Iter columns_begin, + Iter columns_end); + + ~stream_to() noexcept; + + /// Does this stream still need to @ref complete()? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream been through its concluding @c complete()? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Complete the operation, and check for errors. + /** Always call this to close the stream in an orderly fashion, even after + * an error. (In the case of an error, abort the transaction afterwards.) + * + * The only circumstance where it's safe to skip this is after an error, if + * you're discarding the entire connection. + */ + void complete(); + + /// Insert a row of data. + /** Returns a reference to the stream, so you can chain the calls. + * + * The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * If you don't already happen to have your fields in the form of a tuple or + * container, prefer @c write_values. It's faster and more convenient. + */ + template stream_to &operator<<(Row const &row) + { + write_row(row); + return *this; + } + + /// Stream a `stream_from` straight into a `stream_to`. + /** This can be useful when copying between different databases. If the + * source and the destination are on the same database, you'll get better + * performance doing it all in a regular query. + */ + stream_to &operator<<(stream_from &); + + /// Insert a row of data, given in the form of a @c std::tuple or container. + /** The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * The preferred way to insert a row is @c write_values. + */ + template void write_row(Row const &row) + { + fill_buffer(row); + write_buffer(); + } + + /// Insert values as a row. + /** This is the recommended way of inserting data. Pass your field values, + * of any convertible type. + */ + template void write_values(Ts const &...fields) + { + fill_buffer(fields...); + write_buffer(); + } + +private: + /// Stream a pre-quoted table name and columns list. + stream_to( + transaction_base &tx, std::string_view path, std::string_view columns); + + bool m_finished = false; + + /// Reusable buffer for a row. Saves doing an allocation for each row. + std::string m_buffer; + + /// Reusable buffer for converting/escaping a field. + std::string m_field_buf; + + /// Glyph scanner, for parsing the client encoding. + internal::glyph_scanner_func *m_scanner; + + /// Write a row of raw text-format data into the destination table. + void write_raw_line(std::string_view); + + /// Write a row of data from @c m_buffer into the destination table. + /** Resets the buffer for the next row. + */ + void write_buffer(); + + /// COPY encoding for a null field, plus subsequent separator. + static constexpr std::string_view null_field{"\\N\t"}; + + /// Estimate buffer space needed for a field which is always null. + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &) + { + return std::size(null_field); + } + + /// Estimate buffer space needed for field f. + /** The estimate is not very precise. We don't actually know how much space + * we'll need once the escaping comes in. + */ + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &field) + { + return is_null(field) ? std::size(null_field) : size_buffer(field); + } + + /// Append escaped version of @c data to @c m_buffer, plus a tab. + void escape_field_to_buffer(std::string_view data); + + /// Append string representation for @c f to @c m_buffer. + /** This is for the general case, where the field may contain a value. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &f) + { + // We append each field, terminated by a tab. That will leave us with + // one tab too many, assuming we write any fields at all; we remove that + // at the end. + if (is_null(f)) + { + // Easy. Append null and tab in one go. + m_buffer.append(null_field); + } + else + { + // Convert f into m_buffer. + + using traits = string_traits; + auto const budget{estimate_buffer(f)}; + auto const offset{std::size(m_buffer)}; + + if constexpr (std::is_arithmetic_v) + { + // Specially optimised for "safe" types, which never need any + // escaping. Convert straight into m_buffer. + + // The budget we get from size_buffer() includes room for the trailing + // zero, which we must remove. But we're also inserting tabs between + // fields, so we re-purpose the extra byte for that. + auto const total{offset + budget}; + m_buffer.resize(total); + auto const data{m_buffer.data()}; + char *const end{traits::into_buf(data + offset, data + total, f)}; + *(end - 1) = '\t'; + // Shrink to fit. Keep the tab though. + m_buffer.resize(static_cast(end - data)); + } + else if constexpr ( + std::is_same_v or + std::is_same_v or + std::is_same_v) + { + // This string may need escaping. + m_field_buf.resize(budget); + escape_field_to_buffer(f); + } + else + { + // This field needs to be converted to a string, and after that, + // escaped as well. + m_field_buf.resize(budget); + auto const data{m_field_buf.data()}; + escape_field_to_buffer( + traits::to_buf(data, data + std::size(m_field_buf), f)); + } + } + } + + /// Append string representation for a null field to @c m_buffer. + /** This special case is for types which are always null. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &) + { + m_buffer.append(null_field); + } + + /// Write raw COPY line into @c m_buffer, based on a container of fields. + template + std::enable_if_t> + fill_buffer(Container const &c) + { + // To avoid unnecessary allocations and deallocations, we run through c + // twice: once to determine how much buffer space we may need, and once to + // actually write it into the buffer. + std::size_t budget{0}; + for (auto const &f : c) budget += estimate_buffer(f); + m_buffer.reserve(budget); + for (auto const &f : c) append_to_buffer(f); + } + + /// Estimate how many buffer bytes we need to write tuple. + template + static std::size_t + budget_tuple(Tuple const &t, std::index_sequence) + { + return (estimate_buffer(std::get(t)) + ...); + } + + /// Write tuple of fields to @c m_buffer. + template + void append_tuple(Tuple const &t, std::index_sequence) + { + (append_to_buffer(std::get(t)), ...); + } + + /// Write raw COPY line into @c m_buffer, based on a tuple of fields. + template void fill_buffer(std::tuple const &t) + { + using indexes = std::make_index_sequence; + + m_buffer.reserve(budget_tuple(t, indexes{})); + append_tuple(t, indexes{}); + } + + /// Write raw COPY line into @c m_buffer, based on varargs fields. + template void fill_buffer(const Ts &...fields) + { + (..., append_to_buffer(fields)); + } + + constexpr static std::string_view s_classname{"stream_to"}; +}; + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Columns const &columns) : + stream_to{tx, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Iter columns_begin, + Iter columns_end) : + stream_to{ + tx, + tx.quote_name( + table_name, + separated_list(",", columns_begin, columns_end, [&tx](auto col) { + return tx.quote_name(*col); + }))} +{} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction new file mode 100644 index 0000000..e0d1549 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction @@ -0,0 +1,8 @@ +/** pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one inside a transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction.hxx new file mode 100644 index 0000000..e66b7a7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/subtransaction.hxx @@ -0,0 +1,96 @@ +/* Definition of the pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one within a transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/subtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SUBTRANSACTION +#define PQXX_H_SUBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx +{ +/** + * @ingroup transactions + */ +/// "Transaction" nested within another transaction +/** A subtransaction can be executed inside a backend transaction, or inside + * another subtransaction. This can be useful when, for example, statements in + * a transaction may harmlessly fail and you don't want them to abort the + * entire transaction. Here's an example of how a temporary table may be + * dropped before re-creating it, without failing if the table did not exist: + * + * ```cxx + * void do_job(connection &C) + * { + * string const temptable = "fleetingtable"; + * + * work W(C, "do_job"); + * do_firstpart(W); + * + * // Attempt to delete our temporary table if it already existed. + * try + * { + * subtransaction S(W, "droptemp"); + * S.exec0("DROP TABLE " + temptable); + * S.commit(); + * } + * catch (undefined_table const &) + * { + * // Table did not exist. Which is what we were hoping to achieve anyway. + * // Carry on without regrets. + * } + * + * // S may have gone into a failed state and been destroyed, but the + * // upper-level transaction W is still fine. We can continue to use it. + * W.exec0("CREATE TEMP TABLE " + temptable + "(bar integer, splat + * varchar)"); + * + * do_lastpart(W); + * } + * ``` + * + * (This is just an example. If you really wanted to do drop a table without + * an error if it doesn't exist, you'd use DROP TABLE IF EXISTS.) + * + * There are no isolation levels inside a transaction. They are not needed + * because all actions within the same backend transaction are always performed + * sequentially anyway. + * + * @warning While the subtransaction is "live," you cannot execute queries or + * open streams etc. on its parent transaction. A transaction can have at most + * one object of a type derived from @ref pqxx::transaction_focus active on it + * at a time. + */ +class PQXX_LIBEXPORT subtransaction : public transaction_focus, + public dbtransaction +{ +public: + /// Nest a subtransaction nested in another transaction. + explicit subtransaction(dbtransaction &t, std::string_view tname = ""sv); + + /// Nest a subtransaction in another subtransaction. + explicit subtransaction(subtransaction &t, std::string_view name = ""sv); + + virtual ~subtransaction() noexcept override; + +private: + std::string quoted_name() const + { + return quote_name(transaction_focus::name()); + } + virtual void do_commit() override; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time new file mode 100644 index 0000000..85df057 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time @@ -0,0 +1,6 @@ +/** Date/time string conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/time.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time.hxx new file mode 100644 index 0000000..effed05 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/time.hxx @@ -0,0 +1,88 @@ +/** Support for date/time values. + * + * At the moment this supports dates, but not times. + */ +#ifndef PQXX_H_TIME +#define PQXX_H_TIME + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/strconv.hxx" + + +#if defined(PQXX_HAVE_YEAR_MONTH_DAY) + +namespace pqxx +{ +using namespace std::literals; + +template<> +struct nullness + : no_null +{}; + + +/// String representation for a Gregorian date in ISO-8601 format. +/** @warning Experimental. There may still be design problems, particularly + * when it comes to BC years. + * + * PostgreSQL supports a choice of date formats, but libpqxx does not. The + * other formats in turn support a choice of "month before day" versus "day + * before month," meaning that it's not necessarily known which format a given + * date is supposed to be. So I repeat: ISO-8601-style format only! + * + * Invalid dates will not convert. This includes February 29 on non-leap + * years, which is why it matters that `year_month_day` represents a + * _Gregorian_ date. + * + * The range of years is limited. At the time of writing, PostgreSQL 14 + * supports years from 4713 BC to 294276 AD inclusive, and C++20 supports + * a range of 32767 BC to 32767 AD inclusive. So in practice, years must fall + * between 4713 BC and 32767 AD, inclusive. + * + * @warning Support for BC (or BCE) years is still experimental. I still need + * confirmation on this issue: it looks as if C++ years are astronomical years, + * which means they have a Year Zero. Regular BC/AD years do not have a year + * zero, so the year 1 AD follows directly after 1 BC. + * + * So, what to our calendars (and to PostgreSQL) is the year "0001 BC" seems to + * count as year "0" in a `std::chrono::year_month_day`. The year 0001 AD is + * still equal to 1 as you'd expect, and all AD years work normally, but all + * years before then are shifted by one. For instance, the year 543 BC would + * be -542 in C++. + */ +template<> struct PQXX_LIBEXPORT string_traits +{ + [[nodiscard]] static zview + to_buf(char *begin, char *end, std::chrono::year_month_day const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::chrono::year_month_day const &value); + + [[nodiscard]] static std::chrono::year_month_day + from_string(std::string_view text); + + [[nodiscard]] static std::size_t + size_buffer(std::chrono::year_month_day const &) noexcept + { + static_assert(int{(std::chrono::year::min)()} >= -99999); + static_assert(int{(std::chrono::year::max)()} <= 99999); + return 5 + 1 + 2 + 1 + 2 + std::size(s_bc) + 1; + } + +private: + /// The "BC" suffix for years before 1 AD. + static constexpr std::string_view s_bc{" BC"sv}; +}; +} // namespace pqxx +#endif // PQXX_HAVE_YEAR_MONTH_DAY +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction new file mode 100644 index 0000000..a7ae39d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction @@ -0,0 +1,8 @@ +/** pqxx::transaction class. + * + * pqxx::transaction represents a standard database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction.hxx new file mode 100644 index 0000000..e90917e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction.hxx @@ -0,0 +1,108 @@ +/* Definition of the pqxx::transaction class. + * pqxx::transaction represents a standard database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION +#define PQXX_H_TRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref transaction class template. +class PQXX_LIBEXPORT basic_transaction : public dbtransaction +{ +protected: + basic_transaction( + connection &c, zview begin_command, std::string_view tname); + basic_transaction(connection &c, zview begin_command, std::string &&tname); + basic_transaction(connection &c, zview begin_command); + + virtual ~basic_transaction() noexcept override = 0; + +private: + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + */ +//@{ + +/// Standard back-end transaction, templatised on isolation level. +/** This is the type you'll normally want to use to represent a transaction on + * the database. + * + * Usage example: double all wages. + * + * ```cxx + * extern connection C; + * work T(C); + * try + * { + * T.exec0("UPDATE employees SET wage=wage*2"); + * T.commit(); // NOTE: do this inside try block + * } + * catch (exception const &e) + * { + * cerr << e.what() << endl; + * T.abort(); // Usually not needed; same happens when T's life ends. + * } + * ``` + */ +template< + isolation_level ISOLATION = isolation_level::read_committed, + write_policy READWRITE = write_policy::read_write> +class transaction final : public internal::basic_transaction +{ +public: + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * @param tname Optional name for transaction. Must begin with a letter and + * may contain letters and digits only. + */ + transaction(connection &c, std::string_view tname) : + internal::basic_transaction{ + c, internal::begin_cmd, tname} + {} + + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * may contain letters and digits only. + */ + explicit transaction(connection &c) : + internal::basic_transaction{ + c, internal::begin_cmd} + {} + + virtual ~transaction() noexcept override { close(); } +}; + + +/// The default transaction type. +using work = transaction<>; + +/// Read-only transaction. +using read_transaction = + transaction; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base new file mode 100644 index 0000000..c39219a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base @@ -0,0 +1,9 @@ +/** Base for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction_base.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base.hxx new file mode 100644 index 0000000..4363cc5 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_base.hxx @@ -0,0 +1,810 @@ +/* Common code and definitions for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_BASE +#define PQXX_H_TRANSACTION_BASE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +/* End-user programs need not include this file, unless they define their own + * transaction classes. This is not something the typical program should want + * to do. + * + * However, reading this file is worthwhile because it defines the public + * interface for the available transaction classes such as transaction and + * nontransaction. + */ + +#include "pqxx/connection.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/util.hxx" + +namespace pqxx::internal::gate +{ +class transaction_subtransaction; +class transaction_sql_cursor; +class transaction_stream_to; +class transaction_transaction_focus; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +using namespace std::literals; + + +class transaction_focus; + + +/** + * @defgroup transactions Transaction classes + * + * All database access goes through instances of these classes. + * However, not all implementations of this interface need to provide full + * transactional integrity. + * + * Several implementations of this interface are shipped with libpqxx, + * including the plain transaction class, the entirely unprotected + * nontransaction, and the more cautious robusttransaction. + */ + +/// Interface definition (and common code) for "transaction" classes. +/** + * @ingroup transactions + * + * Abstract base class for all transaction types. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base +{ +public: + transaction_base() = delete; + transaction_base(transaction_base const &) = delete; + transaction_base(transaction_base &&) = delete; + transaction_base &operator=(transaction_base const &) = delete; + transaction_base &operator=(transaction_base &&) = delete; + + virtual ~transaction_base() = 0; + + /// Commit the transaction. + /** Make the effects of this transaction definite. If you destroy a + * transaction without invoking its @ref commit() first, that will implicitly + * abort it. (For the @ref nontransaction class though, "commit" and "abort" + * really don't do anything, hence its name.) + * + * There is, however, a minute risk that you might lose your connection to + * the database at just the wrong moment here. In that case, libpqxx may be + * unable to determine whether the database was able to complete the + * transaction, or had to roll it back. In that scenario, @ref commit() will + * throw an in_doubt_error. There is a different transaction class called + * @ref robusttransaction which takes some special precautions to reduce this + * risk. + */ + void commit(); + + /// Abort the transaction. + /** No special effort is required to call this function; it will be called + * implicitly when the transaction is destructed. + */ + void abort(); + + /** + * @ingroup escaping-functions + * + * Use these when writing SQL queries that incorporate C++ values as SQL + * constants. + * + * The functions you see here are just convenience shortcuts to the same + * functions on the connection object. + */ + //@{ + /// Escape string for use as SQL string literal in this transaction. + template [[nodiscard]] auto esc(ARGS &&...args) const + { + return conn().esc(std::forward(args)...); + } + + /// Escape binary data for use as SQL string literal in this transaction. + /** Raw, binary data is treated differently from regular strings. Binary + * strings are never interpreted as text, so they may safely include byte + * values or byte sequences that don't happen to represent valid characters + * in the character encoding being used. + * + * The binary string does not stop at the first zero byte, as is the case + * with textual strings. Instead, it may contain zero bytes anywhere. If + * it happens to contain bytes that look like quote characters, or other + * things that can disrupt their use in SQL queries, they will be replaced + * with special escape sequences. + */ + template [[nodiscard]] auto esc_raw(ARGS &&...args) const + { + return conn().esc_raw(std::forward(args)...); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(zview text) + { + return conn().unesc_bin(text); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const *text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(char const text[]) + { + return conn().unesc_bin(text); + } + + /// Represent object as SQL string, including quoting & escaping. + /** Nulls are recognized and represented as SQL nulls. */ + template [[nodiscard]] std::string quote(T const &t) const + { + return conn().quote(t); + } + + [[deprecated( + "Use std::basic_string instead of binarystring.")]] std::string + quote(binarystring const &t) const + { + return conn().quote(t.bytes_view()); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const + { + return quote(binary_cast(bin, len)); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(zview bin) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Binary-escape and quote a binary string for use as an SQL constant. + /** For binary data you can also just use @ref quote(data). */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return conn().quote_raw(data); + } +#endif + + /// Escape an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const + { + return conn().quote_name(identifier); + } + + /// Escape string for literal LIKE match. + [[nodiscard]] std::string + esc_like(std::string_view bin, char escape_char = '\\') const + { + return conn().esc_like(bin, escape_char); + } + //@} + + /** + * @name Command execution + * + * There are many functions for executing (or "performing") a command (or + * "query"). This is the most fundamental thing you can do with the library, + * and you always do it from a transaction class. + * + * Command execution can throw many types of exception, including sql_error, + * broken_connection, and many sql_error subtypes such as + * feature_not_supported or insufficient_privilege. But any exception thrown + * by the C++ standard library may also occur here. All exceptions you will + * see libpqxx throw are derived from std::exception. + * + * One unusual feature in libpqxx is that you can give your query a name or + * description. This does not mean anything to the database, but sometimes + * it can help libpqxx produce more helpful error messages, making problems + * in your code easier to debug. + * + * Many of the execution functions used to accept a `desc` argument, a + * human-readable description of the statement for use in error messages. + * This could make failures easier to debug. Future versions will use + * C++20's `std::source_location` to identify the failing statement. + */ + //@{ + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated("The desc parameter is going away.")]] result + exec(std::string_view query, std::string_view desc); + + /// Execute a command. + /** + * @param query Query or command to execute. + * @return A result set describing the query's or command's result. + */ + result exec(std::string_view query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated( + "Pass your query as a std::string_view, not stringstream.")]] result + exec(std::stringstream const &query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query.str(), desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec0(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(0, query, desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec0(zview query) { return exec_n(0, query); } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] row + exec1(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(1, query, desc).front(); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + row exec1(zview query) { return exec_n(1, query).front(); } + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec_n(result::size_type rows, zview query, std::string_view desc); + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec_n(result::size_type rows, zview query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(rows, query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template + [[deprecated("The desc parameter is going away.")]] TYPE + query_value(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row const r{exec1(query, desc)}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template TYPE query_value(zview query) + { + row const r{exec1(query)}; + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Execute a query, and loop over the results row by row. + /** Converts the rows to `std::tuple`, of the column types you specify. + * + * Use this with a range-based "for" loop. It executes the query, and + * directly maps the resulting rows onto a `std::tuple` of the types you + * specify. It starts before all the data from the server is in, so if your + * network connection to the server breaks while you're iterating, you'll get + * an exception partway through. + * + * The stream lives entirely within the lifetime of the transaction. Make + * sure you destroy the stream before you destroy the transaction. Either + * iterate the stream all the way to the end, or destroy first the stream + * and then the transaction without touching either in any other way. Until + * the stream has finished, the transaction is in a special state where it + * cannot execute queries. + * + * As a special case, tuple may contain `std::string_view` fields, but the + * strings to which they point will only remain valid until you extract the + * next row. After that, the memory holding the string may be overwritten or + * deallocated. + * + * If any of the columns can be null, and the C++ type to which it translates + * does not have a null value, wrap the type in `std::optional` (or if + * you prefer, `std::shared_ptr` or `std::unique_ptr)`. These templates + * do recognise null values, and libpqxx will know how to convert to them. + * + * The connection is in a special state until the iteration finishes. So if + * it does not finish due to a `break` or a `return` or an exception, then + * the entire connection becomes effectively unusable. + * + * Querying in this way is faster than the `exec()` methods for larger + * results (but slower for small ones). You can start processing rows before + * the full result is in. Also, `stream()` scales better in terms of memory + * usage. Where @ref exec() reads the entire result into memory at once, + * `stream()` will read and process one row at at a time. + * + * Your query executes as part of a COPY command, not as a stand-alone query, + * so there are limitations to what you can do in the query. It can be + * either a SELECT or VALUES query; or an INSERT, UPDATE, or DELETE with a + * RETURNING clause. See the documentation for PostgreSQL's COPY command for + * the details: + * + * https://www.postgresql.org/docs/current/sql-copy.html + * + * Iterating in this way does require each of the field types you pass to be + * default-constructible, copy-constructible, and assignable. These + * requirements may be loosened once libpqxx moves on to C++20. + */ + template + [[nodiscard]] auto stream(std::string_view query) & + { + // Tricky: std::make_unique() supports constructors but not RVO functions. + return pqxx::internal::owning_stream_input_iteration{ + std::unique_ptr{ + new stream_from{stream_from::query(*this, query)}}}; + } + + // C++20: Concept like std::invocable, but without specifying param types. + /// Perform a streaming query, and for each result row, call `func`. + /** Here, `func` can be a function, a `std::function`, a lambda, or an + * object that supports the function call operator. Of course `func` must + * have an unambiguous signature; it can't be overloaded or generic. + * + * The `for_each` function executes `query` in a stream using + * @ref pqxx::stream_from. Every time a row of data comes in from the + * server, it converts the row's fields to the types of `func`'s respective + * parameters, and calls `func` with those values. + * + * This will not work for all queries, but straightforward `SELECT` and + * `UPDATE ... RETURNING` queries should work. Consult the documentation for + * @ref pqxx::stream_from and PostgreSQL's underlying `COPY` command for the + * full details. + * + * Streaming a query like this is likely to be slower than the @ref exec() + * functions for small result sets, but faster for large result sets. So if + * performance matters, you'll want to use `for_each` if you query large + * amounts of data, but not if you do lots of queries with small outputs. + */ + template + inline auto for_each(std::string_view query, CALLABLE &&func) + { + using param_types = + pqxx::internal::strip_types_t>; + param_types const *const sample{nullptr}; + auto data_stream{stream_like(query, sample)}; + for (auto const &fields : data_stream) std::apply(func, fields); + } + + /** + * @name Parameterized statements + * + * You'll often need parameters in the queries you execute: "select the + * car with this licence plate." If the parameter is a string, you need to + * quote it and escape any special characters inside it, or it may become a + * target for an SQL injection attack. If it's an integer (for example), + * you need to convert it to a string, but in the database's format, without + * locale-specific niceties like "," separators between the thousands. + * + * Parameterised statements are an easier and safer way to do this. They're + * like prepared statements, but for a single use. You don't need to name + * them, and you don't need to prepare them first. + * + * Your query will include placeholders like `$1` and `$2` etc. in the places + * where you want the arguments to go. Then, you pass the argument values + * and the actual query is constructed for you. + * + * Pass the exact right number of parameters, and in the right order. The + * parameters in the query don't have to be neatly ordered from `$1` to + * `$2` to `$3` - but you must pass the argument for `$1` first, the one + * for `$2` second, etc. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. + */ + //@{ + /// Execute an SQL statement with parameters. + template result exec_params(zview query, Args &&...args) + { + params pp(args...); + return internal_exec_params(query, pp.make_c_params()); + } + + // Execute parameterised statement, expect a single-row result. + /** @throw unexpected_rows if the result does not consist of exactly one row. + */ + template row exec_params1(zview query, Args &&...args) + { + return exec_params_n(1, query, std::forward(args)...).front(); + } + + // Execute parameterised statement, expect a result with zero rows. + /** @throw unexpected_rows if the result contains rows. + */ + template result exec_params0(zview query, Args &&...args) + { + return exec_params_n(0, query, std::forward(args)...); + } + + // Execute parameterised statement, expect exactly a given number of rows. + /** @throw unexpected_rows if the result contains the wrong number of rows. + */ + template + result exec_params_n(std::size_t rows, zview query, Args &&...args) + { + auto const r{exec_params(query, std::forward(args)...)}; + check_rowcount_params(rows, std::size(r)); + return r; + } + //@} + + /** + * @name Prepared statements + * + * These are very similar to parameterised statements. The difference is + * that you prepare them in advance, giving them identifying names. You can + * then call them by these names, passing in the argument values appropriate + * for that call. + * + * You prepare a statement on the connection, using + * @ref pqxx::connection::prepare(). But you then call the statement in a + * transaction, using the functions you see here. + * + * Never try to prepare, execute, or unprepare a prepared statement manually + * using direct SQL queries when you also use the libpqxx equivalents. For + * any given statement, either prepare, manage, and execute it through the + * dedicated libpqxx functions; or do it all directly in SQL. Don't mix the + * two, or the code may get confused. + * + * See \ref prepared for a full discussion. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. If you need a zero byte, you're dealing with binary strings, not + * regular strings. Represent binary strings on the SQL side as `BYTEA` + * (or as large objects). On the C++ side, use types like + * `std::basic_string` or `std::basic_string_view` + * or (in C++20) `std::vector`. Also, consider large objects on + * the SQL side and @ref blob on the C++ side. + */ + //@{ + + /// Execute a prepared statement, with optional arguments. + template + result exec_prepared(zview statement, Args &&...args) + { + params pp(args...); + return internal_exec_prepared(statement, pp.make_c_params()); + } + + /// Execute a prepared statement, and expect a single-row result. + /** @throw pqxx::unexpected_rows if the result was not exactly 1 row. + */ + template + row exec_prepared1(zview statement, Args &&...args) + { + return exec_prepared_n(1, statement, std::forward(args)...).front(); + } + + /// Execute a prepared statement, and expect a result with zero rows. + /** @throw pqxx::unexpected_rows if the result contained rows. + */ + template + result exec_prepared0(zview statement, Args &&...args) + { + return exec_prepared_n(0, statement, std::forward(args)...); + } + + /// Execute a prepared statement, expect a result with given number of rows. + /** @throw pqxx::unexpected_rows if the result did not contain exactly the + * given number of rows. + */ + template + result + exec_prepared_n(result::size_type rows, zview statement, Args &&...args) + { + auto const r{exec_prepared(statement, std::forward(args)...)}; + check_rowcount_prepared(statement, rows, std::size(r)); + return r; + } + + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Have connection process a warning message. + void process_notice(char const msg[]) const { m_conn.process_notice(msg); } + /// Have connection process a warning message. + void process_notice(zview msg) const { m_conn.process_notice(msg); } + //@} + + /// The connection in which this transaction lives. + [[nodiscard]] constexpr connection &conn() const noexcept { return m_conn; } + + /// Set session variable using SQL "SET" command. + /** @deprecated To set a transaction-local variable, execute an SQL `SET` + * command. To set a session variable, use the connection's + * @ref set_session_var function. + * + * @warning When setting a string value, you must make sure that the string + * is "safe." If you call @ref quote() on the string, it will return a + * safely escaped and quoted version for use as an SQL literal. + * + * @warning This function executes SQL. Do not try to set or get variables + * while a pipeline or table stream is active. + * + * @param var The variable to set. + * @param value The new value to store in the variable. This can be any SQL + * expression. + */ + [[deprecated( + "Set transaction-local variables using SQL SET statements.")]] void + set_variable(std::string_view var, std::string_view value); + + /// Read session variable using SQL "SHOW" command. + /** @warning This executes SQL. Do not try to set or get variables while a + * pipeline or table stream is active. + */ + [[deprecated("Read variables using SQL SHOW statements.")]] std::string + get_variable(std::string_view); + + // C++20: constexpr. + /// Transaction name, if you passed one to the constructor; or empty string. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + +protected: + /// Create a transaction (to be called by implementation classes only). + /** The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + m_conn{c}, m_name{tname}, m_rollback_cmd{rollback_cmd} + {} + + /// Create a transaction (to be called by implementation classes only). + /** Its rollback command will be "ROLLBACK". + * + * The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base(connection &c, std::string_view tname); + + /// Create a transaction (to be called by implementation classes only). + explicit transaction_base(connection &c); + + /// Register this transaction with the connection. + void register_transaction(); + + /// End transaction. To be called by implementing class' destructor. + void close() noexcept; + + /// To be implemented by derived implementation class: commit transaction. + virtual void do_commit() = 0; + + /// Transaction type-specific way of aborting a transaction. + /** @warning This will become "final", since this function can be called + * from the implementing class destructor. + */ + virtual void do_abort(); + + /// Set the rollback command. + void set_rollback_cmd(std::shared_ptr cmd) + { + m_rollback_cmd = cmd; + } + + /// Execute query on connection directly. + result direct_exec(std::string_view, std::string_view desc = ""sv); + result + direct_exec(std::shared_ptr, std::string_view desc = ""sv); + +private: + enum class status + { + active, + aborted, + committed, + in_doubt + }; + + PQXX_PRIVATE void check_pending_error(); + + result + internal_exec_prepared(zview statement, internal::c_params const &args); + + result internal_exec_params(zview query, internal::c_params const &args); + + /// Throw unexpected_rows if prepared statement returned wrong no. of rows. + void check_rowcount_prepared( + zview statement, result::size_type expected_rows, + result::size_type actual_rows); + + /// Throw unexpected_rows if wrong row count from parameterised statement. + void + check_rowcount_params(std::size_t expected_rows, std::size_t actual_rows); + + /// Describe this transaction to humans, e.g. "transaction 'foo'". + [[nodiscard]] std::string description() const; + + friend class pqxx::internal::gate::transaction_transaction_focus; + PQXX_PRIVATE void register_focus(transaction_focus *); + PQXX_PRIVATE void unregister_focus(transaction_focus *) noexcept; + PQXX_PRIVATE void register_pending_error(zview) noexcept; + PQXX_PRIVATE void register_pending_error(std::string &&) noexcept; + + /// Like @ref stream(), but takes a tuple rather than a parameter pack. + template + auto stream_like(std::string_view query, std::tuple const *) + { + return stream(query); + } + + connection &m_conn; + + /// Current "focus": a pipeline, a nested transaction, a stream... + /** This pointer is used for only one purpose: sanity checks against mistakes + * such as opening one while another is still active. + */ + transaction_focus const *m_focus = nullptr; + + status m_status = status::active; + bool m_registered = false; + std::string m_name; + std::string m_pending_error; + + /// SQL command for aborting this type of transaction. + std::shared_ptr m_rollback_cmd; + + static constexpr std::string_view s_type_name{"transaction"sv}; +}; + + +// C++20: Can borrowed_range help? +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +std::string_view transaction_base::query_value( + zview query, std::string_view desc) = delete; +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +zview transaction_base::query_value( + zview query, std::string_view desc) = delete; + +} // namespace pqxx + + +namespace pqxx::internal +{ +/// The SQL command for starting a given type of transaction. +template +extern const zview begin_cmd; + +// These are not static members, so "constexpr" does not imply "inline". +template<> +inline constexpr zview begin_cmd{ + "BEGIN"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY"_zv}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus new file mode 100644 index 0000000..fe78a9b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus @@ -0,0 +1,7 @@ +/** + * Transaction focus: types which monopolise a transaction's attention. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus.hxx new file mode 100644 index 0000000..0707e3c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transaction_focus.hxx @@ -0,0 +1,89 @@ +/** Transaction focus: types which monopolise a transaction's attention. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_FOCUS +#define PQXX_H_TRANSACTION_FOCUS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Base class for things that monopolise a transaction's attention. +/** You probably won't need to use this class. But it can be useful to _know_ + * that a given libpqxx class is derived from it. + * + * Pipelines, SQL statements, and data streams are examples of classes derived + * from `transaction_focus`. For any given transaction, only one object of + * such a class can be active at any given time. + */ +class PQXX_LIBEXPORT transaction_focus +{ +public: + transaction_focus( + transaction_base &t, std::string_view cname, std::string_view oname) : + m_trans{t}, m_classname{cname}, m_name{oname} + {} + + transaction_focus( + transaction_base &t, std::string_view cname, std::string &&oname) : + m_trans{t}, m_classname{cname}, m_name{std::move(oname)} + {} + + transaction_focus(transaction_base &t, std::string_view cname) : + m_trans{t}, m_classname{cname} + {} + + transaction_focus() = delete; + transaction_focus(transaction_focus const &) = delete; + transaction_focus &operator=(transaction_focus const &) = delete; + + /// Class name, for human consumption. + [[nodiscard]] constexpr std::string_view classname() const noexcept + { + return m_classname; + } + + /// Name for this object, if the caller passed one; empty string otherwise. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + + [[nodiscard]] std::string description() const + { + return pqxx::internal::describe_object(m_classname, m_name); + } + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus(transaction_focus &&) = delete; + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus &operator=(transaction_focus &&) = delete; + +protected: + void register_me(); + void unregister_me() noexcept; + void reg_pending_error(std::string const &) noexcept; + bool registered() const noexcept { return m_registered; } + + transaction_base &m_trans; + +private: + bool m_registered = false; + std::string_view m_classname; + std::string m_name; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor new file mode 100644 index 0000000..29d1b96 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor @@ -0,0 +1,8 @@ +/** pqxx::transactor class. + * + * pqxx::transactor is a framework-style wrapper for safe transactions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transactor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor.hxx new file mode 100644 index 0000000..eefd04b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/transactor.hxx @@ -0,0 +1,147 @@ +/* Transactor framework, a wrapper for safely retryable transactions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTOR +#define PQXX_H_TRANSACTOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +/** + * @defgroup transactor Transactor framework + * + * Sometimes a transaction can fail for completely transient reasons, such as a + * conflict with another transaction in SERIALIZABLE isolation. The right way + * to handle those failures is often just to re-run the transaction from + * scratch. + * + * For example, your REST API might be handling each HTTP request in its own + * database transaction, and if this kind of transient failure happens, you + * simply want to "replay" the whole request, in a fresh transaction. + * + * You won't necessarily want to execute the exact same SQL commands with the + * exact same data. Some of your SQL statements may depend on state that can + * vary between retries. Data in the database may already have changed, for + * instance. So instead of dumbly replaying the SQL, you re-run the same + * application code that produced those SQL commands, from the start. + * + * The transactor framework makes it a little easier for you to do this safely, + * and avoid typical pitfalls. You encapsulate the work that you want to do + * into a callable that you pass to the @ref perform function. + * + * Here's how it works. You write your transaction code as a lambda or + * function, which creates its own transaction object, does its work, and + * commits at the end. You pass that callback to @ref pqxx::perform, which + * runs it for you. + * + * If there's a failure inside your callback, there will be an exception. Your + * transaction object goes out of scope and gets destroyed, so that it aborts + * implicitly. Seeing this, @ref perform tries running your callback again. It + * stops doing that when the callback succeeds, or when it has failed too many + * times, or when there's an error that leaves the database in an unknown + * state, such as a lost connection just while we're waiting for the database + * to confirm a commit. It all depends on the type of exception. + * + * The callback takes no arguments. If you're using lambdas, the easy way to + * pass arguments is for the lambda to "capture" them from your variables. Or, + * if you're using functions, you may want to use `std::bind`. + * + * Once your callback succeeds, it can return a result, and @ref perform will + * return that result back to you. + */ +//@{ + +/// Simple way to execute a transaction with automatic retry. +/** + * Executes your transaction code as a callback. Repeats it until it completes + * normally, or it throws an error other than the few libpqxx-generated + * exceptions that the framework understands, or after a given number of failed + * attempts, or if the transaction ends in an "in-doubt" state. + * + * (An in-doubt state is one where libpqxx cannot determine whether the server + * finally committed a transaction or not. This can happen if the network + * connection to the server is lost just while we're waiting for its reply to + * a "commit" statement. The server may have completed the commit, or not, but + * it can't tell you because there's no longer a connection. + * + * Using this still takes a bit of care. If your callback makes use of data + * from the database, you'll probably have to query that data within your + * callback. If the attempt to perform your callback fails, and the framework + * tries again, you'll be in a new transaction and the data in the database may + * have changed under your feet. + * + * Also be careful about changing variables or data structures from within + * your callback. The run may still fail, and perhaps get run again. The + * ideal way to do it (in most cases) is to return your result from your + * callback, and change your program's data state only after @ref perform + * completes successfully. + * + * @param callback Transaction code that can be called with no arguments. + * @param attempts Maximum number of times to attempt performing callback. + * Must be greater than zero. + * @return Whatever your callback returns. + */ +template +inline auto perform(TRANSACTION_CALLBACK &&callback, int attempts = 3) + -> std::invoke_result_t +{ + if (attempts <= 0) + throw std::invalid_argument{ + "Zero or negative number of attempts passed to pqxx::perform()."}; + + for (; attempts > 0; --attempts) + { + try + { + return std::invoke(callback); + } + catch (in_doubt_error const &) + { + // Not sure whether transaction went through or not. The last thing in + // the world that we should do now is try again! + throw; + } + catch (statement_completion_unknown const &) + { + // Not sure whether our last statement succeeded. Don't risk running it + // again. + throw; + } + catch (broken_connection const &) + { + // Connection failed. May be worth retrying, if the transactor opens its + // own connection. + if (attempts <= 1) + throw; + continue; + } + catch (transaction_rollback const &) + { + // Some error that may well be transient, such as serialization failure + // or deadlock. Worth retrying. + if (attempts <= 1) + throw; + continue; + } + } + throw pqxx::internal_error{"No outcome reached on perform()."}; +} +} // namespace pqxx +//@} +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types new file mode 100644 index 0000000..23a5caa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types @@ -0,0 +1,7 @@ +/** + * Basic typedefs and forward declarations. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types.hxx new file mode 100644 index 0000000..f95b598 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/types.hxx @@ -0,0 +1,173 @@ +/* Basic type aliases and forward declarations. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TYPES +#define PQXX_H_TYPES + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + + +namespace pqxx +{ +/// Number of rows in a result set. +using result_size_type = int; + +/// Difference between result sizes. +using result_difference_type = int; + +/// Number of fields in a row of database data. +using row_size_type = int; + +/// Difference between row sizes. +using row_difference_type = int; + +/// Number of bytes in a field of database data. +using field_size_type = std::size_t; + +/// Number of bytes in a large object. +using large_object_size_type = int64_t; + + +// Forward declarations, to help break compilation dependencies. +// These won't necessarily include all classes in libpqxx. +class binarystring; +class connection; +class const_result_iterator; +class const_reverse_result_iterator; +class const_reverse_row_iterator; +class const_row_iterator; +class dbtransaction; +class field; +class largeobjectaccess; +class notification_receiver; +struct range_error; +class result; +class row; +class stream_from; +class transaction_base; + +/// Marker for @ref stream_from constructors: "stream from table." +/** @deprecated Use @ref stream_from::table() instead. + */ +struct from_table_t +{}; + +/// Marker for @ref stream_from constructors: "stream from query." +/** @deprecated Use @ref stream_from::query() instead. + */ +struct from_query_t +{}; + + +/// Format code: is data text or binary? +/** Binary-compatible with libpq's format codes. + */ +enum class format : int +{ + text = 0, + binary = 1, +}; + + +/// Remove any constness, volatile, and reference-ness from a type. +/** @deprecated In C++20 we'll replace this with std::remove_cvref. + */ +template +using strip_t = std::remove_cv_t>; + + +#if defined(PQXX_HAVE_CONCEPTS) +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#else // PQXX_HAVE_CONCEPTS +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#endif // PQXX_HAVE_CONCEPTS + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Any type that we can read as a string of `char`. +template +concept char_string = std::ranges::contiguous_range and + std::same_as < strip_t>, +char > ; + +/// Concept: Anything we can iterate to get things we can read as strings. +template +concept char_strings = + std::ranges::range and char_string>>; + +/// Concept: Anything we might want to treat as binary data. +template +concept potential_binary = std::ranges::contiguous_range and + (sizeof(value_type) == 1); +#endif // PQXX_HAVE_CONCEPTS + + +// C++20: Retire these compatibility definitions. +#if defined(PQXX_HAVE_CONCEPTS) + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG std::ranges::range + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG pqxx::char_string + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG pqxx::char_strings + +#else // PQXX_HAVE_CONCEPTS + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG typename + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG typename + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG typename + +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util new file mode 100644 index 0000000..6d85ab6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util @@ -0,0 +1,6 @@ +/** Various utility definitions for libpqxx. + */ +// Actual definitions in .hxx file so editors and such recognize file type +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/util.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util.hxx new file mode 100644 index 0000000..4aa5ecf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/util.hxx @@ -0,0 +1,521 @@ +/* Various utility definitions for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_UTIL +#define PQXX_H_UTIL + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/internal/encodings.hxx" +#include "pqxx/types.hxx" +#include "pqxx/version.hxx" + + +/// The home of all libpqxx classes, functions, templates, etc. +namespace pqxx +{} + +#include + + +/// Internal items for libpqxx' own use. Do not use these yourself. +namespace pqxx::internal +{ + +// C++20: Retire wrapper. +/// Same as `std::cmp_less`, or a workaround where that's not available. +template +inline constexpr bool cmp_less(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less(lhs, rhs); +#else + // We need a variable just because lgtm.com gives off a false positive + // warning when we compare the values directly. It considers that a + // "self-comparison." + constexpr bool left_signed{std::is_signed_v}; + if constexpr (left_signed == std::is_signed_v) + return lhs < rhs; + else if constexpr (std::is_signed_v) + return (lhs <= 0) ? true : (std::make_unsigned_t(lhs) < rhs); + else + return (rhs <= 0) ? false : (lhs < std::make_unsigned_t(rhs)); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater, or workaround if not available. +template +inline constexpr bool cmp_greater(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater(lhs, rhs); +#else + return cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_less_equal, or workaround if not available. +template +inline constexpr bool cmp_less_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less_equal(lhs, rhs); +#else + return not cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater_equal, or workaround if not available. +template +inline constexpr bool cmp_greater_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater_equal(lhs, rhs); +#else + return not cmp_less(lhs, rhs); +#endif +} + + +/// Efficiently concatenate two strings. +/** This is a special case of concatenate(), needed because dependency + * management does not let us use that function here. + */ +[[nodiscard]] inline std::string cat2(std::string_view x, std::string_view y) +{ + std::string buf; + auto const xs{std::size(x)}, ys{std::size(y)}; + buf.resize(xs + ys); + x.copy(std::data(buf), xs); + y.copy(std::data(buf) + xs, ys); + return buf; +} +} // namespace pqxx::internal + + +namespace pqxx +{ +using namespace std::literals; + +/// Suppress compiler warning about an unused item. +template inline constexpr void ignore_unused(T &&...) noexcept +{} + + +/// Cast a numeric value to another type, or throw if it underflows/overflows. +/** Both types must be arithmetic types, and they must either be both integral + * or both floating-point types. + */ +template +inline TO check_cast(FROM value, std::string_view description) +{ + static_assert(std::is_arithmetic_v); + static_assert(std::is_arithmetic_v); + static_assert(std::is_integral_v == std::is_integral_v); + + // The rest of this code won't quite work for bool, but bool is trivially + // convertible to other arithmetic types as far as I can see. + if constexpr (std::is_same_v) + return static_cast(value); + + // Depending on our "if constexpr" conditions, this parameter may not be + // needed. Some compilers will warn. + ignore_unused(description); + + using from_limits = std::numeric_limits; + using to_limits = std::numeric_limits; + if constexpr (std::is_signed_v) + { + if constexpr (std::is_signed_v) + { + if (value < to_limits::lowest()) + throw range_error{internal::cat2("Cast underflow: "sv, description)}; + } + else + { + // FROM is signed, but TO is not. Treat this as a special case, because + // there may not be a good broader type in which the compiler can even + // perform our check. + if (value < 0) + throw range_error{internal::cat2( + "Casting negative value to unsigned type: "sv, description)}; + } + } + else + { + // No need to check: the value is unsigned so can't fall below the range + // of the TO type. + } + + if constexpr (std::is_integral_v) + { + using unsigned_from = std::make_unsigned_t; + using unsigned_to = std::make_unsigned_t; + constexpr auto from_max{static_cast((from_limits::max)())}; + constexpr auto to_max{static_cast((to_limits::max)())}; + if constexpr (from_max > to_max) + { + if (internal::cmp_greater(value, to_max)) + throw range_error{internal::cat2("Cast overflow: "sv, description)}; + } + } + else if constexpr ((from_limits::max)() > (to_limits::max)()) + { + if (value > (to_limits::max)()) + throw range_error{internal::cat2("Cast overflow: ", description)}; + } + + return static_cast(value); +} + + +/** Check library version at link time. + * + * Ensures a failure when linking an application against a radically + * different libpqxx version than the one against which it was compiled. + * + * Sometimes application builds fail in unclear ways because they compile + * using headers from libpqxx version X, but then link against libpqxx + * binary version Y. A typical scenario would be one where you're building + * against a libpqxx which you have built yourself, but a different version + * is installed on the system. + * + * The check_library_version template is declared for any library version, + * but only actually defined for the version of the libpqxx binary against + * which the code is linked. + * + * If the library binary is a different version than the one declared in + * these headers, then this call will fail to link: there will be no + * definition for the function with these exact template parameter values. + * There will be a definition, but the version in the parameter values will + * be different. + */ +inline PQXX_PRIVATE void check_version() noexcept +{ + // There is no particular reason to do this here in @ref connection, except + // to ensure that every meaningful libpqxx client will execute it. The call + // must be in the execution path somewhere or the compiler won't try to link + // it. We can't use it to initialise a global or class-static variable, + // because a smart compiler might resolve it at compile time. + // + // On the other hand, we don't want to make a useless function call too + // often for performance reasons. A local static variable is initialised + // only on the definition's first execution. Compilers will be well + // optimised for this behaviour, so there's a minimal one-time cost. + static auto const version_ok{internal::PQXX_VERSION_CHECK()}; + ignore_unused(version_ok); +} + + +/// Descriptor of library's thread-safety model. +/** This describes what the library knows about various risks to thread-safety. + */ +struct PQXX_LIBEXPORT thread_safety_model +{ + /// Is the underlying libpq build thread-safe? + bool safe_libpq = false; + + /// Is Kerberos thread-safe? + /** @warning Is currently always `false`. + * + * If your application uses Kerberos, all accesses to libpqxx or Kerberos + * must be serialized. Confine their use to a single thread, or protect it + * with a global lock. + */ + bool safe_kerberos = false; + + /// A human-readable description of any thread-safety issues. + std::string description; +}; + + +/// Describe thread safety available in this build. +[[nodiscard]] PQXX_LIBEXPORT thread_safety_model describe_thread_safety(); + + +#if defined(PQXX_HAVE_CONCEPTS) +# define PQXX_POTENTIAL_BINARY_ARG pqxx::potential_binary +#else +# define PQXX_POTENTIAL_BINARY_ARG typename +#endif + + +/// Cast binary data to a type that libpqxx will recognise as binary. +/** There are many different formats for storing binary data in memory. You + * may have yours as a `std::string`, or a `std::vector`, or one of + * many other types. + * + * But for libpqxx to recognise your data as binary, it needs to be a + * `std::basic_string`, or a `std::basic_string_view`; + * or in C++20 or better, any contiguous block of `std::byte`. + * + * Use `binary_cast` as a convenience helper to cast your data as a + * `std::basic_string_view`. + * + * @warning There are two things you should be aware of! First, the data must + * be contiguous in memory. In C++20 the compiler will enforce this, but in + * C++17 it's your own problem. Second, you must keep the object where you + * store the actual data alive for as long as you might use this function's + * return value. + */ +template +std::basic_string_view binary_cast(TYPE const &data) +{ + static_assert(sizeof(value_type) == 1); + return { + reinterpret_cast( + const_cast const *>( + std::data(data))), + std::size(data)}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +concept char_sized = (sizeof(CHAR) == 1); +# define PQXX_CHAR_SIZED_ARG char_sized +#else +# define PQXX_CHAR_SIZED_ARG typename +#endif + +/// Construct a type that libpqxx will recognise as binary. +/** Takes a data pointer and a size, without being too strict about their + * types, and constructs a `std::basic_string_view` pointing to + * the same data. + * + * This makes it a little easier to turn binary data, in whatever form you + * happen to have it, into binary data as libpqxx understands it. + */ +template +std::basic_string_view binary_cast(CHAR const *data, SIZE size) +{ + static_assert(sizeof(CHAR) == 1); + return { + reinterpret_cast(data), + check_cast(size, "binary data size")}; +} + + +/// The "null" oid. +constexpr oid oid_none{0}; +} // namespace pqxx + + +/// Private namespace for libpqxx's internal use; do not access. +/** This namespace hides definitions internal to libpqxx. These are not + * supposed to be used by client programs, and they may change at any time + * without notice. + * + * Conversely, if you find something in this namespace tremendously useful, by + * all means do lodge a request for its publication. + * + * @warning Here be dragons! + */ +namespace pqxx::internal +{ +using namespace std::literals; + + +/// A safer and more generic replacement for `std::isdigit`. +/** Turns out `std::isdigit` isn't as easy to use as it sounds. It takes an + * `int`, but requires it to be nonnegative. Which means it's an outright + * liability on systems where `char` is signed. + */ +template inline constexpr bool is_digit(CHAR c) noexcept +{ + return (c >= '0') and (c <= '9'); +} + + +/// Describe an object for humans, based on class name and optional name. +/** Interprets an empty name as "no name given." + */ +[[nodiscard]] std::string +describe_object(std::string_view class_name, std::string_view name); + + +/// Check validity of registering a new "guest" in a "host." +/** The host might be e.g. a connection, and the guest a transaction. The + * host can only have one guest at a time, so it is an error to register a new + * guest while the host already has a guest. + * + * If the new registration is an error, this function throws a descriptive + * exception. + * + * Pass the old guest (if any) and the new guest (if any), for both, a type + * name (at least if the guest is not null), and optionally an object name + * (but which may be omitted if the caller did not assign one). + */ +void check_unique_register( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Like @ref check_unique_register, but for un-registering a guest. +/** Pass the guest which was registered, as well as the guest which is being + * unregistered, so that the function can check that they are the same one. + */ +void check_unique_unregister( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Compute buffer size needed to escape binary data for use as a BYTEA. +/** This uses the hex-escaping format. The return value includes room for the + * "\x" prefix. + */ +inline constexpr std::size_t size_esc_bin(std::size_t binary_bytes) noexcept +{ + return 2 + (2 * binary_bytes) + 1; +} + + +/// Compute binary size from the size of its escaped version. +/** Do not include a terminating zero in `escaped_bytes`. + */ +inline constexpr std::size_t size_unesc_bin(std::size_t escaped_bytes) noexcept +{ + return (escaped_bytes - 2) / 2; +} + + +// TODO: Use actual binary type for "data". +/// Hex-escape binary data into a buffer. +/** The buffer must be able to accommodate + * `size_esc_bin(std::size(binary_data))` bytes, and the function will write + * exactly that number of bytes into the buffer. This includes a trailing + * zero. + */ +void PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data, char buffer[]) noexcept; + + +/// Hex-escape binary data into a std::string. +std::string PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data); + + +/// Reconstitute binary data from its escaped version. +void PQXX_LIBEXPORT +unesc_bin(std::string_view escaped_data, std::byte buffer[]); + + +/// Reconstitute binary data from its escaped version. +std::basic_string + PQXX_LIBEXPORT unesc_bin(std::string_view escaped_data); + + +/// Transitional: std::ssize(), or custom implementation if not available. +template auto ssize(T const &c) +{ +#if defined(__cpp_lib_ssize) && __cplusplus >= __cpp_lib_ssize + return std::ssize(c); +#else + using signed_t = std::make_signed_t; + return static_cast(std::size(c)); +#endif // __cpp_lib_ssize +} + + +/// Helper for determining a function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(RETURN (&func)(ARGS...)); + + +/// Helper for determining a `std::function`'s parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(std::function const &); + + +/// Helper for determining a member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...)); + + +/// Helper for determining a const member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...) const); + + +/// Helper for determining a callable type's parameter types. +/** This specialisation should work for lambdas. + * + * This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +auto args_f(CALLABLE const &f) + -> decltype(member_args_f(&CALLABLE::operator())); + + +/// A callable's parameter types, as a tuple. +template +using args_t = decltype(args_f(std::declval())); + + +/// Helper: Apply `strip_t` to each of a tuple type's component types. +/** This function has no definition. It is not meant to be called, only to be + * used to deduce the right types. + */ +template +std::tuple...> strip_types(std::tuple const &); + + +/// Take a tuple type and apply @ref strip_t to its component types. +template +using strip_types_t = decltype(strip_types(std::declval())); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version new file mode 100644 index 0000000..8dd5e48 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version @@ -0,0 +1,7 @@ +/** libpqxx version info. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/version.hxx" +#include "pqxx/internal/header-post.hxx" + diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version.hxx new file mode 100644 index 0000000..a159f1b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/version.hxx @@ -0,0 +1,55 @@ +/* Version info for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_VERSION + +# if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +# endif + +/// Full libpqxx version string. +# define PQXX_VERSION "7.7.3" +/// Library ABI version. +# define PQXX_ABI "7.7" + +/// Major version number. +# define PQXX_VERSION_MAJOR 7 +/// Minor version number. +# define PQXX_VERSION_MINOR 7 + +# define PQXX_VERSION_CHECK check_pqxx_version_7_7 + +namespace pqxx::internal +{ +/// Library version check stub. +/** Helps detect version mismatches between libpqxx headers and the libpqxx + * library binary. + * + * Sometimes users run into trouble linking their code against libpqxx because + * they build their own libpqxx, but the system also has a different version + * installed. The declarations in the headers against which they compile their + * code will differ from the ones used to build the libpqxx version they're + * using, leading to confusing link errors. The solution is to generate a link + * error when the libpqxx binary is not the same version as the libpqxx headers + * used to compile the code. + * + * This function's definition is in the libpqxx binary, so it's based on the + * version as found in the binary. The headers contain a call to the function, + * whose name contains the libpqxx version as found in the headers. (The + * library build process will use its own local headers even if another version + * of the headers is installed on the system.) + * + * If the libpqxx binary was compiled for a different version than the user's + * code, linking will fail with an error: `check_pqxx_version_*_*` will not + * exist for the given version number. + */ +PQXX_LIBEXPORT int PQXX_VERSION_CHECK() noexcept; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview new file mode 100644 index 0000000..66ea2a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview @@ -0,0 +1,6 @@ +/** Zero-terminated string view class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/zview.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview.hxx new file mode 100644 index 0000000..36a779f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/include/pqxx/zview.hxx @@ -0,0 +1,163 @@ +/* Zero-terminated string view. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/zview instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ZVIEW +#define PQXX_H_ZVIEW + +#include +#include +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// Marker-type wrapper: zero-terminated `std::string_view`. +/** @warning Use this only if the underlying string is zero-terminated. + * + * When you construct a zview, you are promising that if the data pointer is + * non-null, the underlying string is zero-terminated. It otherwise behaves + * exactly like a std::string_view. + * + * The terminating zero is not "in" the string, so it does not count as part of + * the view's length. + * + * The added guarantee lets the view be used as a C-style string, which often + * matters since libpqxx builds on top of a C library. For this reason, zview + * also adds a @ref c_str method. + */ +class zview : public std::string_view +{ +public: + constexpr zview() noexcept = default; + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char const text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Explicitly promote a `string_view` to a `zview`. + explicit constexpr zview(std::string_view other) noexcept : + std::string_view{other} + {} + + /// Construct from any initialiser you might use for `std::string_view`. + /** @warning Only do this if you are sure that the string is zero-terminated. + */ + template + explicit constexpr zview(Args &&...args) : + std::string_view(std::forward(args)...) + {} + + // C++20: constexpr. + /// @warning There's an implicit conversion from `std::string`. + zview(std::string const &str) noexcept : + std::string_view{str.c_str(), str.size()} + {} + + /// Construct a `zview` from a C-style string. + /** @warning This scans the string to discover its length. So if you need to + * do it many times, it's probably better to create the `zview` once and + * re-use it. + */ + constexpr zview(char const str[]) : std::string_view{str} {} + + /// Construct a `zview` from a string literal. + /** A C++ string literal ("foo") normally looks a lot like a pointer to + * char const, but that's not really true. It's actually an array of char, + * which _devolves_ to a pointer when you pass it. + * + * For the purpose of creating a `zview` there is one big difference: if we + * know the array's size, we don't need to scan through the string in order + * to find out its length. + */ + template + constexpr zview(char const (&literal)[size]) : zview(literal, size - 1) + {} + + /// Either a null pointer, or a zero-terminated text buffer. + [[nodiscard]] constexpr char const *c_str() const &noexcept + { + return data(); + } +}; + + +/// Support @ref zview literals. +/** You can "import" this selectively into your namespace, without pulling in + * all of the @ref pqxx namespace: + * + * ```cxx + * using pqxx::operator"" _zv; + * ``` + */ +constexpr zview operator"" _zv(char const str[], std::size_t len) noexcept +{ + return zview{str, len}; +} +} // namespace pqxx + + +#if defined(PQXX_HAVE_CONCEPTS) +/// A zview is a view. +template<> inline constexpr bool std::ranges::enable_view{true}; + + +/// A zview is a borrowed range. +template<> +inline constexpr bool std::ranges::enable_borrowed_range{true}; + +namespace pqxx::internal +{ +/// Concept: T is a known zero-terminated string type. +/** There's no unified API for these string types. It's just a check for some + * known types. Any code that makes use of the concept will still have to + * support each of these individually. + */ +template +concept ZString = std::is_convertible_v < strip_t, +char const * > or std::is_convertible_v, zview> or + std::is_convertible_v; +} // namespace pqxx::internal +#endif // PQXX_HAVE_CONCEPTS + + +namespace pqxx::internal +{ +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(char const str[]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +template +inline constexpr char const *as_c_string(char (&str)[N]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(pqxx::zview str) noexcept +{ + return str.c_str(); +} +// C++20: Make this constexpr. +/// Get a raw C string pointer. +inline char const *as_c_string(std::string const &str) noexcept +{ + return str.c_str(); +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config-version.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config-version.cmake new file mode 100644 index 0000000..c47d695 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config-version.cmake @@ -0,0 +1,70 @@ +# This is a basic version file for the Config-mode of find_package(). +# It is used by write_basic_package_version_file() as input file for configure_file() +# to create a version-file which can be installed along a config.cmake file. +# +# The created file sets PACKAGE_VERSION_EXACT if the current version string and +# the requested version string are exactly the same and it sets +# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, +# but only if the requested major version is the same as the current one. +# The variable CVF_VERSION must be set before calling configure_file(). + + +set(PACKAGE_VERSION "7.7.3") + +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + + if("7.7.3" MATCHES "^([0-9]+)\\.") + set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}") + if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0) + string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}") + endif() + else() + set(CVF_VERSION_MAJOR "7.7.3") + endif() + + if(PACKAGE_FIND_VERSION_RANGE) + # both endpoints of the range must have the expected major version + math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") + if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT))) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + else() + if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() + endif() +endif() + + +# if the installed project requested no architecture check, don't perform the check +if("FALSE") + return() +endif() + +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") + return() +endif() + +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") + math(EXPR installedBits "8 * 8") + set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif() diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config.cmake new file mode 100644 index 0000000..cb25a05 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-config.cmake @@ -0,0 +1,4 @@ +include(CMakeFindDependencyMacro) +find_dependency(PostgreSQL) + +include("${CMAKE_CURRENT_LIST_DIR}/libpqxx-targets.cmake") diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake new file mode 100644 index 0000000..980f460 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake @@ -0,0 +1,19 @@ +#---------------------------------------------------------------- +# Generated CMake target import file. +#---------------------------------------------------------------- + +# Commands may need to know the format version. +set(CMAKE_IMPORT_FILE_VERSION 1) + +# Import target "libpqxx::pqxx" for configuration "" +set_property(TARGET libpqxx::pqxx APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) +set_target_properties(libpqxx::pqxx PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_NOCONFIG "CXX" + IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libpqxx-7.7.a" + ) + +list(APPEND _IMPORT_CHECK_TARGETS libpqxx::pqxx ) +list(APPEND _IMPORT_CHECK_FILES_FOR_libpqxx::pqxx "${_IMPORT_PREFIX}/lib/libpqxx-7.7.a" ) + +# Commands beyond this point should not need to know the version. +set(CMAKE_IMPORT_FILE_VERSION) diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets.cmake new file mode 100644 index 0000000..4716fb7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/cmake/libpqxx/libpqxx-targets.cmake @@ -0,0 +1,99 @@ +# Generated by CMake + +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6) + message(FATAL_ERROR "CMake >= 2.6.0 required") +endif() +cmake_policy(PUSH) +cmake_policy(VERSION 2.6...3.20) +#---------------------------------------------------------------- +# Generated CMake target import file. +#---------------------------------------------------------------- + +# Commands may need to know the format version. +set(CMAKE_IMPORT_FILE_VERSION 1) + +# Protect against multiple inclusion, which would fail when already imported targets are added once more. +set(_targetsDefined) +set(_targetsNotDefined) +set(_expectedTargets) +foreach(_expectedTarget libpqxx::pqxx) + list(APPEND _expectedTargets ${_expectedTarget}) + if(NOT TARGET ${_expectedTarget}) + list(APPEND _targetsNotDefined ${_expectedTarget}) + endif() + if(TARGET ${_expectedTarget}) + list(APPEND _targetsDefined ${_expectedTarget}) + endif() +endforeach() +if("${_targetsDefined}" STREQUAL "${_expectedTargets}") + unset(_targetsDefined) + unset(_targetsNotDefined) + unset(_expectedTargets) + set(CMAKE_IMPORT_FILE_VERSION) + cmake_policy(POP) + return() +endif() +if(NOT "${_targetsDefined}" STREQUAL "") + message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n") +endif() +unset(_targetsDefined) +unset(_targetsNotDefined) +unset(_expectedTargets) + + +# Compute the installation prefix relative to this file. +get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +if(_IMPORT_PREFIX STREQUAL "/") + set(_IMPORT_PREFIX "") +endif() + +# Create imported target libpqxx::pqxx +add_library(libpqxx::pqxx STATIC IMPORTED) + +set_target_properties(libpqxx::pqxx PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include" + INTERFACE_LINK_LIBRARIES "/usr/lib/x86_64-linux-gnu/libpq.so" +) + +if(CMAKE_VERSION VERSION_LESS 2.8.12) + message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.") +endif() + +# Load information for each installed configuration. +get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +file(GLOB CONFIG_FILES "${_DIR}/libpqxx-targets-*.cmake") +foreach(f ${CONFIG_FILES}) + include(${f}) +endforeach() + +# Cleanup temporary variables. +set(_IMPORT_PREFIX) + +# Loop over all imported files and verify that they actually exist +foreach(target ${_IMPORT_CHECK_TARGETS} ) + foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} ) + if(NOT EXISTS "${file}" ) + message(FATAL_ERROR "The imported target \"${target}\" references the file + \"${file}\" +but this file does not exist. Possible reasons include: +* The file was deleted, renamed, or moved to another location. +* An install or uninstall procedure did not complete successfully. +* The installation package was faulty and contained + \"${CMAKE_CURRENT_LIST_FILE}\" +but not all the files it references. +") + endif() + endforeach() + unset(_IMPORT_CHECK_FILES_FOR_${target}) +endforeach() +unset(_IMPORT_CHECK_TARGETS) + +# This file does not depend on other imported targets which have +# been exported from the same project but in a separate export set. + +# Commands beyond this point should not need to know the version. +set(CMAKE_IMPORT_FILE_VERSION) +cmake_policy(POP) diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/libpqxx-7.7.a b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/lib/libpqxx-7.7.a new file mode 100644 index 0000000000000000000000000000000000000000..fb941debbbf9db796aaefff0ca29f2730cf7f917 GIT binary patch literal 4600578 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

    )hCpCaGX~rdX;bRU}hIgH;#mjPJqLNxAQU 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 R>127yk5W?1iVqea{|6hz^@bV6$1WI0beEH zHwyS_0l!(m*9iD60)DH2w+Q%c0^Ta%Z36yr0l!ng?-uY+2>2%j{9XaSPrx?{_@@Q@ zGXj3UfPYrN9}w`*3HXBo-XY)*3HTQU{7VA@J^}xofbSLX-wXJFfWIQ(`vm;Y0zN384;Jtd0)D7~7Yg`01bmc$A1UCY1^g%hA0y!J5%8>lA1B~r z1^h$-KS{t(7VuLAe4K!f7x2>re4>D#A>i*5@G}LxSimO>_&EapegQvEz)J*tihy4r z;8O*Bnt)#@;1>z_bOFCuz-I{fB?4X{;Fk&bOaY%Q;2#q34-5E51bnW5&lB+Z0=_`N z7YcZlfL9B6jeuVz;7bJj8Ue2r@TCG?FW}b-c$0wV1bmr*FBkCZ1$?D|uM+SZ1bnrC z-z?y31pF2Ozg5833HWUS-YVd?3-}!Z{&4}nQ^4;Q@J|T%Jp#T#!0#3C`vm;c0{$5R zzhA&VE8q_Z_~!)tK>_a&@P`EaVF75*-ig83Jwd0(uaCK{afVNKI?+jq{%@>s*B&AHi=__}B>EukaHhc(H2gi4lCJ!tGwGldMph3K!>DBPS<@yYK|A~v^c`1s=rpXvkrZHf~8v(3SS*bKkPjO-4wx#6@GIBZ&vu42wtSR`q~J- zS>d-t@bj|--4?-{6@GgJ|D3|_h~Q5t{NoXPkHXs{_>spFbY}#=Na1%y@Q*6|?g+kF z;p-##E`@(0f=^Jc?Vbp}SmB?H;6GLPh6p}Pxxz0*@Q*5dO9UT1mY~NX_%wxgM(`UI z{&)m`T;bn{;D1*5HzRnFa>3goc$LDR`2WX6+}c36hszL7C{7+|L>f8 z&w207eRt-~Bq{yp!-uxtoOkYi@44r04u6>W9S&cMyX-q1eg^Zq9DWb;`yBoj^ItlA zhiwVn@9<9M4>e6{Te(XGzWp91rTqY(ePk@+JIPj64?QHRfG{;b1K zVg7rEU&H)4hp(^$q30dm%=`}yU%>nYhhM_{MTg(d{ErU*kolh+{-qrWz2xw7nZNAt z)psKFXNT{~{9T7HVg7-`FJ=BOhd<8zLx(T-c|spKyove09eybD|2X_i=Kpp0>&!oP zc-_v7mMi_mcbG5d@Vl7nvl#l>D!b5M*Kp+bV7{iqk7vG?!|!Fjw!>GeC;jU+wWB|KGT+MKr!fDV!#_2VzTd{-oy@m& z`1{No9NyeWdL}x2g!%3czn=M2hd;qQ=kN`iNPoY>4`F_c!_Q%UqQhTiezL(hS=Kpc{l08WNzYhQO7l?oC@bj5}dU^V7_~&`%>pFbGo+P!Q z!)Gx6ti#V`zPZDnV!nmL*WHWsZ|U&)%(rs*?aa4!_)2?|o*f-Njd{Jp&t{%>__|X` zPlLl}FrVn~qnS54{A%V+4u6jM6o+p#jl$i>;q#f#a`+X@_jmZb>7?gihhNM*>+t3b z$sgwMKQQli_%1U@e%Rs1GC#rLk1#*c;p^{1dQNtDk@*=8zmWNv4u6^XIS&8)zNG(r zhyRNC1rGl=^9vomc?;>e*x~KWFLC(E%rAHNW6ZC0`1UhN|IH46iTTeRz6rYwZgY5s z`CSfwh57vsubWNbKIrhnnE%S*mok6S;V&?M%HiwoNBW;}cpLNIIs9wPUv&7b%;~j- z=+8fyzwYq*IVAUn!@tD*?+#DRCHc1;-oX5AhtFmHj>Au8{;tDsVE$i+f5iM_hfivy z_~^4~^bh_iFkfi}`M3P}G4qujejK}gR(1G>ZS>`*9exP&)g68_^EDhkrJeMw>G0>7 zujB9y=aKvd4!?r=#twgp`Q{Ga`T)|iwZj)N-`3$jWWJ-rcRi5w?Bwuy%y)M98O$3T z{tWYGhcEad>7V5A513DJ_;(H>`Q07<7V|wEK726APj~o5%=dNp&zR40_|weybNGsf zkp6au=b0bu@JE?1aQHjS&vE!VUn2eAad-psa~(dH`FRfSVSc{Dzs~#uhp+Hu%u-Up zyO5hvH1P8o@U_ifBmdvdBfmTI;2p`&+pk(ZdU785Vdgh$JU6s@j%FUbJGq|aUuPb? zJIT`@{O(fb!Ml@rD}OV1T)J*&`QSaub*=pGm%zk+%2j^wtM|AKk& zj^w?T{{=iQo_}Nc`!!ri?^=ga{5SfP{XErY|1udoPS2h!AG}A&W);54dE^(ceDF>s z58seK#v^|P%hPK?=7+lr{Pl6>pVN4mpppjVELyt{*uo#4~q}? zV(iP|?3?2c_#p4R2wB!F!-@S-xRseEzh0_&34pQo;L567HXv2k$H0VfAm)6|esQ5AOo6O9k(Ze%9(a zg?aGaD4UV^-QylTYoX(fEBF1t>rz{P%Btn}bm{LWFn9Go#5{Pi-$@;Jqs8Pu}s!H+EBef_GH6uzJ4e z;YTtL-dB}yU-9s^1*HG|6|CBn=)cUv|H?dgk9B+d;mSRv=R?)Ar{&u-cjc!u58i2& z{9MF5c&D{*Iiu)G@VNT$bCy3}%aP3$d@|v1icj#q*nT!X1K@Fb?qm62pNaGjuYgZT zy|$|TJhhSi%SsF5^{ngR8+-UJ;C1v=xBdB?{WHrvcxUzs%b)h>d5PtN_shO+<)`(= z$Fmi@F14bDyU6DAkD0HcT*_soK9UdKLEFjdZ)Sd}%HL!8SHa`*`F56HP34hx{@J{r z^snylVdiTpmv}zHe0}B8ewP~{J)co7`MEvwjg?C~-Iw_$$|b$?nFsH+Nk4oA^UWOj zUohW7IsVB%e_`F0wv$X~`hc!zFBo32+q@}Db^{v8}WU-Iy8GvCRPzn^*Vo}GmIsUgzu%J0g2 zXGhPQ%zxzYo+9aS3qdD{!mjBDbF9Pk`5@4%BeBu>1`VU-3kve-A4sE9Ew?#%f_FTnpFb0v^tV}u&{j77*Ln1$ zP9{CUKIhL{`OUy5q~3GlKLwoh%Z*$=xA~tXj(q#IHJp#L>G&FWT>Q`V@XI{>S`WV+ ze8TcmRl=%2h^zakF>r%l!bIH$(!6&5N zaq{yfmVfF~5`Sq&E1ybwo_6@v;FPZZ)y)^uUVdY_JgoO^tMF~hyLLA~RzB7|jr3oy z`WvnML~zo7)>;Pqz_!P`EuS&baLLaXDsQ=Yq$j>qj1bC+i8`^F=k_pS8bf;`5L-KvuTlX2I)H!8^a3*!VvQ9vAMb z9{wTg3El-h&W5|sw@80*UPjv8LhuQxmz;WdCU{)9-(@|AX#Pljc#rv)l<#E2osEW8 zm->qGUdzABJa~^-?27l82k#MYW98Flk)EvTnP>TN%!7A|x3>JJ%>S(N63@4p=ako3 z`904@xuD&R*m2=K%X`7=QbQ`=YWbbahaJA=IV2yvgDm~k9^h0Dcd$TqT=lVhr|OY- zUJf3Y|1Yw9@SgJVHa@p~Ctm))9=;|F7>du0*09>&>S+Xz3wL)9p8;N%>eBd&o%TZy zU;8{0?n+yl0MD@FU@LfBxL1PLrGj%zQg81BpOE^yQ*VFI^1-{(+uL;YoKJd!ccn9y z|ABe%uC$cbQ5TSW@UFDf!;hE;?@C``^&EB~$-l4p@HxwW&-@?CMgM^p#i#cx;B~1F zR9@o$H|8HImwIyg#UvlRH=VZO?tY2M=X0!qbDGWPW5MfE!8_EVe}hYj2k%hZ;V|_* z@VIh$iRFX$sXxD*33%#dq$hZvTKa)ImgO9Cz9tH^F10}ArMz}vez@{=Q|9MjaB4?~+xWa-`}1SKi4S)p58oafe#I57+LVmrCxMgx z%WcK9!KCi;=y{6uEc}${k^1w#hi~*f3O9HkT*@&69+%IpEFZkbJ=F&E2=hJ-SNgqm zuOj`yyW0z`{9NV(j{M2sl-@zBV9tu>gKJnmc&A(H!;8#=ce=N+`Vad)h5H5jHTAvb z=XvH+mG5f#Mn53=;5~6E-~E^e?}ryjRewxjr!1DX5yyXAJKO{Xf9ln71 zY~@n_Ph;My9K#U*yu@5;SxVQ@R{Rm^ze(%o6;}R4aLR`tH5u@P<^N&%MJg}hZgef_ zars1WO7Er3M!}9Y9~Oeg)raF*&tV#WX?Oo*-lbgfXS?et+z#bZpAQ75a37jv!adxE zdlbvhS9uv9p9PPL&&yU%qb+b5$5;Aaqkq2TGpznr%YS4W+%1;h0$!IYXt>+i{CtV| zpu<4%m zvK2~pV7%jzU+G4Q|5r61uCVbL0FU#pewDbD3IB1bhhO61KlJch!0S@SXnc0GfxOTB zIOXk@pLZ3f_<{4?G1R@)%Z zP4UmAmM=fg{QEHTN9t+IJ1iIZov{ z@BViXzue*911J5r9%R0M&FcB5<^OZA0bQ2Y-5DRxsopz z@yaEh2QvSfa*;os`ANz}|KrS0R$gcIuYbRZ|JL0GoM3sQwkITXVmyiwEEv+?(PSh z{BXSfV?F#4@VeA*RDZ_iPtzmBFV}QQJv@Q=Z&iLh8=v1Y|E|hQ{%`mw>2dcpWtl&t zdZhk*oB6ZK*RuMbW$x~?TKzH7|9h1`*2=dsclR}&!Q9<1CFFO1>=I%bI9ez#n?*5|tn7^cYB%iyVB>6uoKisBki>HYHS-I5zdCdQ!e7cqY zD)YZ9pJDlZ%->Tkdbauv>3>_f3>M|NWKkw__fU4{V-cTM|x5ku9R;lb9X^EH)A z{;c%}3U@8#690>tucN%*>RImvl7Bg@SUvMzj30OU z!QqEj`7SH}4D(Hti=LK0#_PEnye_qw%8NboBJ(YjZ({X-=1=i@4hFAFZK?9;zWC=u z=I;94z)K`wr}9!>cQfBgx#a)smr4F}%0>Ps%(qd#mkoEjKa>1+%0DK)V@tstDiIq>iN_=PK_bq3BaW(UL<+H7P>uV(6p!_h)S9_g!vvR5D^TFfn zy>nT9vdSN0^&Id9>2cSgj%U8B%1gif4D;QTOMY(rSJJb)a_P61F#m$`sW#kunD3?h zSj#{6Ch1vK+r<`^ALii~G5@q9{~Hfq>u;og4M%>qho8!PEl2+69{witbsYKa{!Zb# zyp#EQD&Jt!`!Mrqnm>|n>%2vJT=^rJZ=iZ4-){Ht)Z3)TU1vOo`BV*8%J(7W?)qKo z9nzCgd1)_uG2h4G$1`tHF8Xh0K2y2W=a-nzR=%~(pH1GSaOWtWVELDsw<=%H@+Hjo zS1$3q8a%GO+{p6nDlh%vbIjfKzE%H0@i{={rM%`b|DtlK=eIEboKs$Jd-#s;k^XHR z`7RH?g!%T4{O>$`gZD}Qj*k2c4`0mu^N#!t9{vXNT~xlomP`9TDcnOee@I4DlhftPUeR?{A1>aDHr{_ zen{cwl+UyIkY(PfT%)6EEZslKKo>$&&`4%6M{vPEL&raqGl}miCXWpy)NUP^J z%=?wsS$@F3N&leoQ!KxQc|p01Uw>y_RGzc)ZT}%XBg!XRelGJPlrOUUapp%VpKJMQ z|0O*~E8oiU-I*VwT=H{(`Ed@vllk$=_qBR9`|2LJdY5AGVzoq;q zmanlq$)BNof6J#cZ`1a*h2@Jq{2J!-9Qo%we9aXo+yfo?X&!zA^Mf4uD?R*S=7%`) zAA5Mirzk#OR(a{i&Srj&=8yCMz=I`6lyoRep2J?`M9#!&57h{tK0h{zm2(DVKh%jrk?YrQMy*{4(Vte>3wdly7U} z^IPVJYy7vde7RL9KHpV&$+vBpU#VQ$(J*-2_e+a;`1tGtUYELBG`p8(Z3t>pD5qUrt3!L?mF_j%zv)(Gp+pASU{;u-Jx9c zAHw{0hhNY99_6CvUFIh^^<*<_0IN&gr}B+9+-b~zsa)z|FY`B5kEH8D=I;9Aoy;Fl zJ<{Hn#}%CLpC~`phWi!fr>TA^$8UQ0FPMMBk$=a-w_2ORJ=2l@qKBW({9BIvjUN6y z^RpcJHP)eUUA_nNb5y>;=EDWdAJP1ge0$O(zYDG+txKJ&dL-YvJ^V7}?z-^0xVp41 z^{|F3_3Z%W?)vX>%pX&E=_hYu{)EHdVE&|X(Z4yaMy*RdrCjRUZp@!nF8$;p=I%Q6 z&zL`>@{*sc;EGk8Ur@e*&F2G{|6chN%P(jCKboISmamR0S?f|SsJz$%Coz9fx#YvT zpCS3@mCL$qCwN?cdnwERK*JS1KV|+$)w7&;MBzTJe3q3T29FE( zL6#5R-T1tfe-(T}>aR}!ztU$(|DQBI63^|yqc}79;TJK#)scVN!`IoI^xx*lAK>8^Fuz0Pr5$~G3)1tp=8xpt z!OUIxUopQ+^+>*bW=qoJ@=oUNI{53%-_mfUeD|C{dffHyW0=3I@=`zVXa1hU*Qp~t z|5Pse4`lv3>r5 zU+Vu5^Z#nN(vRK4{A1-C+xTqzInwhV<%7Zj12EQoRKJwtt;|<-_@bRiel_KL*m&;z zdE%=p7d^jb{)*<0w4>E`Ci&MKK9%|F%4J+z!u)OJlK($rzJ`V?`Lp&er2kzrxvk7yYL&-$=RiOSgbe zNc~pF*)6S}yIFo?NB(u@n<~G?%Fk|~a5q;j@%%RPEtI!e`A3*9r|nwex$;EPGePAg zo;l`QIs78l zN9DI!J>S8`?7GzFl}mryFp2ms%0>Tc%+t!nE^3}k@)MOyzTLpQNx9gWTTCJO$;u_3 z7cg&D{*;a9oLxzNigJn1znJf;T*~+K-AH~nO65GS4WNc<#9u$`GE3^ zZMm;8lk_Z7ewgJ=%!iaqxVJMOcK8~zNY99J$%liOFIN7b)qgv9Tz~jF%P&!Ru?HGv zll~)>i~f_CAEjLU_V+M%{r~@AezYUM+kT|~Sml#!Jip1@_4B{L{CJg@`0O=@^qim^ z-4Xv>%KU4}B|qO|?)vR_o=bXM|9m&|Q?;JRxc?&$f1CM98g8>q*RHLk-}UDYGe247 zWxjbkbJuVG59X(;{6SWK*Z!pcERCn+&vndCSNW5z{6CnVp^WPZNG=glMi7b+J!?Gok}DHr{3GQU{4 z^bfrUke-_~-=usmV}7a1i#`0LM}DOPNzW~go@Ni9&-`bO{7*f6wJ(x>*B`qZ^E*|K zwBHfta=T3`HPe>M)gJkmng7Dkv+h9@uFLmg?)r64WPX+Ao79t^GXK7E$^XwDO!}`@ zF7k&mzec&#s|%UCe#obo|48Mf+;={N^k3)j1* zHz}8JA7p-u@_nqH8DAznKUXg4J%jnrl*_pP2J_pLOTJ~lLgW5p&ba?oaQNp{UgC2z z^ShMGxWB`pB!9PZiO=!O?@=!K{}^-E-?CYj^xUWN67H$Y?|1lbnLp_8%weSG-&zmT zHs4NT?#_#!Wd4|=XZ;-Mc|y7L4-1+9T6u%je;@OemCHQtpbpaWlyb@cjXH@xt$bIj z=PBmyd~nAul6U8QCoo@2^@#or^CbU_@`YCagUp{*F8TZp^XHUHIj%pS^gQqIIn4i{ zd{3+YOy(~tm;V3H%>SfZ`pJE}NxwUf`x^6?RbJwAEAu}qKg5Q+`~uSR7v++!1DU_( z@avhs;qaAuNY9(fCEOO~e^b7b4fh=8?!0NO!%5FuDlhqeHS>3r%e-U%g(UCJkN(a4 zA1W{7`+dFf_SnjOr00E=KXL^V(LXZ(K>6Qo{BP_h`45%XS>7~2+?^ji#QfhXFZr`* zkmNJUCI44gMBJS>eT(^jR9@0Gxe%YOeLegnaNK92dL-Oim@l`AO^%+I`4jWy9sao? z(zAkcsm}w@IluLbHdzkdBu3Xa9 z$9zqPKhAt@hwm~%de&7g;U3C-J>`<#tC)8?@qeB91}ZOlwp&d4H&ib1KZ5y2$|e3! zG2htX4M&ikO&xwZb9WweJ@d^~Ui{ThF`uCP+cy7?T0;7_R=&jYsYepu*5MyA-(I<- z_r#+}-knc9$$STumwC-5UnTjSluJL~!@OR(_#uDIyg|9N$BmCBJv%Fx^2#xH=Tnz4 zcjrydGoPq>Bwdq_A^nZY_qO?SK67`T^;hQ2DnHlCHylfPCMy^HM>C(IT-NU%W4@bm zneXg$9O>CZx!9#e=I*@gSIpgc)B4Ago-a6hc4fYo@&+6KuQA`-;g2$(ru+gc|M?T* z^|v$6sCXC79pRber0m`NSJc9Wbm2YhG?Ly}6eCko= zmur6|?Q6x8N&lBrkJO(j%w73G=2xm7k-yl(A7Flv>X&-H@hKFpJ8#;L`Bzk4+V2_6 z-FeD`%(E&l`afoVm~tuKeNLrtJCsZLUc|i1;qNh@@9`c;gw8I}@{wu9No7sB1!Z&H2^^nf9WdGG};B_fieuViWsz>|= zH!wd|!}VU zNhZV z=L`R0ezwZXINN+Kh5H@l67I>&&r>e)_kqXt=c}DZdM;3TX-7X~?#>G`=aalUFL;yr zMXE>g?W_w({$hte&-@bQvJd&13rYSmSzBIq~~Vk67HqUf2v&S=L^hlRW9{&-787Y zYRaWw>STVKa;a}uGrvQ*guB9bNzYx%MSdppyOm3PPGf$ra*5Av%w2na_5UILzf^hA zzd!Q_9DW}2hm=b^f5&`F<&w`EevkBT>f3Uda3v=VpgJN8}X2df^bC)-^|`v0a}*84KdUHK!KyY}sM z%->QylFzR&e@D6G^V$+zg!$UarTuPv z6Uncu{0lZ8e$L#r--d4{`Sn#^^elf1@r{)4ZS~y1d{gBTpO&AJ{N~D~KA*vSYvu1) zJ?Wp3{5Hx(&jZZ2b@?V@X$yLQow z%y(5i67KqUlm6Y5Oa6b6`5wwe{u|7{pj_hf2y@piTH_wl@7hIsGT%$}i2efey&ZlP z^QjJhjrnxt{Wjlrzn8+Dp@Uh%w2onMCPtNa2@mgRFCBUv&`oxm-KFMKZV<> zT;!)RcgOv|FyCM0-?8~K@&M^+S3bk?Z!vf6fxDTzC;1+gZ?N)zWWG?jJfj}U%~5Aeagj7So9m>1IopJ z^)d5B%B7wh`ZUSA(S2B0Uk-sxPTIEIml;4y7 zW0cEybT;$jluP_?VD9$kZ!kYW{(Nm-u{(`4tX- zmic#;i(jJYFBIpUV6ym6!Nj#ry}#CEqrEmGryyb_(-rR9^HPz}&5$ zUt|6wNB+mmPggGez?|18T(^9$V}8CPzu)U5f01$-zi#&ME#4sc>r`Iy^GN2`D?ikh zZ|bi!E@QKbe0<`7TzV_$JAJR{2!RKVrU#^0O>I;cq0rnezFT zZ~S-SKh^k%{x5*X*~4FA`I}W<=KIHb zwcn!nui(h<0zM&imm@!mWNxAqLmN5Uba`-yUN5H&lL8`^(pv|4q60 z_g48wyq?X#C#2q1c}edSk9-@;|3l>^o(nzl$FlrCRbKR8#Qa0$o7ni@%KSgdCGC%T z^uNsVDJ^$d&)W1oN>_t&(K8oZ{vOWH<2?N99{vq*oZnRa(qH}1BYzLeujt6X%-nsK zZMpa3AU#_v7r*G8;1g2YDVKWkdvMViF0W7hi{y7ydD)P>Ci9(@i=G{rra2QMrr@_nsWTew6AQ==EVI)0! z;!u83#{b*FT*3d_Dfn%6xWBB1rr`Hevf1wb;Vfb^yCI#;cID^ihI@B{yG^ydRMxu?IFFZAbnXQ!v+`v!|kvYi8cg9Af7#e8ctG@LJ(pwbQ5eP+*{y7%mCc1|`uWe73J7qbKNGp(~G4R%9) ze?MhSR4m<)FBAp}6l70-cgyU)hWh$U2A_2Hw6zzTa)m-}NlWKJ^RgL^di3Kd-3Xw6 zpxA>jLO~odha;Y@4@xcFobT@}EEz0j2XjM1iw6o_Q=5===`@AZ-jKzAnK`o#=%qii zoxK_SNpWp2PM$y9&*k1SV+5j^%(Qe%Rr=f0S@T~8+SAZJlF7`S$J(QbnaqjF_2m&I zn}FtGA=f{YF5`CJ!rcyLL!w+E#>l1VQ@{P#Jq3gI}>ro{!S4}s$L zVtNuH($i@REIZPZU)<6OobFtJ`iltn6o*=nPnmQ*N;W%K$j|Sg1`{8bF$^Fs{*C#5 zn=PD>3i%Q*Y|El?D31o3E9Se9#Y4rG)>+B(;*dGB+Ov`Bm|iqIfQ;ofB{dQHntS?t ziaojBo+I-G6HI#}YW@MesQ>sA^>I>`ntVE)ZU`3xN?>BPJ;(WuFWUE}|K`V*1*`B2aai?x%R2{oE#+ftgd_$xIQ4o15bbPs6O-Mvc&7Yw1rlw`oDVsJn& zg+H0IWMoczeKw79?i}bs2a@eB3=9uu=4J8gzCMaow2`IL)XHpUnQ5Dqo|J9fpSp>j z{`muQ2dN*|q)aI;8O&$<(IQ*QWxP}MZ8?|@E3OA=7_%M(Ri-gJ!}d_zL!>8Wr=p|C z_T~C>-T6XwAyKxX_Mpn4ufqSc84NA^Q4gCnLxgsQ?MnG_Vlf?R)BFEZW?7jd1EcPMg(ip&&_#mKgD6b2TLS142|$G2C4`u(!hkq-{A z6K+W>LAWt^zW2V1CQ2suf3?T&5KxnX!vPqvI&sak=3U)|d{DNXta6{5^ex zy<=4WVO3GfmS%-sBwv`z6@D&i{L-mE&bW-hhc9S^2kX)~ux!#~lT z&$0_A@|%YAd>BE)1I}VYvrx$1S*&j|g%K2Hjb_uN`MI86Xpe-6 z;wZpU?q^Svan?nCZ*sflC}`lS$HoX1p#g;i_Xm6fgT+G2tSNAJVH|-!ZuXqOPY0>l zA@5uR%vH_$bbb8yVUdzRYRSghqEkyq;fOb7+dAMG%IC8S;HJtKg4#8i9G69uC1y~w z;Z;Fx>2jsCw$vLTw7PsttM$tm|Dm0AWia<!Z;x$mJRo1#y*+8;$#?Z1A;x z6-0Eh4Bg<2kWjM+~8BFd&OYG^(4c3&K6>_jNw?cVOE-E;T zwUK|a@sOh8o*NDp>YgI3X?{<>w=04sVwxzx>E>$b7Rq-($SN2Plf{&bc6ehSTqtGX z?zfhJsFV?P;|QfT73$7w(kF4_(o&~tV|T8YZ;k(rvRVZs$u2KI*I5fPa@*gc2V zgO+$DXbmSwMC9WI-rvNyiNmroG&oLqk2wQNU~e+BvI}}J90swW$(5}*odd)03zcs! zHGgO-t1NL<8~bTZEvVtKwl7xCu)IZXVKjz`wjI}^pBz>&uR>bl0z@V3SW?U*Hj&jQ ztO#(o3#VXxmKOm+7H4fX1aiz6$rul5#8hL&V~51nj^sfHCHw!z5{TwdU@nkFhdi?u z$$0b@;k;hvvP()b+K*4}#59Zga#$p#{WT9IcKzA+73NUdPaAn@Y^C!xEtcp?HZ5c~ zwX|W8VuV_3u#!=q-Itb<*~FgRmxeJI=_2vn><%o@OR}ixW#B_{ifUp z^_iKiSU?U3!woq6O;eGAXsIlSbsOxV=vhSbFcYH^)vZWDIQC(ATGOGm>~K^_o-AFq zcBi#8A;IBKIML*8&zN}!mSuvx3=3A&9m>&qO2IIu?3hc&M2AWaA)?q28X8pCC*5Bh zDju!M%Ck|t&ua!3d6La0br3Nnb@I5uRek#Lf8R>Pat9Asrf(4X*{ zNfx^ju;4_?a^u>wp!Hw~!eAH7el%cAi;OEJQeDC}3a6(bwBds?x_tWze_nM%3x6D` zqrfc|7yIewkOmej>cw6U}p7kRGYGW#s;$MGLc>zPKug(YkXIA z&BQmAD&~TcdP!67@Hc8cR1$QnWyu$<6q_JVBl2u2#K>2wkPDJp?&Wlc;uJOsVm{&0 z9Y@POF32EuHTYp#7hslwP7wBQ&*3A*EiIx01XD$M0-Lky~6q{B|AX1sgwq|wk+Bz6Oe*%Dd?p4gvXY?j&W z47NIdA_pDJhnI$bO%j3qgY`NSUYIvWMzHKnvv6KAti`>@u38@H%I4A1O>wB8Yf6*m zSgxiuN8dPS-AxfwkUd)HacL+ckC4uBjn&c7L5-)w>@X!qAMMyOjtjRhsxXnHP|D7v z6U?IGbjZk*aA_T5QKLL-jM@& zwqks)@$$3`Pg9mam~y&CB_tx0XDfsc9% z1C=lOE$kwiiQ^-2>$kjcf>|Bg743t@D3TTMVy?RdOBUETuLD-)exr>{*ok%tAv)NN zWqNqaapGt%bBmI2vzq+}WIWPv(7vx7PqizFTk*)Y)Ub)QyLSuHrTFOe2Sqh|mYKE+pY>*)g=mj$_$vmPm^@Y`9zSgo9TCTX>S6nSE*hmZI!leOc#DT@wN`Xt z!4A=;VAF-3g`R^B#`}HgP7RX;7>_yXS2#9ROyi6J7Wq2Z#+-a-2a+|Hdd27_5*}4e z{#0$z;Y#NQ3NgYJs{n3h2YVRefA#|`4+fH#lHMD?RU5cqE6|E1VQ*u?k~6P~L9>i%_#Yfvjtim3$<&a*X;CvrnUsuERI7YSbzk ze#xpx7M1{Sf5UcqvkxUaF)O!;e!Mq~hAYe1STxntAT9zv%V~D(ge@aX48?AuT_d&F ze&zQXhLT>L@nb9s&uB^&f`%pfb*WiCUe*SUfiVMMTuCGwP-mh$vYV(PMH17{bx@3T zFjGz-az1@9Hu!K(j_#nKQg+7?&sfMqa2v|4HRw43Coj%; zCA>QaxyaSeQPM{I@d$>hxQ1GG)be$iC1KNElPX6rU)fi;jT_Crmj0SrKQ;yV=his< ziJ!JsI<^ZND|UVjha2@-dV04cPrT(}{6OkzM)MDE8x2(t9<;(6OqXijPzF_*1&PKh z9YW9vIUe^4V;w#~FB~%hB?*~6mf?%TMyGD)RTYaa7|p0&(11?9{4!-2d|=x;4^QDw zDu$^8Ucw+%K0ZWe;^Z6f(90luOgH0qk$Juje+OFB&_BbREc2*!)* zI)`W@FW1A{xlY6(fL%`9_v@ftF<*K631ut!oXgbH1wmz@1%yDdVhAz)eZqs7cX7|+7(c4;z*ql@d za&7Fhr(y+a%C|x<(VhLXX4JSq&xbA5@#pjRiz;q&+T5o zN<)^@#q01KufRXjmiRk811}8_=yZZpv=OV)iH+{Ib<*((6-qF$Mk`m$I4Iu03e`?_ zZB`luoxF(|pQm>N*6sxf0-U0!Y!q7ziE`~siVLAL~5nPnT}fOtw{~sUClc%49!eDB$Sp_ zpU~Axp%3-GCHtZNdz$&Me{o+cb&6fRtt0K+;OQDXzLu8mt8JvaX-x?Xn!5_Tt38p8l3TqyT;^zL?u;j2!Xr%rxU3@1E}dOdBo<;ESPX zrXIb6x}moSHFUjqyoyP5<2kmk+WWrxQhoV8&9G8s&As{l?&1QHC2gUewiO?_Ai|XM#huhlilZw{{K;)1~TJbMw~xz9J-! zG$Bkz5#U&C?@&X%xlWz0B*R6|hW7R}42@9yWzSda6%I}=;>L6P5nV)v+vPhKEX>mV zTL_ddpq)ZJVqXpyZQ8|H?A&R}wr7hySQWvX4ga(`P)?FWOpg<}R7_e+%%tFl!vCXjlrdeq7|Ysz(w(;85vY8hN{kj#{&Ny(I79-Q4h^!*Y|&Q# zC0$H}jLT3P#r7)RQCmw(3}q+jKz14@KsC8(`)+f^eDz5&b?t!u#XY#hu?<&o_2sqy z(~?PZnc+GMx~;zh^(*L{>=lHy_C>bt=;Cd{qHE$;A51kzW>x!ns0t>px9A;Z#Nv8u zQ(kM2rMav*XglR(>i_k(*&&W89K*AeyBO-y8l6ch8>dSj{L(v)ku!3|&l3q)yy!lw0vLI&8ot;5# zD*Y81@aUTJW_UxuaG1z`U3=lD(Th%-M?N!xn-++}nV!Lon^AhAwPfwXGH9(C>L3TQ z9m9C^hn}mzREG?FJd2Xk<$Fq__vyFXrrSk?e>iLUy!DfX#g*#m>%ROWU7o-i*c>sWd-VW$F#~=*M@uSo)?6 z;nJzyB*9})z5vVx649&h$N-Ywb?g!xX%Bo|1v}8SwN*b-S7?;ll+u$hUB;6;^xlQt z{@&7u%NaYQQPfa?l%=#lgO-lUVRntzVr)b#w6V)OF z%f#J}{}5crlK=mcUCV9>2mQkTo7@aKk!3E*p{RYbcj-&}EPk?g=`Sn!5p>MUT$Pb| z4o&7kyBoXcMPxP~>~GBz2#x$IkKx>FTg={PS3K&Y>2|FF|B7Ltc+;NlS9z>lp z72XQL+L3$rJT>g7mhv~%LrK_wmo#jYT9UBKr-1IrDdf9*hTwa$op=>dZ(J}SduRBo z=%XpF?x<>xnfro@S&!43`OD=d_7JEXHw)`MNfZv%`q1}oIPvjoHZRj=`0{V_`U|?q zF=*DYZ*Xg@>~M$$HmrA!se( z^2vlMn~9Rml2HY1s%<^?-}U4EFl^6DH`+J;?2~`wLQVDb=L__#8XgdI-T;hjeZAQq;XUu4)6_dTE&c^K}t^3ou z0ag+yC!;5#>4pM$g5w^jsPs4j`;W)&aRhE46~YXhkW{TJ2+MftlphAix$q+f)he)6 zQMeOLEybb>JwR+aJXb|pRk*)v$Z$Jtur(&zhs%F}G70uAO0=#2 zHdODLX*~@sXM_r#_IU1x*W<9QlQfuExO;WjI;+KmfKpwga@F#hj+^pyg_LVVL#awP z3=Z`26W!FjIB_<6TEP(w?8M|vZ|s}GEsNr&LaG|D>x~@WgTd6|^d9yTWmMQbtS!2Xxvnnc1>1JIgR3re7cj`E`HFR|Z6**KttR!`LSoa7? zx8@4DzMR`T4^nc&d+pHZM&&Q#;ln%3hi z9@c23ZPD2vbEZ4kHc%2nS$_%@6_(LyGc7OmFD~>H%XFZ*c7F%j)Y&^QWO`nt9;@9j z!MpJg=_GoV4x{k&ehh7756jJEPVGvkxyLZ3SJ)aF8#4@pPwZ|$9J-hi$wUen=JZ5-5nz*FzJRYHUm6tpE+#G9J&xoGJzSf8Mekaz zb_F;l74?gT2hbsq2aHF%W_8vw(xY4T1#fP)Ku0ir&}`jwT3TcN zh_5#@X>fS>X!`X z9;poVRrw-4bK042jlSxhMopkDXjJ#>u}_VUrneXSX`gzP7xZ=TXy(QQ_AW9X9YuRF zzi1rP@^*MP*s9~-NS8=)Ur!OG#8j67_DU9-IF3PVy6jx9+F11U+2N|%4}$>5BKm`a zCK_(fIyvgCz=5X4YZZQbR}-3tlc|=x-$O5D{U_Bf@=T&lyRbcK{obCyvs*?b4={<1yhus!QDT0Z z!*r|#FN3BVF;9hMfL^ND14l*+pY!t=uC&<1U&DWuZNZu6mR8&ljNMi=Nx_}PjM}Hu z!7A$7?dz6p^lLM-#_z~5seT9Kl)>Sl1-N|@Mjsvbqf?jp0?zngqhrvGhy626*r42r zlZ2DAEpxLoT4qx(%?N+uxD)--#AF-~_y+#F@eCy53Ji_^>4sca7Yy*ud=CnjF7M5H z7B6@{V46h9>EO}KI>bX!a^BcPSEeNCk^ng>OKUERi&G+VSsaqYJFJ;ZBitBWSV@^? zE9*Fx9{E%;2%Fo-f+tpS>XtgkrIittC-oE^IhZA*Fb?O-v4YU;!Q+@&8FR%pIxRDA zH>;K5AtbTsJd^Khfu`^hDh#6F!cgk+vBfr65zXd0JK;#JDY&xh>U2*P-&G|e{U;Fg zpz)~EEX{O_pX?@)=AM2Gg>+h6M-1FGBDD>})le~fWA%8}Iqm{c7vd^=@Z|6(x}`>P z3znrnlcr~b+;q*Krb3>Mk0c*1mR8r~>!abUqTBt=v3u#O;g+PX8~tW%agFPKQF=51 zHzZ`}KiE+6rc<>>ps8-5(+28&8w39h#6ZAMG=J`B&@yJwsFRSKHOjAMWP`%ZY!cVrb1>j1ez0gG6jv-_Ir>tVx0j;vy<7XLbHkL`&Ry!Ui-b*61^e1yC9 z7mB_k~(EMez?ejTOzH(K|nZ7B15 z^1L`&Qa4p|iN0}Zi%59njSRj@qHGLk!o-s%ULe$aJF(7B9SZenS$;LGtddOh<8aeV z{GB^E)RW(xb5;(zRh6}DiBs>=pJ%^qoZUIThKzZ~h+SSWgW|Y`Z4*!RA$e)QcBR&2 zH$GPNsdO-Bsghwe%{q!p8rF?6l}+3B8bvdJEUYXzuE;SCF;tZ?;Le zGLwffvr;MgN4&1d3kHUYDo6i_munmxz(kE~8u|;#I8CAv4NF+3@9MQKspvjW zJ4T4nT*<{u{ddSS7#-xo-oS>5!QRwyhy#`tX!b-CtjL+$us4pE<9Hyj$v3?NtcOu} z*7*`5qafs3XWvn%0#?dK^4^BFm{?zrHCo^y^V|*#)54xSXddAgQ$2#@VD#siPM z3SHyf zCz3ZXYqfQGtE8)rH^XcGOok5Lg2y!%BdzonW}s-sX^cK>l%QUM?&%LrTtl)w_;ru( zmzapSUkB4O3D1gASLB_dNt5RNX`Q*DVoMM1q2XCy71@b4gRE;c1&Q6(u;%OJxR3VxJ)P zrO8-Tjcw65v^X~i=OX48n6dG$>e!~zP_G6K94!4qId3Y3ru($Ekxf@+JW-Slqb8K@iMn5I!PbJ#A73t4fc zqd61GyN$btbA>J}#4H-_Ddf3bjfDXq&vp67`fS$_-hyDW)oyOa!t)V5Fn2@ID&$em z@FH#N{^TA*+^6FO@! zzimQ9JFI;l{1n;;kM;ieeehGWbKCbpTMuPMt|L4f&|akpmjqXL*JfsVPW)%mIR__f znrQoQK2%Yv=%hn4l~8Yw+mfp9?cwv)@}@!>?agDbfXTgPH!iu!Zp3P=Ni?V5%)U$< zGW|5(l=S7{rGp;WC>Q{1Hc&))*yw6qP#YPz28*|ayyB`?=j3LRhO2J`JW^3mTd_Np7gM2J;Cs!@Wf-@ptaB9Xn*ipiW^l8TNz95VDv$knT+>~OQT zG)1-PEt%%vsQ}L`hkj!xIc{8F5mDAn2JMwf*J;BS)~n~s7qY8^vc}Wea1S%s2P^LiouvFmzKyuim7`1#_iYA zQ^?@z?Cs%)U+gh2Y2?8UT8(OYBDwyvav;nc#c*g`%OOe0%e(Mj94BfGB7V4Gx6(agDAdMpQ4I?2&rXJ7{j zRgMyKFE%sC3WA#h7DDK$z|ba=n2$=-j?W5q=?Y@fc#OtY8l25djdL#Ii%%N3*i0oO z0p?6}H-TP6;C9=Ppfmg-2@J?+0WGup>N7ZdKbM|lNlz>e<5+nXZV`HKs^uW;uN7wm zCL?^uwmB9s*WQDR-_kl7&LD^!bYSzu4Q8p%ykNye&02WgA&HOWV2s~du_-`NCK$?AXaJ=;_KAv}feYx%FDDQ7YA?%4+pA(=8F$`%YdBZfI32uv?k+igX! zg`hW{Rd+j^<~mwh_<>_Ode>5R_j(4^mfjm+->0c&sLIuaj_w9cUY`Z4ItERMfjR6l zpWR|{_HX<%12Qu8@PYQ~i)31Zcj97Jw8?iFn#NXJd(e~P;Vv<4&Ar&j-q>|L1Xx=Y z|-7Rj~0#DXh6YsiResaGF@WdOGhn6eRn-dhrFF=yrU_DiKt$*qp&v{ z-c(z4QAWBs$ z4X+#~bUxJ3r4_~6DG;+sROYjM6;?hlVv`#POu+`{W<|?OVOL3Wt8g&c2BT;O* zWip0*e1}$FLe1Q?U~?u9%~x)D#Whf6CUSbO8%!ter|H?Gq!&pA-ca1`Q1!Yo1*oy~ z?m~1tI_&xIU0I9$fjTdx$CPU7NMM_o>0r7kM-wx8oof_lZE3JTyk>fn$P3bx`O%G* zuruo6(wqxN0o%1Trbfo7QX>;d>qg3uMX*c58*^#V%yW;f=RQ%EH#>ikjFR`1gHGT1 zP0&Gwk2}GV!?Ysis?8F`sQOcLxLT$!*N@vB3oWfUJ_f&7LmDlZE@#zoUMJF=8f(o9f+RQ@vhIFv?2?gl;OkUE>jRieHL{&4p zFYQP&)8RgvAw_(=C^A059rWvoztB36PG{$_zl_b5*$4#JbCiY>UI9<~fj5Nu%uKx4 z7YV~SM?=f(rGb?BM#E`hzaK6dtE9Y=plXbq4&wYNQBC*LhGXp<1d5f9*UzVqV&wJA z(X^HZREd}%&{B+DjGe4O&5jX_ z7rbk7tGXr(NvWI=dmP2hgwEcK?Ko-WB3!76;vO16%KFK}<`rxavl9^>cr4>|beMgO zXee?)C!!*=u1cGusjWoTp^(H+c9$^^x29m()QCJGSo^Ju*wX9q_u zztC87_C_<%EM}UU1=TghP1TlY=q1zIOl!I#!c&}P8%k{Ae4n^^Rj$}@v`}wd^wye& zG+)}xK0Wd;;w1AB4pPHGS5CDP5gQWO?bN>{aDS13HOOnmGaKg;b{5 zY5=vANTnFj%p>+fs$iyCNky5d1nPKrD)Gto*nG~>OmsDIwPa~I_X7H8O)v_3Oy|>7 zLujd{{Ir?c(Nez0ii{kXEn?&>a}FdsHKiM-vV4mWZ8)HIhOCM^ZjWE7HDBh2C2QT( z)KOMyQ~V?icZt$B>Dmr=5oY0U*~@9F3T6S^U1A{}TVqA76LxyP3YeC75=N)F)s#BlE!hVZB3vPnNh8#FT=;RJuk%%W< zo|WyH&r8}d^=w?@7<$jz=93%WS#-%3Ia=Fi(tqI-4P$0)M=U~g2wKZfk8x!!?PMai zbAZY1%#NXDv<>3+8F&e0ql3STv(Z<7A^dK^1x3asS-SBqfkQH^!t0r&$y~f=GW>aR zyQ0+58t0-6YqkRdc2RTc*;h$%s?Jv#(%4F_&N41b>(Qp+CeG_ws;R8!61SF)!gCo4 zs#+JO`)T0qsp!iLe;o1LRr{qkO!8C)p+r3(eA2vJut`4FkkyTuIJm@LXc(@G#uu2q zc%htUs?w+Np|ZEH{HK*%q!@;9C>%~w{Esf|QM0P*S|QYOe%RpC1W7iV zWMS_`R(3)vGUS;x;{)0IRg`h(NQaqn(RYqVHwdC6Y}9fTRwQqrp!7OPeQOz(Dp%LA zNCVwC8M;%01YlWWsS!tV%;k4{=*;66<#oZZBeNuidK;H-VKjae4L+;9hFD=hc2t!e zk+ElU6eDsFR<#4N^JUOgR2)@9-d0E*1K9;u zO!|R_;5IE!PzgG$3SY*D$<43qmt!~#mkq}bD`kfAs^U7@LAY#OHBZWo!3i}4J~3aujT_)GXEi|=w`I2#S>D&x3KE&slfNQ6n5m6E;@M( zlv-8=VAPoZkVm1_wqSiK$qKhFQG{ZUplLY3c@00jYcxn>= ziOv-~J3W&*26-c0d;ke2PVpayVmI0uQ-uIR?IdhWCdoP3b&r-Ao+HHvxU?om+-7QY zOL}7N$)a*)Uph}nkU!-nKuA>OB*nWODLgH4h4`nv{R4$OE?C8d_g%1wQ7sd0 zE+flXO=O!=Gk~#UlkL2a@tSnk85x242x2;q29x8Zw=hS)2P`W)bTQY{i(!Q)Ji10N zH~L~7N`35Nh{G0O;RNSiIeTdO6I9$_@>H!JxaKTrhbXePM^|^o9_Nc+wOTOx6K|>l4R${{9yrD)-jJ#)=SBKO zV2)Ru7U7%fW<}-$ZwNFgD!Dw=EPsa2j+Ml!%r_d2PKhchuOz4%-3d{NYQEjIob?$i zAFrPc`WX4pOe6Nh+X8YsRXDfCR%DEB?%(ivg%fWvUxs28JO4=%tBNW1}T!SE~oUt;k(JNDN)|V|LHLfQq}+Hu?Of#Em;TW$M_)9HFZRx5Cp+eYl<{ zd34CiiFH3Vb@j}*cmHLJO9tT#$36?r1AGzd`W%~ZMu7N)L z5P9J1E#|t(ea}`(=pNi!W~Jzko8gT%3qmDk55Hj6-MeIPK^E8RI1`rJb~p;

    ?!$m_W^swX2t@Fmk7Y@>fXf!|GlL!IX)qgOZAeTsput+nUk z%wuw+aROL(xuerM(9}oZ2n6|DviF^C()Am!O+Ecs87SZ~GdlM1h; z!&X+EfKd;aU}t@75HK5^TQ|tas%|HHoa#|-Y4@ruJ4YGa-uAdKtDUu!(GggBB{K$h zlU%Hp>Si`R72a6Tyd~zNXyZw=B9vH*#zm(&i9dDMj1qsUp}KRXiaHXkDkatt9}k`} zB-9a_*~HGbs#teQ7$Q$XD(|CDs4W!#*qK?f_}7$Uo@q&Kx`L7n&*2hgg3VHz*EM9( zmru#}=Q?l=HqO-@)L$GbkhO{%ID2vKZ#W;l&$@{j-h`PF8V=w%i@nJtCOU~`da;}C zW0XZZiZN^`C9|rCi!o_D%FPmEbR?KJ>cU9Gc^9Xv(vn%sH?esc$_Km%(t(FhU_+y# z-~tBRHI?Ugyh85rq$^9Y`?AWf0d!_MvAqM%{UN@JfPDP)_8x8Tkd5)x&RNa=C)w3k z?bo4Ow@VjA63)FvgX}Lu354cpotU{Ko@Vls+&ne$O*6}=i=RDmz90tC*<%?s?&Oza zRe4evDtHuvz4%mJ(ow@v@cc2^Z@bLO3tZ$lIhE}%{765JZ!FgFM z+-BPPYAnP_&_O*o<|Va7g4gNr6kM*er?@1;v8bU%X*BG1!)j|Yj-R%3gUaG&$-)p) zLpyV%AFe^$erTvgT#?=1U0h&NRekxe-Hj$OI53nqTO31GrDUTW*Hm3d^{x?yHr^%u z!j80~4m!Nur1ENJ>9$|QwpkZVWnP?oZ8S3pPvsU11K4b5=UTY=#kf#H<&u0gmuoHF zl*BELU3tFbG`vDfVNh!*n`cXP7d0#%yGfRplb3SXYOIaVoytjS=+aGbP}i5aZ5X(H zK3nMNUQpy(tI^|%ye!|5K( zzTm29o#(Vp8tkU4$8c{mS!rco{$Z;fovd8;jDfY>j)d?&2jk!jR`p{XqY+P}bx_xS ztFrAR{rz?gRu(xrwePLzdzm)^~X^R83NcI$u_l!%J7@W=piYaLp`RF~jdk zQKe57KZx;7TVl`Cge`QfF-L&r80O;SY@ubO%^Zcs)x5mXKkS>p!ru@}cCx#okR3s; z@eSPkQWw^Rtc!XsOjl&4-TV~}kn$_nN$*YZn%@*!ri04)1AG{qtmk?5mTKygd|%qr z+H`*08r(^>Zmd~>gmFNxn#T-NsIQvB!{HQS(@y5~|A)6$r z)j>&Y$l8ZAcn3d9q*~`sru|5 z!lqbp!!2`d174uLd9OZsfykZSzOT8cQ71cO?TzQPk!38Oj2MH)kX!aLk4!;Z+UCm9 zImo_9mU6?zsz+M~JbroDsc?wriu7C?=FFaczP**MENjzw#Il!e8fYW6yq45s8WoIv z@mH`e!+8)HRDyI+Gg_wa%B9KNFkYJ-tqG#%EaK{Rwq<U82*DpPaZ-4ZydS3wu@Tm;?$JZz^c<^sFah)LWp#9< z4dr|-a5gu51bNMZZZf93H>pVCgb6MgEODO2?m?vbozQs}Qe4I=iMV&6J%JZ3q&UNq zKsrTfm&X&j(?Tj{@_stTW|!s?LORPBaXy zzMBpGPP9nG%9LKoby4Ey2_-D*owIuv*{znQlg)9%j^kDfViVP7H#pH47TFIM@v!+m zwo$3x)n*>FL8ew4&ls;;$f;H-o;7&aB&NZ|pnU5mUk1u3FP5x?4fjm#Ax}!CrwtD4JmZ(~Jz8zhyid5VRA=FwQGz@Hc4hlUs zJ8N$nkqvp85UhNqu~SlZnE8a{z`v0TtUlO#rLNWSolKW_XwfZ4uVV9D$3#{vD!%_l z16tk_9W8PPlwK56xPW-i23j`;w=8f=xzM-K-V}(}Cd7CV*DVeZ&%F{oucefV9%GcxIRh1h}Nof8w&+fn=cd9J;$$dld@uQxFOO1A7b@IFF zbUz^Nan1DAT5`OPQZt`29=V1k7`(ZvcMo=%sXJ|4tggkjqU)pH558bNi%sWdscT0s z&jG2I9;GHL;Pj$3ZMiOI75ipErT353W~G*DNo1auel$9}6uq1~+bIpg#tY*UHK6e8 zx1m{1=|>W;+O1iN7*`m%=7={QMaS{@3XDP>Y12dbNFuha(HY_Jxpi;>sFdoGNmW7Vi2#!!mX{sbChkJ3dohL5SmM30Z8@#EUHMS)B| zYj`HjKkp}%6HL=O4Xtv@s*(=t)^(CfVaQ!v>R)Q(`=~;*E?mY_W_}gk+{cpw-e$KD zhyOww@^GmKddAWF4MVXi8F~0382@eUFrULm(6z;vT#Ou z0^K$;j|a_A=U(!K4YqnOg6{hWw`1>ZHRT5!Pn>EPZzNVS2T6RmkK71s@zFX1dGB$> z40;x0g75~D`MF+<-%FcBL}xsKdto5v`M_PwlM`|vfe9d5wn>L^Q!g< ziz6js&~VpUG0a5veMK!2^BOu}jXP@2AbQkcoQLf)SMHbJVrNGPKJRBNx{y=3#&eUd zlg9Ny~JY~Wmu@eP#)gY0B0G_V8L%|&H zv+Ow`bW&|*z8ISN*mF+h2J`TIhekd*i(Qi~v-|3CwZhC2%ZpDo;VfA_ zY6;b#kWcEMc{ovss)O@Sv^E!>fzo<*e0J101FbH$vnaYWb*m8HIkQ52TVk7mR#>SW z@qpJ}>@Bt+sp&LbP9c{cbY{@T;i<;8jsC8ej|ZB=fqUDnZe!r447!(UPFI-x9i@-7 zyyX|__^OMUaWr{0qmm5^Pe>d6x^!3^ug$t`2vnU}!5-aZ(QpVIfxwEfIRddvo@Pf= z4dU9_Yqs6v&5f91g|#CNuZAgNtjVr@T=9xa!8&ribaifruhLL&wyf?hZJ2C58ulE* z0_^e3<`)g)%27IUgN3%Bo|i0M($R}$_(%@#1&N%l;3I=l)+p+@{n}dG?2HT2z7%FP zWKQ8uIXo95lN)t<$HjEK`WrqRfPOvpa6rh4@MPflPW;dmc}#cjnZWM+sE;o$&&D-! zSQ+#50OW=X#(wy=KbbQO)F<;9hGif!=yW|5XgaJrdiR5Umt@zN?I32&0o|1x0n>gr zi~B^(26<2R+upa_+$Gq9TWJy#mgLzCzatWA7d)E@OO>g!VIL)rJu+(vO>07`jL&$i zCO9F*@iQHED@EofW+Y5F(~0OGiz!c_uw>dm69RjSbnM>pNa+Mx%1t;ig^8>fL~MJS zyv(e))t#nd=`77zlFf#Kh?P!@O!~@9i<*4XqCjVCmQ_DLVplAxYRqgd2+I@yaucO+ z3QYaV<_d+}5}o7B?&B@&@Bq_s>`dF<_-B^yJM=Z2k?=O>OeRUQ(b=``T#n5)dLjr# zi;^uh%p)~Tm5j2Ysh)C?NnX!Xou`=mv+r;r#n*vKx|3Fc812|!6WyGpVP!HiY0=8- zGzdoTebbl~S^f60lL1zCSd-now z^_0i|{~!su-$FQ46roatP!u9WAw>5S-E<*@j5`e>t`BdBN-9Dp6B@Y@2kNzpV)u~f_ z81c!m(<*$sbiCUyb+hZfeJl0k$%aL8AfVd&gQ}cuSbEt=X4iSyNZzU@8+-Ta)+HVJ zvuq^a-(|=TDc;Gj4E;{-m(BA#d8-<~lgaZzg&9n7+V_*+#87GHDD6`#AK%Wo1{CJ8 zp_$}mQ&d(Cp3oa;Aj8z+cLum&zfDX3X{Wlkt+4-$6fu} zwc@x&IPP*lQrE(EZ`kiGJSDVZKQn~$$GF|6Tc?i0qQgJNPQ~So{CgXcrCjA$hE1%n zQy&h%#(NuT9PhBL7LNY%>EuqF_{j4bTdBdb0;`<4sYNA=(lCcks>h;lgjj+~ycnBF z_f)&X$;nP)JSLPpbZgY;IJ#86enN9w-0de})}Cx-g$pg&?G0Hb7x&Rn*OSMACEgSc zb*I}vv1txZo`oD*LFKkz6N^bs4hqw_VWX07gbMv=mD@;?bQ52zxSRC=i#c>3ye_2C ze}H!o)wUQyw-@%$7u)aE>TZCdxKJIFC3wZ14U1^9LDedTx@ciBafnCqj~LJ|ImzEE zBv*JIcapE{AZfJ+19C=z(t`jyB?kf08zKtb316fYzkH}w;SuD6lF81Hq?kJm$&G)~ z=_K_iv66Q`e|}&JcXwogso_lu$vi#zTFtTPy=7VS3(jQ^P%k{1yW|P#)ej?iv1*%* zUr7_$sc>2%WUuP23rSa8yS^dZxZqt2Y3r+4rsN!|&tIQ}ajTl8?4s?|d}(oDl`DEn zzI4s;X{jz*bN#L9Iwiz&Y1}-}YN_5lP`oNv@pZ>xagj{;Yw)zypYljTt#558t-Mvg zy(!$WQ+&>DnEC9Vd_hM%ELOPaT=*(ndc|tmL-kjalYu|$No)R@N@wd!K9=u2hw4i{ zvxqx0JTG6-MdV~fw-%?Zuv?t!<)1@H8+Br{ z;A$)`%E6jX-KsHM+OaJ8T&^19)p}j~u4WO}BdSR>Cr69wd`dQtlU=-I5><;M=<&At z?ni`~Vl6+L?P%5VV-=f1wNJ5Qi*$;!$ZgA;w1wNuz(ix07j zAsRR``R?)2gOUqIrwkrFC|o5<{;P6@Bz(o?!O0W1!W?{1pHaOAj2bvPT`DD4(~={+ zC6|?wOvf&1S?4I+Zkm)t;&OgTgnhpn-W2b=Jv)kC!|7C5;n(a~cbFxnPge?O%z}4S zj)^C>7IVJ4crmeL(wUS-r^AY0vQe@s%w0*QckLF>ZR9S83rDvLhqhx8m!z<$b!XwT z)vZ`^wwp>8c=7Cd;aO72T0PlA%NBa23y3P$fRm-+qObjytQ|`C5At(W^d@_bQ?ew; zHqvXl^w_1}@S!96j2sa5a|?M&Ytv8IkA=?c=hj`(xC@<9jrXP&e>OXrmREO(cUhg4 ztnO^KeNA<~EYmZHi&|am$C0K|Co3jZg)6g#Az)FalFrT3Q5BzFvLQE%NKzT%)Us8} zUue{l+Crf$!C9lSq$^N@D+$llEY*mDm}H9 zY)NS;Dla|fbAtblW zWic$=B-g21JULhKRJi0httHRwUc};|;;Z-KJh}#phvLcE%8yA2lg6dHiZG>GEhj2{ zu<(eg;MyYA6~zz4>urVZ)sIxOz$kvG+U>z`>s`_dRJW-ay0F?CEKc&%?j$j?*d<5N z$HlEZO1BPwjDO*4v8rE~RbBdVrnPV?zEF!6QB)QBT9j19XO>byE!tjbIpvggO^qyZ zFiZVN`i*$@%~QaO|0dkRDdUO{*XnHU;*G~G@#tC7bA|q`xUW#@#O&g&RopCG?ct%M z!PMxfA|8;b*vb7-Cn%E(_#FH!w0@p95EcS8bggSRDOd3b)gN^jGoG|!xL&fYZ%?7N zE}TLw9O?^?c<}^k#csqBo{bD=0II~PuyIxBX{x-Hv+o~HTe!aw9{iAg7g{o6S4|+# zN?}qOzLUKF@Z@T2u*eqy<{!#SdVNk8hDQ}8BSi2&zZ7yjD9J{x9;UlXuPVpxsy-*E zq%!2VQF7fQJx-Q%c(pq?Hey6!cHM3CumPd@*Y3l`v8LKapW}F^wpEVV)xHpl9mUYD z2gcJjiSyMw2DtEa(XeQa?%Sy68>T8ccK+>knh{PkW)K;tbl)>zWRmq)Tv!uktp3 zb=&5PIR#g>!lwu8ibvooClQ|JlA6p@EXs-EaktWgUxjmD*@@qh!+iM`D^9FcGf~XX zS<#Eqr9{=wgy*vsT7S6CvxvF%pkm_>=dy~*k`5+Zh^YSfRiW*-NESUwN+nO#sU~;% zc4+!FzPys;a?vfn2A5Z=&sEWzcx5D6M^rp7KY2=O$Xc6hCn~!MG&womvg#A?TlGrM z$|s*l#{7!UBzwmLjvqeq)NtS{*IM=8lUJy3h4~}L+!tXb$ERf2-8s4Kp?`8Ewoku) z$%C+p&W-MKe90Uonam{@Yln>)5+1w}zG!V^=Op@llPO=i?5mjUwMuRS7@XYbFnZ+R zVaMk`3@8~GlZW#sLt=6>N1u_S(qnI3`z6C%Je^mvyHU+)nL>3f9LcHXaSKbZ%~5R< zm9LsE?fs5wldRRoNA(tJGVoXP$zo>^&QdM1GpOd%OKGWHQ_ICBTJz13YHTmA3#q~6 zp&F~z#-iwPHk-&_1SHM7c%A2`INY*Jd?;k+H@Fpx^lZ$zr*DD+`A2wo0pMC?D*vVwQu;`OV;R#_$i%G7!7jLmlYFn~|&F&KF zb^Mq@d3&6s0FsC;;%HnVxx9pO_t(h}?vf^0PViO71^kd&v z%N>RvH=-@U5v=9V%0dTK7_~Yjo8cA5VUlT9b}nFvI^OKUYM773ZNuCHFiGjx=xk5e z@GX6Y#Lv&mP(>>qCQ)(->Ey+oLdwFHb1opM$YBAJcV1=j=P4F(_ewHP$qs@f_tTFY zFm%AM(K&9Ujj1N7B@QS5rN>T^SyA#=IutMZiMUx5md*K-P(VCbH@Q~Puao=L$z=?_ z7d$)zC+seaDlDhNgENu^dGfTzF#|gF?UWqK2w&lnO!$(GhMa|Z(&>io&FA)pemIO> zp*!vrpUhWi1m3Y)r6c$HbGDxB7S_$V%gL%ex;DbSmFd@L7Y$VDON$?fn|xKS<}dCe zblDZ#d5i7ri^+!VHcVtQxsn~hWEZmdk%Fhi&+tTr%Dz^KaK&ZhPMwxCz?i5}d@J-d z4sYd86th`;Zbao=CZWmu$dX5fWYZE^o zKks5zvhkesRO##@--Vn{`(gXInq2`bUPmij0IR)$!Zp!~i*dn7vJg(zpQ8tj9DYi2 zxVL|Nw%)J-r-U!^%7oTOZvC;0$cKomx>GRm1}2} zHW)5CEotM6m*y7Vt7Vtw(ql#Tpq0H#+D?>G;cMQDrT*~I{NAfdGPKQ~bkbV9=2WZ8 zV#{gbTJ*ML^6HnlCN(N)mxU&^_))f^`c-_Q%9W{bd?Kv`$p!Y(ceBR?hAR)1D^r!K zo^111)bv`e%+jk+Nky;xxylJ9wKrac3iZ75Rj3>#b+uy6wAjJA;0&M4Uzw%u6s4@p zDmzpqR@LkT6TMo_f~qxEqv5)mPu6(g&iiaJ9K|7gu`#d4SdC{&)qJ*)iJ~KPKDE7d zIT>`bmR9SJW=(E+ZK@To4>GxZkOr zS|vqW5!dAvoa}4j^XEiAZ9p=Al76<@!%EA-n;Pt|7w55uC3hsnTi1V1d+K3|nt0Z= zTg3s-D%S&+TZGM!B{E&uSfV3X z`nIznX?a{vY}2cA@+`+<_LjpOJG!tuqmT^BwYY#59=Ea_;*{=)E{BBE0!sSy;sU$c z(Qt{HS0~S-w@J>UCu8j{oi;GhT>{&(MzQ&>y7M##W``@5?U_RE3|>?uF+IK^I0loohDbcNb{##Kk>1e zPR_K7XI84M{fW~*?U|oSEoYy?og9Vd#b;07DK?R03nAyiLGF;+x__V1eX>UNdebn zZ@23H=pxs5HL{s*`4+Y}6EBk4;LvaqHGP;)(pf~eN**YXvwa*MVp#}Qp~9x8I1Aqj z(I>g-A(rw;bbo%xxC62Y^5p__9&Aq)V!(`H)t!DPN4`Ec>$~9lhss> zCKeSp0aV^UT!tNMam%v0&b3n6grccf5LJ37*>WosTE$-UV#dLWt;WS{8CGeM*#{}I zY7n-GlonT((yA|X+Z9K47BOX8qN-Ao z)ug-@m7^-X@=v_7sM-+{?&a;Aq3l>#^%TC;v-JM;N;3x+4oQX1CZeU6R+VMfSkw9T zu;P5XYtFnnnN}BOEmb~H+ZnYJ^yIR9;Wn#ug5Gke&Cqr7l#zW#bk5IJ;h;*z#zdvC z7UuQ&;S6tQVO+)yiV1Hr8Wp>Vl56K-N}GRWJ$bjn-I5PhJKI}CO{!L3VSJH`%%wk$ zBW9g3}h2u`?7_!K`|HS=Vwb@^Wk0ndT((IbpvP`HD@Ipd`^0X6awbVM1 zWF!nz(25SKU^wm}?A&*7|G~+l6~iMIldpTPxN$bQH?>o8SS_hoWDY_a#;EVteGY}K?Z){cwKb@mAN<&t=^Rd!IgXL`i&QR!pbk_x!=d&|Yf zAa!Fva*y=zQ?nh?<>5wn3~9Jkq5ps(1CrgqZ~=7muHmS7@;%=JhllzZp9wl}K%dcL zMh-~s6BylV)R++?hL0RQpnq19$%k6*G;++a(SwH$NWZ46^(lk;#5>{^X&~+z6*Rk! zI%!Dy>FiQsu-kIT@Z*!a$qV1zR!c$n2ucaNCcv1NF&w|C4 z)w~;ht}w7O1`3Jr@hb0?ezZ{fazLS+fr=-zF)w5F;qh6gRgrxcWW7@m|^-P9@=>AZ;dD#swPP<;SO z9>kbgWm!;&Q;?lp2w6xo{%c8=g#~L%`oYd=D{6CExIUT|U=oJd8erho#L- zlO=7s;sZMm9+uo_GdLVtPkRGDWRtG=gq@n=l9pV_;a&QU9Dd?}Vac>-*syd?@#>s(rPP`sN5eH5?P}DpfEQIliV?*2aHXx7A^YL?IfwROp|ZVOoo)C!)n>K|A3)M z*$o+xw#8w6h7Q=fP12jRY#Gk22j4pPE&Lo@@!^(L$|oBXLZMqi8P6^D%7T(Y%-#&K zDJ{nAz0|S=nZ1*I%A(A0`hk+d%-&osJ>+stJl$e!8}`P+9UIwvXK7x$Dn7d+nR-)&q>Pg1rj1CxV)euU+4ma6r`sfNE%kM3GUA3ARkF*TZtCXmdM!z(&6nhaRZM(H zM;LbVGFi>oo!xU#Ix6#RVnEcmwY58y4}|AIG%{}+A%ynKc9jSvU*&Ee{I zfv=36cJRL^#yBWOW{+o(*!;Pei{5vaQ%4~ZoT>(J`p=BtyGMg z^=)1F<>)tu*MV;fx4yNEJS6`u@!1`I1$Oquj&V2&Zo0$Zrh77c8|+^Jx4zv9x4zvE zx4!)zZoBv%eii9%6dGdk3UOFF`M-Cp$BlCMPLYRSmhawh%lA;Y<$FBb@;w=D`ThcK zoG*nN=c^(wE#I5rmhZjTv3#F}UrpRXY{M)3lK%&O4f@rSe}`9i+qi84H*U?~#%(XS zaXT1p+>VADw}EiuHZ=0mxSawwZoj~eak~+2eC~rAhsWT?;f2Vv`uSNQie+W5p*Id6 z!Y3#H&c=m#aO1ELZX8ysn zN5jqUK)CrG2{*r|MqZlVbKvIpQtX)DN8zUX3fy#Ghua^%2Va>u&xdP&)m75+3h~$e zI&kebglm6Cxb{23wciD<{UhPpKLM`&v*6ml0IvNj;M%_iZvX!l+XmP_c9v;J@c_)YL8@SEW+;Zxx4 z;HKLZZao|azYRN=!LNt^9)1V>HMsh9Rx9S$dQ}d$UhNopDBsZEj*j!6-OyXFI>Yb8 zpTpsnV;{KXI4JUv?p@d!3BMbD26n7hzl7g|{wBC_xF2pDW<;LF;r1AZ=g=F6*Wt$D zeYkP>0&X0>j=VGu|AQNc)mAT-uW{G}elKy@5pEpzgd2y0BG2ORc8o(0^v2Hn`;*tP}> z4A=gyaP4=1YrhLz`+eZ{OSi$TClA4`Cr?G5)su$dAIa+_^wyKV!mTGC!OibiaP#|J zRqXpbJ>;*Rt2S=X8p?i$OQRt1sAh>ZD4L1(s;l|;D z$V=mJIovqhfF0Y*eQ^7Yr{Kn67Th@eE%Gc5+5XEv(Hn+Mju`5gy0zn5S?{PXSL zK=Qg8z4^TZ?mFT@xcPk?ZhoJMJS68j;uW~-h&Qoge*X@CnD~4Kp9ZhHP9b}R@;w>8 zF?gxkJOhTFa_f@}XKxc2XaYyUyG_Mgt-FT!0P{T2QQahMCg z8U7jE_0czQ{aJ0@V!0fHoekjXo5Ae|`oMpSonOMI!#{wBJ-4jgt-fB-pU2@NBM24`1-HKK zki)y>@Ig6z6x?zg3%49!jl49@Z=yHObvG#H*ElzbJhM|j#eXaLcPX-12Ih!+XO`cR1X1&xD)q zm2lI&JBL3Ex1LOgTTd3ke@EOl-nbaIE#OVz&aZZfJgaZn_1eABJHI*UlxcMCn zcRny8@{q3ctJC1lug=3x6Y_N#-2C1IH^28|Ka7u!V}Cmxz4?6xuARS>*vZ=IyXdv^ zANZGyzbkH1EHC4>CfvAf0$0B^T>bWuhd94P+;)M#4Bs0&#`$3Q4D|ir#(yN-xSbt& zR^Nui_)kD@+$O`db61I-EdCFn*Uk%YrZ>Q{&a%dZ=V479L^u$Z&Hr$z~6$;gZ~Ns1N;s6I-3>a zFblpVd^UUlT>tNcuZjL4_+R0FfNuu>3_b_G^5#W9--d4i*PlUf(;Wvl-OJ$bVE-<- z=e{0=>*ot_=gF_bP4^S{yQI4i{x|puF`p^<0f(G77t8jId>er|@s#>et<}tndos&S&VGz(0p~ zf`0+;3DvvpHP*9dme3xcNN^uK(lUrh7Kr{%0=S`ur{2_Of2%VjR994tv5E!27~& zN8{n&qQ4^Y6_aGb`sMMJ()6w^;m<^V3wFN4&Trx2tYfyX_y*kZ_XD`)^6wm8w@EP$ z|Hb|maPzx2d?ET{BG2-h&GY-AcOPR6+;(~?+!(@a`=vL>-j-&?F`7_<8%0Axb}Yye~*0q7VbP@9()}7ui?%I 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

    Set>}Q zM`f*EdjETW0Y8v=z5Wdp@PmQ>Kmo7L)n@t+5%8+6oBW{yemvlZ2>8j&>+w5Wz!wAl zFadudNdI5~Ujg`Z0p9@lqXhf{kpH0qei85=Bj9fV{3!Z6`U>aez1yz;nnC(k3j8g= zKU&~l0r)Wjz7_DJ1nFN3_%Q-rjn%1_-hSl>_>F)+RlsjyUO#@v3HWV*A1mO!il+Nd z7Vzp^YsT*s0k7J6lRr(stG2@Ab0{YK*Rglo@iQFoV+FjbE2jTs0iO%_Qv`eg;KvF0 z3ju$sfUf}jX#&0h@TUv-1%OxQRQ~JOyRG~e1O5yFzZCFi3ix{gKS97R2mHnKcl_6} zcU%5f0X{6?*D$ZQA0+~Q9q^Y5_%{H*Nx-Ymn#b=y1^iaPzc1j^zLMzwK*0A0{6_+Q z5a9nK;D-W!n}E*%{3il_9N@PL_&mUWCg6(!|G9uK0em0&JNgRe<-OaE-%7ymCg7U@ zzq^262>8ANehJ|B6!6Oc-%r4|0Ddn4zXI@k3;0&R?<3&X0)Afs-v;>o1pG$84-oKM z0RL41za8-V3;2F}xW}1({!)D!@3`~cZO7jL=Jo4`fdcO5b(>H*N^`N0)7?nUnSsI1OD3rel1AIwYWgow`;`s+ zHwgIgfd8I=pA6E!M8FpV{zd_RAxQsC0=@$9w+Q$Kkp7zm{CwcQRlqL-{A~jM7Lfk$ z3;1Qguf}xfzd-f31@J!*@GC(2Zx`^Zfd7XAehu(16Y%SR{|*8F2H<}r;5PyOP659a z4=<{<8$vPZt9IL4m&<@IMjol_38Q3HTh`qXK>@ z;MJHq{pY;AciZ*z!wPk2Ec~}`~tww5b%ouUnby}0=`_p-wXJ2 z1^jZrR|xo3fS)bk*8pDK6AF6#t_OUTfZqW4Y5~6)@Pz_?8{q2%eBZqj+uu0?egNPb z1^i&Z&lT{)0I%-p1ug$6wNzfQof2K-Z$_@L=u$GqNudRoA@0e`E2 z-w6EY2>NfE0soA^zZLM$3i$0H|EmRjzkL$h@8<;kK)^pQ;L`y=MG*ht%4du|GR)+1N{FG@aqBpo`Bx~ z_(uij&&`0}Ebwn*UT^>YCE&e*XMOzS-vYirgSvl+u^V;4cLJ;{|*L;7<_n4S*jm;1>XX zgn(bnydJ+31^g|*f0BT227HEqe+clI0)8dnvjqHVz>gI0>j0lE;NJjzj)30;_^|?h zE8s^7__Tc!+uzXwzCYmAnxdfnr$K-}RlpAg{5J&sj|{+{FW|=k{sIA?2Y9t7K+yOV z1O6fbUjq2k1@W&0{CEN11o$%q{6fH=Dd3j?{$fG=mH|F2;9CG+BH&j5zEr@s0)B>o zUkms$0pG^Fe*U{iP<|T#{|y1Z3GmYd{1(7}UBGVx`~?C&Z9ljD*5h}ffbYk=-v7Q> zzz+oe5&=IL@TCHNDBvRkemLM~3ixd1_4v&a@Z*6$D&X^g{}KUT4E!|${zBld74Q{+ zzf{0Cfb`c3`1ycu5bz5Df0=+^4ES#f_*)(6<-wga$2>2G@zf!=j0RHa?_*KCF zT>-xa@QVcedXWBW1^gR;Uo7A^0{(gdzZvBJ1_8ef@ZS^geR<<%z5d=P;0G|Tpa04Q z{f|Mwf1AKR6!;?o|8U^{p}?O5{4)jq@xb3K@J|N*y99hO@ZT-qO8|e5fUgAny#l@o z@b?M$g@C_bz%K#(0|I^-;MJZEL9ahs0RLkFzk+%F_3OCe@MWu2mHeV zegohi5%8Ot*W>q70lyXS%LV*)z&|eF`|?9E^z{Ei!1o9IN&!ERdHwwJgn&;6{$C3C zVZi^SfX@c}Dgi$pq<@y+{E-Lztpa~B;D0UPOF;Uc5%3kj|Ez#-0Q_nJzW}8FI9gL5 zwEbNK{Lcyew*dZm0pASx-w61J0KZ1SuVh|tKSl`R*9!c<75LWz{sjTw2KW~R{6@g9 z74Tb_*W;HZh~GBg|DC|!cmKru4=)M$0f2v5zz+ueIsre7c|Crk1@X%O{@)Ay;{gAP zfX@T`9|U|c;MJbQLEEnqz()mqCE#Bbq`wL9uL<~tfWJhL{w08)E#Q{{zEZ%q0KQ7V zuK;|tfNuqSjeuVZ_*wzq2KY+_{6@gn3HU95uNUy!0k8J-4to6cJ0P+Bog?4}0=`ke zr!%j&pC1X1zhS_?RlsKh{yzeKJm5bT@RLFQ|102&fq$ETF9G}~0=^RPp9=UUkpKS) z_yxefUBE8}{9Hl(T?+Un0e>&x=Lz`bfWJ(@uLAsMg7~drUO#@n5b)~&-$&4YY6JZ4 z0)7L?e_sK=8Th{`i2qjL-$UR};|DkD;}?4h`2K+JC*TJ$ub2N`0zMu1_ZINOfqx$X zpAG!|1^js6pD!r?JmB9~;4cRJegeJ(@M=%ip#6tRkpHg=_y*wLU%)Q_{sRR3BH$k= z;BNu`%LV1X4EPTc_*(#fuz+6y_(1}`73BXA0lxCkgm+;Li~7wSdnQ@bf|XM+*3bz_0cM588e#0sJTd zzYL^*jDWuv_;UpOa=>39IRC8z{FMTJ4d53D`1OGQmVn;?_^Sl`X272+i2pXge_P=1 zdr)Hgzfiyr0Q}VgelXy_BjASt{<{J`8}RCxbU}~b@qoWZz)uGJwE})R;I9+#<$zx- z;A;VYy?~z&_!|WLBEWx7z~2J+B?7(~@HYzhhX8+*fL{stn+5!8=Jo#D?Sl4aE$~kg z@NIxs&vXoW{A~pMtpa`v;BOP~+X4T50pIW7#P)ZofFB6>+XZ|&;C~?ChXekH0zL=u z%LIHb;O`Ld1%UsNfWHv%cMA9lz&8u{2EgAX;1>Y?ZUMiTdACbpkX3i$qjUnSrN0sbigKNRr467U&-e_Ftg1AME1&jb9g1$;5!pAqmSfPYrN zR|0;ufNui)a{_)L;GY-pO91~H0ly6JYXp1?;D0ONR{;J60pAMv7X|!U=Jo!cdZud7 z^T&F?X9?QxH$eKI68JX({?`J2D@cE60{?}8|5(6R0R9sJ-vIbe1^fcQe3}Z~@WTOrmVnOz{MQA1F5u4>@CAUsK)_!J z_zMMm1>i3d@C|@JTfi>>e5rt64ES;ZzZCEh0e>&xXA1b`fS)DcR{_34z^?&(o`7Eu z_(}o40q`{fely@}1^hO^Un=1H9-i2K)(Q9lfUg(ug8{Fe=^pg@XBgn~1$;K(n*{uL zz<*P~PX_#a0Y4q^mkaoEz+WNYYXN_yfS(We1p)oNdHTM{&(6CxBb=QcZ$H@ zk9mFl$v6Q&5b&o8_;kRZCg6ty{&WGK1NiX*K9_kt{$~jI$-qBBz)uH!u7EEG>0cz^ zD*=C=fNubNv4Ecs_{jo(A@h3uKS#hX0scY(zZCH23ixJ_{vrYY5a6c?_?002(*=Ah z@P9+VuLb^#1^jy84-5DWfG-j7n?d?#2>7kQUnbzwjz~OzLEifFBR|t%CMrGV{C*f%E*nbppNw`2Q;4D*^wBfNx@6FTZ;Q@mm1=j|uiaS`7U6 z3;eeL|35+g)yMkK|8#3L?$w;`{_!o|$KU(M-MnA;UEL;AW1{2v&)!?}T6d&0{r}v* z8AgHph+r?CJUuw=So&w>r=-QbuFQ!0W9$#=v-)c|{Xu=F$uD3&UH>rsZvJ^R{hj*G zJ&cTbe2D%{f0_PF`bQ`K2H*N8H~(HfRsR1A@?S!5)4h+#TI`X@P7jQ zms|XQV?QrrjQP#{UuWSzVV<|KvhqJ*-ptnk6T22V10Gk#+%{Q1lq&4=UCzp~WAM+5Q~5|7HSfaB-INgaP*0r9)R z;%{RAiF#t`cQbz1So{^B{PqO?$1MK)E%7(~k68RmfqyUHZ?pJcWj_xC#G*hSk9+;W z;$H*ezYp*aqYSCM`pbz&^=AX8-{V#N*%ze$ zN%rq%Bd&BiNF|Xo35cr!d{(IT)SAV@V>88Jl{d)Ux5b(EI z{LcjR|ABZE|0Tdb2>7!IM)BXk{sVmCf2W22C?KCkeOlz-Lv^g^V-f&U2LSI<;K@te;68aIrwpJx8&S^RD6FJV$0 zKSu(;dZrHYuVMd)nA!cs^#7Cj-OYa(<9>dC!JB`6$CCb>zo@9DdCRb!{?|~D{v+tZ z1*Lxg`_1~JKC8dHJq6ABQvm$O0{=fO{t@iwVUU>84AWnUNA;%y_=f@ieRNHT@;@b@ zznQNo&HOI_{^NnajOrEgR|oW8Ogzf}Qs5sB{73JF{Wk>k42X;Lia5AMTCw|58BzZN#JeZvg%*;LqO2^_%s23;W+T4mjn~Uz3@&8gmh7z6yju=w{sIavOGX7LXL{;|OSmc^eH z(Eqx{KOXo`0scXBgAcVIg#rBs5Rb}#I`E$g{1Ytxx`6)EEdE;HKOOjIS^PHz^v|&P z7XiQO>r->JHAHwDD6#Nyw? z{$IsX?*3xN?*igc{b^!<3-iif0Q~n_{P&M@LBIUpY4N9TaO;nr|3cvZKN{de@n6k; zzw>uL;!*x{fWH{{FR}PHvi}61_(v@M0`_NU@t+3#Pgwi|c;IDkqr#fyuby*_^1p!n z1Pb7x5A5`Px&n+9>s4H$FGh3s{FzrelJ@5uW-XZ#K-@<#ozi@xBPT}De(Wt z;@>jfO}L+5Jtq+5f9c;6{bj&Ef*N=f|9#JN{S$oh|25)~zjkAyKLY&fIbFzKIKlOM z?XUZ%#PR>PEdIQAT>laVRr${X{zqtl4*5R~=>IYCDF1E19|iu)=mtIV-<=yQ|8s~( z{))dR=6^QupGge_@=px8ehP2gOMO;<{mjB&$h=?qJxn}G|2B~RYLNcRse^>l-}fvx zm6P?v((h*b-$Xp}FZzcYzYOM8{iy~1tb?(?fc*tN{u7Bu{*}OA2mJ3?{LSn)`>$sC zseK}me-rRG0RL+0prH6~VE<5`{NH>C=KG%Qf_~?(ibFAfDD!^xuZ(z<|3RD7-=?MM z?MD;H|ER;T|CxaP4C0Z$1^CtT!>AfMFABT!>O<@NQ2Z~+bN}5h|7x8z^5?vpn1A*B zB-8&}i+}%o*YDSUOgJ2;e<<^Q=|7Ell>Rj!{a1qY?>hwh*Rp?tn~m5{v;EkMc;uh{ zPd9#C49@uZw}Agui+{g~!QvO94n8XXqnIBROS$`tnf~#_qx3g(`t|ltJ%7L~|1B2( zboSFf$GuGddlvsX_IveQwZGp1{zubs{+j~k|3TtW{x^aAtLG1x`M=~y?0Xq^9R**{d5(eJw%f1XbtK*!G`%=?{xCLM$MXPNhF{|-17^RF@AVx-qh|Gvbd z@@wJv>E|!?`~kE6zGd-W!4>ywKK|D&{+!J!Rq^)^)&Bpc|K{Ux{#)38f{*_O;!*w! z*smWyYX5)Jzs}-c&wju5>qU!y0m%RD!2eH+e=GaX^~wJ`7XMO^e>K;_%>N<7aQx3Y z#}()K_y-b?;=hLd9|I*%f>z`i! zKL-9O7Jn=I{mMVz;vd9*z5c8H*QpqsmzSPE7XSI|_v^ntZt*Vx`B(d|oBsDL{v`qZ?^^t=z_0dSH~j}4kL%xa?Dv~LHrc|r z1x)|h#H0GV1*CrkNdL7K|GouojXBb*IQ(wbpQ|nY^nWKFKWhJVGk&L21A&g;lh{v} zS8*@(S^ae~@hJZ}z`qjs=UDvb1oYQh`~|?T_8&I$|Ek45JD`7^#a{vZYX4!=KXN#Z z|1|;qBZx=wUjY1S|6$XAhsFN@`>A^x_cF_Wsl~sP{TWQF_Nx{6uR0Ou|91iXmlKcj zzXtf#{=;Ve&l-XK9|iQEK|Jzr1Aevtu<8HWN!Wh~pSb+uKa_anAGSsPZCaWhf3^Rx z=|6xzfR6vu1N!$R9{HyOzuJG;^#9S~j|B9;V(~8mezpIw>3=vA=l{BZ{ubg<{#OFO z+JDyc-KncP#!ri`@F|cmCO6@h=7b4Zz<@^VCrOPYmdPl6aK= zHNdadUz_c33(a#v{-S{Xdx%H=ZNR?~_-~?lKFB{Wp#OT}k$>1n>Tl!g|KEZCT$<;D z{LSpA+q-cu^ZMgn3;#It=JkWg-$^`5|8!2jcb%>JkMDx?|JUMQ&;Fz0QlB_}{h`HQ z3;gc^f6-|;ejl^nZ~Q~e6GHi41pNO3{!1Q4)(KYi$f=K1>ti@%cnbbBZ6W%~bP;cp4Z zA2|WXe--o8J&k*r{=vkf{I`Mn`xTJ?3oQPR*grbX?xt1$t7#Vh7U16#_;0iLkN>)B z@oT@@Ec`g;se2jsGUN9LOZxl$M@2RM{^{Nz{eyCG`8BfNul^oDyfT^V57XIC!xPR+ zoxl16|LGS0GWPq`-vDl^>;twQT*3{_#X!H{|$@3 zi2Z)`x7gy}0Q`po|D6{9we0t+znd-mGUms+VT}DWkNCYk_mEVAm)!)YV-;VEw`v41xE{pw$sc;ufB{Ko0bou?};G&FHFYiA9sP9$_<9ltiR6@kNhjy zU%|Yper9oGd^?Euh+lRK>GKhaWdqu zX8#8DkJ`(ue|?EZ{u1`0e9ZBq;s0%$xPs&pD`3u;u z*Z;}DUqk0<=!D>dt{k({)DS@@fn_lw^q;!*ln?v@z8sUZE&Ux?Gcj{Sc1@7Kg5 z|0ee9_3vEZUwIMsPpJwPzwC=KU&6d!{7xbsrGLOz66044(!Wm_`+vlKzxuZa@yI`( z{d)bI2K;Fy*ndTh8^7b-x7bg!{{PS7Z`s4mzkdBP9rzC_#r~Fn{;v{`^4|*l=L7%n z8QA|yK>u;XBYzw4UkLoUbe=`W|Mr0X(}_p^Ex>;<@LyPt{m0h2MecX~`gP)wzu%sT z^}hu8$40RKV)pMBt9kA(X8k*aE-+C1s+m8)hySyM{}%Ip?e841c=u z=ckBA@yp@(HSydEQ2y7j-yA8#5lYAS^cjrA|Cn2 zv%iEttjfO%_TJn}b#{MP{g?R1_(@qaX+{}$qre;x2&3j9}9WB;oG z{g)Gu{Aqh7mVZ6)hp3%K`QOfdzxp?xc;wFj{yD&ZG#zKie_Wkgas2Av5aN-)g#CK` zn+yC+luzWpl>L77ubz11Zw2|E2mI%d2l>Ar(4R-2L;fwm|4rb}uE+kT0{TxP9{JPv zPON{I1OMR-*#EbH{z1eee*y4c3H%!@{=F$*>g8Ae|7`Iu0RC?Q|F7oY{EuS4U;TfA zc$EL;>@RV0;f|ku8~6{Hi~U!!->?4fOFZ%q*e9|4uLk~CE&lrg`qx?fS|7PGn^a||%Q$YWL#3O$z@ZSpjZ(ICd1oXdQ@oxeC?*spnSK|C1L+z@1 z`PKi&iAVWQ|G&igcRTRky#V_s1@zxRJn|O+{||xxx^H3sr2+llAs+b`0RJ7pKjkXy zU&?;J<3FExX3S=>z})T|62>Of8R!z%XHsj zKh5jE`NSjt_vd%Vj3eZc?7cd&mY z`}r~?rZn^aW8#s29s5g|RQ?BmzvjEx|267YsMr4PTkNNq|Iv#uKaTm980r3ErazN- zl>UtU-11w(yh{IrApP4d{*CNE(#QYOH8}lyaKV}RH`CvIE#?PVcr$*NT!;DNnfDvN zju4OH*UItB(Bk(fh~JruvA=@-e&heA5|8{_*sqWO{}lLhuE+krQ@={RxEXT)KtIj+ zk0c)X2kr0HA3gt%0sp5K|Ao}AQm-T2x7bh9{~wD#kNty~RQ31gz`x%OIREq6pA|E^ zznK2X7XA_D{l;G}xA0FfKf>^v^|y(56#o*C|0h8HAGY{62aJD<#oq+{PXd3d#owR$ zwd&;;|4%IZY0Ue@f7thM`Jco52satApJx1zCLYCq3CRD`ApgY{|9tlQ)&Hp$e+%&c z8u%M5{$&Brsn*sedxMIz0C8ES^iZP zehBj|?$^YAn(apg@u>c^ar)_>otJ9A)`0Z?#NvNGVEQ*%__l!Q|C=TK6$d2tA6^9M zA95p({{p(MQZK*wS6KL)nD>i+8SyCo+d%qX0_lI;;y;wy1#i+?)%{jMM1wfLKX{}tdr`X*d{SFrzoMuv?)rVSw;#eXIHoB4oI^?yC^ z*IE4YzU7AefLP?+UrhgU3%{6ozw-NuCH>P6PAtDag7oiwGmhVb0n=Y+;hzea{wm^8 z{A)q_)gv*f7@U_^FJHF!{~XZ&g2lfG_|+rrO#jGRaQr@D|Nfj_@2!vb3%?(HE9U!O z<$l2A&G!2n7Ji6@H~pvFhW!~9-t;fB@Ml_h(?8?;*k8=NS^rJ{MZ}}}(+tW_Jrcky zzt=4Ox`63lx)i5>p@lcozxVB!zsFVU>F@tToc_<*zn@R~&#>_O(zuv<9q+!yewz6o zM?6aZCXjx$C7l`ni!J^f_NT|p?k{Hieq`aNGhb-%X8Lcpq(5ztd;ZB|UY$Qb0O|j) z#s47tkMi+9GT>fj>Kh^M?@taCKD!&qtf3>8_^ncspKWw2Z zrs*|tFVla8#oq$_{{{Y^Tl@>z?|1&$X5nvR-tYSLBTM?XfbvsI3e5P8yaSitYW9zg zi=O*g{jWw4PhXp`ezV^piT$VTz<-m)|0(;kbQ%3_mf!Uje>(81DcxrN*IWFT(G>A%e4e~tZq z^=FR7zZCe@lwLD_f3W!b)40BR`PHA7EdJ%ducqXg{;%GN%kMPy`_-TR#H0AH0rf{s z$ua#?EdCbu`_-Ri7XFva`_-TCThc$^P)aPl^z(txt@6B-vsK-GOc z;Q!e}IREK%UtPWY{0|e4@}D-ujlb?c3HTcy#{P)`{g)Dt{DXi$6ZlVl1p6BT`bQCu z{29PM68Jy1_MoKjdfFpLTG*?Ehsz|H;H7|FCqD(M$JF0RDkL$Nmok`u8Iq`KJSa2>3s?_>cdd z8*jh(e_-)10{*js|Mkal{%5fNbT=8XpJw^LN<7N{O5o22{$Kq9`|o1^{xP%ri`oBt zVkPDu3&>yb1m>R$$d~>S^KBO1jNjcB{+|}!%>Q#1emnE~`NZ$<7Ji>4E_kL7|2FZc z{5Ns=>+RpUp#1k*h2wV)`~AxQpBBEv!kh6Q{S@}sS$H%4w z5s%`Zp)R)QrN{s4ApR?Uh4cSv!2DnTH0IU39`zdHzQul;@n1wdN`DilUq64H57M93 ziv4@gyb|^Dt3T(rVtx?wM>yZo{=+Q)^N2_3Ujov95lH{T7XKLb`;~u-#oq$TKMef8 z|25A4ynyk$=^4x~w(w^8@BS?2e`Mj!_)oL&%bE8({vNRKPc!cq|GSAt<-Y~QKLXOz=Nv_erI&vEReaG`&$M4ul)w+|9(sS%;V>sHJD#%;mzact>0q) zg@Am^3z&a{`BU9$9Q$ed?;#$Q-*S#$29s+1st&~O$``T!(3@RwgCR8IcNy`>zk&Vw z{yPo8->??@Kc#tL>NUrGi~ThHHN+!--cXX!tBFaK|3=`?{T=q#-s*y8`)B&+SokZM zH^-lhaHiD~kJ8`D>DSwjc_96_TKo?NO#f;N|3tv_KW#~W8%Y0rkp90~{2K$Nf5=O? z{5}ep{zHgI@!tZ{e;HO-KL_|10{`wW-Rlz5K5Q{*4y@p){{iz5L4m zEsMVd_!k5J-s^DrU&4OB^8X6)DE>>>ub2M~z+YqW52bl=>g8AdmstGUhPm-CalXa9 zf3gJlZ?yQYWxrqh@fQofjCsHM(`HHkbak_dUKv{YZwBcf^Lt!=ud}~^dGF0UezS;2 z<+lj(A}L zf8Z-P{u60llX~svzQukT&1qWH!heJL>=^0(V)D0I_#2o%$l%TL|C5Ekm-+n--t-^z z2b}-M1M+1Sehu?O48NKFi-|||cLA55-hXQb<@Z~Q|L+0Qf698C|7`)&Kbm-y{-q%O z_ki>-xA+gb(+!*%KePOPV(~8r{`-LcRf|8H{RjAz-@dQn_?^vsmcg6p--~z@zcnEJ zEg=2H7XQ3}@tbP#Zvg%Wfq${Zujcism*4UCOAG&F=BwSWiTyO=_j617w{iNLm{k3z zhe7(cS^Nh#yP#kF`^e(29ZoWO>BsM*z(3+OTz^J4J9vzD|CG4?ezt|5!hFO7`Q2=P zW)hF;-y%+b33DobKLhE%-{OC)*#&1Y@4cDjcbCP#3HVn4|KBYBL+^5pqdYOcoB4m! z;?Gl)Md+oM-{Zi4)E{yAO=Z7d{W+X?6#o+7UkUuvEdFZtd+F!wC+y#FqlNzt^AQi^ zcQbyAE$MIK^p`NF>d%uP{V!Pj@3G&n{yb;#w*miCz`uJNF2BON-GuwqpU*A+oDn3W zmluDP|EGcfG>iYc?DwlbV~I!grvUhW4g6PH{P(lpOTQb9#P;Vm7XDYvM?8?e~$Vy=09e>#sm4?tUren zkIHX4r@w?b6~Ets^uJ^ANA7h&zxuPm;$I2;F9ZLBZ{Yl|W&dfMe(%l9|9!-x{13_? z8NIyttNi~S_%Hnn_V0b4YnhtHufKMzZ-AA@=qro`P0>8S92$p72GKlyLi|9rswpG`dSuL1f08}JX>i2Zv%5Ul(U zARhS#WRc7$|961@S&M%>`_Ffi5&LN#|G%>M$FskLN!9-S1Ng6g2j~9>?DwmG3y4Sg zZ)U$<|K0`u!oOqxn*rm04)Msp3B>AK2ms&M*I;Sp0+3WOI7y`TrO2ul)zk z|8(~IwLiZh9_7D;{d)WJZ{VM|3HxsdnEwXik$(xu{|CSydKdd&37G%!#3O$j$p1&c z|DMIa=a1d;_ZvSN{!g6#Lzq9){hHX%KC$22UydUlrN3V`C6-=!?#G<ua|A_rVIQ`z6*?x^C9{HEDU++JD3jEC$|EhrHcfh}J`d0b`w_Zdk4Vee!AfCt@(`PH9;h)4cy!2bpCAN_CaFJ!-8`3)f+`NylpF7(pN zug@M}{inrW%YMJ(Z@(=#{Z|Ey-`>Qd^iSvX>&IVTkp6=|!2Z?jKi)0I*iWZ_}{vzU$ ze-rTc2mVhi{z~>wij}-7b{~Q3~_l(7#{gCTF(tV5lG|TU+ALIN_W1gC~ zxR=TICmyB0iPKNblk-yj_k%$C^DX|f9(K9O%zJO9KiA@~7~|GIJ${3Le~!g}6Z_5b zGwWZi#lIBz4+Z`=E&kWoZ=OHQ{Ga$=Tz;FFk9vXQcatARJSx96ApM7f^fy@ig^#$x z1AY9h7QTY{Gko|bE$QC|(w`2}-)9?+--GP;JANiw__fUY9X}!BQT&JHxb;^*evSs| zzrx~Q^{5*-zvE|~#Xm?bcBPko{2T-P_gnn^mb-qx(303{xueV*3Vqf@A!Gv;$L%e;_;IO{9jo7 zSFqpj`1#c0-v<2Iz+eAATz=26-|zVOorPb|yx;M&hImwd!_;DTdS$r9;FRAOkp3gK zmSF?h57EVHD)8KnO#kp5RK{)^df9)D*1 zKDY3-%+E5?Z}Oj5(!UaCd$sHzVw9g*|MG}N@k<-$oVs{r^HTl_b$->?3) zTKMLG@q5ye{y`x9MIiloeQ^BxJ?;k1FMbnzH{lf$LR}zo>ZNOgw{Ok9`{%PzVW7I#h{dt*q z$vJsfItH{u7V<>8B?4pUZ)N-d@=MLcsVp5Rd!??AP1hnZUnf zZ|vV1(0?8A$X@~c6~O<%KG;8GWw82xH}S~70QfHf{?`83pBK>oB=N|<6!t68NB#k)CH8+BfPatuv47YT!Rmh>;*ozC@HYZ~`T^Kq$bP^2cNp==Kc4-1 z{c8gLz5}uU+JO20!s4$5`M(VK4?Ph3R|NDQNIc5_BH*77{22#f|C<5*ClHVP&A@*J z@aG+j{r!F!to}_P9{E=S{{rAI8HD{=?DwmG7Z8v9>)5Z?zpH@%%tNsM680Zqod3=K z$En04f7p$N>Jn}CA@w*QAA3PlU%LDrFBOdu%fd6{n z|Md{;zagN174gX53jE&#{@0Jd{*?j!uM&^^ZNPsc@PCw!{eNY@U;FVs@yNf0{d)Ux zGw{E5B=#S=Dp>vdJ@Lq&K0dMixE1){KMMPE1Nz@39{F>C|NFqd$58CA4(RVgJn|O+ z|Lwq^ehl_64d_3Nc;v4D{vQJW$;V>)#!~Kjb*<|1@C!4#3TP2;J*v_Cw>k4rv&teh)4bnz<&?$&p00Yn*#bTA|Cm- z0sno#f7uDxe>eO6>fapVk$=D$iQ^X!0RPvAWB=>yH~SA}|LG|Uzd0bEbt3kE&b(j$ z?L^{H{>O9v2WkC}pMd-i8G-#ne&vE^Fz>yY`9Fks%ZwgC@xK=^{e3cV`afg- z0-yMAx1_(7(_g~8D*q=y`hRQjPj7WWzxuzLcoe^Mwb?tp^!Pmq{3mAN{C}ra(P?RZ z?e8$+kw1t1`uYDU;NNE?_W!EY(Wjm6zQul;$KM{rBYy?(KMnjJS^S@||A?5`{l%>R z?_2y!LHvIW{C8yI{15)M>lI@IMRuzp?lW+3#2W&sh9xK>VKr{+v-b z|JMfek0c)De;e@s2KWyejs4FA^naCjNz@L3G_8WHA`_;b#iAVkx;C~hPzcLQ{ zf5iT&KJ_n+c;s(me~DKA{s{cbEdKWc#{c^kf6iHn_3ux>UwJCd|FNrsmH#Z_QT{7{ z|IffbG%mzxdxwJn}DRe+dUp zwLc#Ne|7=(N7;X@7kGX*<9`zI$Uk6WV*IxO|KHEW{w3`9i~rliBma2z>+$~-`2SOg z{jUa${}$qre-Zoj_-_aP8;i03h&67&{o=ovc;w#%;{Q4DPnd@NXR+Te{-+U-{DUUB z<*&y-ZO_E@`-NY}{_EK9SO3o;9{Eeyug8Bk;D3KQ_P@q{bNtOb|Gi5*^0%^I@4xf~ z{;!{p{d@k_Eq|~7;Qq;->+b!o-V2FG{xu>VT-pQ+2}ck}qahj`>K zn4DPt{eb_S3$gzh_WO^g{_j`d{5J&j-$Xph z{|4Y62K?WMV*f({{l&y1|A2zT@;@H z?=s?1{MT{*OBht=-)xZoTWhd?#LF%?#1r$o>0d%T@@Jgu)_=YKI~w?3w)iKr-;BR` z{c}<+PXEQskMK$V@x-I_=YjN(1?jK0_!qN(s*gWv@s|MqDZu}##s6pa`<351i@yo@ zPX+$Tm*V(;%6`A`_p^yd@m~V`rvv|o7XKmZ+`yal$E?4D>v8%|2*{t^fcaAc@+0S9 zek${Ro3Rtrvm1`nt0?-D^ARRG4TKV3he)a{r}J2o4`j|B=6&ICK*9R6BQK|aflaQ z2#5%Z8qmm~pizh-f`lUo$|WR-E@%``#t_Y_C@QY#qN3}8ii!%F1%!CVV>RoEcQEW4 zkJYTY%m1l*tNZPD-tJ7)-S6-C|K>xeo~Ns;x~r?JkN22N{l5a`ZTgd<-|YW0E&A`c z%&x!Ujn?)55|p>;ueY>+m_`2w6?Xk=MgPue{-3`7=yQd={F_ofQ~d6U^0xXXilghN zb1e0L%Ax-o(Z3}_{U3Aa?=AWhGGS8u9%<3vcCNksAH3-+PPbqB{QIqxPrv@{{lzce zC9VF6wC{gMd7J%)o$1@pJbx~+)PKl)d;PnJ{!G_DPDOc}{yNd$P3lYb8)MPm>q@)+ zQ(LLOJIdSiduRFWH}#LR=x=uDFKea#Zyox(S@e&$=)Y%yz5Ta{{=&5WP9J}FqP(sB zC8FP)|0h`VKb*4b|4{UwoTfkBfA2?moBrjZzr^VO^DX*MuC(hv=q+oFGpMgJ~UcKzk8)W0Lj+w@Pc=$~fM{}+e;TU)8W z&Y^#?MgMe*{(0Bh+rL)yXY&8cP~O)5TG4O%f0;%9wbge0ZQl0%FO&aYjq*1Ad1w3n zXZrt4i~cUx+4Y|;`ZM|ez9?_gKTY(T@o$zz|IZHn7qwFV4-WlHE&4C9=>Pb7d;4!| zrT+I(-q!v)i~iXb{V&{L*T1fn`kzC2n|^P2H2z#_(Z6t!UH|4*>c0x*ZTh=e^jBE) zA9Iske_p-s|Cz>LFO;|GFA@Fb_`AZQ|D?rs{l%g`)A;L$@;3d;MZY=z=2`TAc(Yyq z?V>-^_}3j{oZ{`qwSB>wjMKXBz*{puA20 zG|_L4{~Ij&N8D-GzsozV^S`rD-lo4!^qceVjTZghAMN`4v{L_14*lN9X#81h(Z9i= ze^e{={~6_N?eAvMe~U%`?aS=#pWjOTx1hXDe~Cr^5{v%%ciHv-sg?RGP~N7$+M@pt z7X6d&w(EbbmHH>3yiI?NMgLNZ{=@IF>;IvZ`VU5VoBk$?{yQ!DKUi+p-|1a{{AG$i ze?@tl{=~V___NHSfAhU|{bNOcrug$I%G>l$5dCKSx!a=uia*))KPdV$-TycT#yZ|gs=#P=U%fAZhQEbUJ{Y;XTLt*rmBN9^S%OZiOxKLq7%_3t3{H`iaQEcL(k zQM>+!TB-kPl(*?GvFLxwqJQH`yZ*0RsediX+w?ED=wEHozx6S@{v$r{9XFHxe?)nk z{w9n5XDs@Udcv;1yp{TUpuA0g@6pltS7XtC{wllvCq#dy@%MK}`RAp4QHJrq8Rc#D zuaNqi>*sZr`WHNDum7GO`igs`=}(V;$Dq7T{|eD>j{oN@`tNY)A0+xS+3)$M?Dapl zmF2&A+FpKIE6YEz+Ft&OR+j(68hiO0q4iV(>z}2L z`Y*89|7}bCuU%)iUz?A7y_x#|YLvIxug;?XuNM8a>+SjnivCRfzw|kK`4Lh+{roRI ze&34nw)%G%>-(=cf4pa@|1KNs`mbnZ{jYSCzd_2M74Cj7EA9K`C~vEOQtDqK{Ivf3 z&{F?t8}0RP6#bd{{{ob^>0d7T&Gq9)7XA0u+Vvmyv0w2_{XgY-d-(z>pK1J0M0s2N zo235c`2W;W{|_Dd&uwM>i(atTf0~rfH2zOPd0YM4j*G_MFD&&x`bE3`mqma7G=EF? zzavrJroYIdf3rpZjF;^Cb3bWa|L^s(y?nlu&ousbLwQ^M7fb!k@xR4V|HTgd$yU~X z*H`TIA1>uHjsHB9x7EK^>R%%LN8|r1OZ~Sx^gk^6Gxh(E4*gw9qyG1`MSt%)d;7n0 z*e{mmkCm_4%Ww0k&zPIWpI&~O*X`wZmGXzBl~4EoER?s|f10%4j3587w12Eae}BU=ljzSBe|LMsZohk_d?x?d3FU3}TV?T|A1(Di@lCt_ z##YvUfusDtT3P-LNBP{({Eo}i{#Q`m)_!k%bo~6=(*8DY+1r15EA_`v-ljik(eELK z;2(dKU-x?3uK#+`pUHogIm+MF%KG1q^0xX{Tk4-}segUFz5ZXcQvVw$Z_{6I(I2z$IJMp=s6ec6irrze}b3o*Bwt?kK-l%J<1oem2V6>_2RRZ+|sT zsQo)w+W)!ePrrY+Ui5cK(+?4$&qogZ(?oxXaFhOAi~c>{v)j*W@C&BTf9d_-9_4NA zuM_>I|LtVa-`}CXtLQ&G)LPF=*MF=-zc(@J|GQZ9Um*I^?O!7LyQJxdh|p)eLw`5X zUn1OO|6TE?$}7LP(V>4qgI`ebDW$5s`u=-|{%X;mH1zL|!m7NI`;6$1r5ScXC(^zjhVtzHX?Ws%-~VO_PW`_({_u}Ks{SXVJYC~T*WX3-D}E`a%PYLl zp?|UHS9(bQKKN7R6n>6se_H={%b;J?=S-zPt^5j${>~QtSBZWVCzRaYqW?ez2vzZ4 z(P}B5#^#NZ^69uLr|_jH-v(dOs_&IZ`GjH=s_duWRiZz=e1(+HD^;96O)vi_%G>;> zR_s?d*e^%@cYwuy)Sh(RRHFJ+zoorb`Q;Bn+1KD?O26v=ZIPYsdsL!Ueo*$c=fcv{ z?YEPo{Nh!<|38oRnV;}C&zm-JTIr;TQ%bvzoi(fL)WZ|q62Zq$`~Uaq*^@Jl=yv2$ zNA#j($#$0&4mv58m8GknFs3V>}$Ga2iJwOtD4x zUX?Vq+l*n`>|yKYVf)43u?_M5f9+tM8{wpY!X&#mu{2d|Nqi+2`zJCb1 zNzxyIek|!vgnkP8nWR4l{X)_WpqnNAC1|6hw}Adl(tij2O43cBU*qo^`Ti~Fcar`G z==YNTL1;7RKPCMm=ueXV8T4P0{x|4WNz*{eqCfZr%_p=bpmYvsT+%cw+DN)B=(dvH z4s?4-w*%cl(mR6YN;*&IPM|wWdKaPXL3fq(ZlJqMx&!DQlHL<^FG+U<-CNR~K=+Y! z0<^QF^FjBO^nRfGOZouN10~%B^dLze40?#94;6YCXje%e4%$u9-9dXu`UudTl0Fi& zm!yvZ?Jem(phrvk7|_1>J666Q2YS4u`-7e!=@UTVA4fZi$TKY}ik^j)BL zOZpzr<&wS^^gc=d3G{wRKLGlmq#puZA?b%fACdHUzYSMLSF@~lk{t# zuS@z3p>KlzMbdA9zAfo`p??K^N7CA!*gUD96(Z36vT(%%UER_J%2|B&?epg%~uS?E7Of0Xo3pg&9c zU!eb%^j1(>Fwwj~E036@vxVk>#wEQCXd6kl1>IKC+ktK`>2{zyNP0)mTuJAF?j-4* zL3fdKd(d4ay&LH6lI|dM570d&y_e9ALiZNh33MMxCqO$(Iv;djN$)3gf6xOYeIRHT zNgpKiV9-M(eW=jGgmx8rxX^Awy9@0BdW58V3O!P2FVLeT-5a!zq>mPQjL^P9j|DwW z(#H!e5ZVv4zobt9JyFtyLQfJpKxk6vK+uyVeG2FxNe>1+Rnn({7D@Va&@&`G1azpR zi$Twn^jV<8Bz?Bf;h^V8dW6uCLeB*qCFv5-(UKkmI#$x-KuaY(9`rm(PXL`L>GMG^ zkn|+b$&#J|I#trsgkC6gI_M1imEo^ku$e+H0-Yu4i$O1u^zT4tOL`9IrINl3v_jIC z3%vq#uB7LI&X@F+pjSzH0cc9nSA$kcdLd|)q^}Wrt8-&wxHF=^D^KOL{Hn zI!UhweNNIFKsQRd7W8>ZzX1B8q+bGkS<3xOn2fDwc4-k4FXctKzB=lg=LnM8u(8EBxO8Ri2 z-9Wobx`)ssKzmC1NTIzzkCJq6p?yG)mh>?~`+^=T>EnbR4_YAUenR_$o*?NHg%*OI zBRLN63L z9dw4I%Y>E-oe6r8q-P1e81xcJ|4!&^&^eO6ROn@(6_UPO=oO%IB|T5*e9$W;eU;Fw zK`SM_5VT6t*MMG&zi)Fp{aBn#eU_ZNr68G_Q#&qMnX`WvjKyTCu(^9pva+x?S&1(j z8-Qu5zE&33rmk2@8N@fY1|k$=VZ8;bOI8)vC#wqUlBu^0)=kM&aRakg6-`4nzHdmT z-u6|JWRY48p5}4ML;M<+#hKyxbw(Q!Xah-VP(>nXvyuj1V?Ieq&iye<#A*Ss1M6vA z8Pb#oP0dsv#W=SqYhF!RI}@sIxrBwiTD4_J^71Y9Z1FX{w{G2F&CQ~mY zQ}YuHE$RYdc31;-*nFQ~`XTLWYJLF~6|`ztL9()ng;lb!WYzo<7X6B96?$W7vT6~d zRaIO#70#rt`cS-Mevx0XVZIXo+x#SbBRR@Bl$LNE&7MhtTUD}XmS0%A1nhRU%B@_) z(orUsaSP-&57}U1f&8R8%0R&)Q1|C}Gk}R5LdX zO8e@&jD?BqTv^-zUvJN&vFzB!UhJT$bxFgLjcqh29jAt0y)w28qLIykFAl+A@0~u_ z*>{4WhRPodSFTM~vH39~g8^Gvyos|+sIbjtZP45Ut!fnL^A%awB^jG_uMK71b(fR?MtTE82^WPEbTN zn~SL4SOPf+lb$kNGPM?Nh4>Owp10dN%8V~g4JI4G~C zy0#Fx`wbNn+IrV647NZ&a14ZQKhiZphA<3c+soza0(3rQ|q~z(iMKZAW*72D1`y$ zx6C)q-1SB0^cyi!XTkQ2d&%j=>&Q)jjqc0ML-=c=fYS~Ort99fwM$>6%AG3$he zdFRGGRYP5EA`x@fCoJt^k4u#=OKaBLIm^6@N2fKUu%@zj*)R7OWdIDYs3{7USMuzU zDqKz73k9j_3crJwSIQ)#c>1iJO^XW*5Wl}Fsmy<}%k|m=Lop8>-VANcN*j7Mw6rnv z{Ap}gg7hR1a!nNOU=}db#u~}@HB#*_;VKs|fGyM%l6ynVZ+9;Ut{|ZZ9hli^nOMzV zIUI6MOYQ_O%408*6*CPBSg5>-*RNH^s4HXpu#%OuhTZB^&M+Yt(k@8QJMoL zE9VpX3~K7B9uO=Uo>+62kX5#+-b@!+HA}%P#GVD}YbYdP{UClQ0j+Az(q!e}1p`wx z15>XJqNrClFonUswjsNHATlI_M&$w{yh7RHAKmN2aIhFh7b*3lJr$3PZWR`EnmGzG^`=&7;Z^mBpwwO}D-V zYE7Ta8)UrD4Cg5pIf4kJ9<(Mc{*vnd<)w#wPpgWm18yw`hEm&sCN$Nc~l#;p+Q! zp3xd{m6+z!>m2S+)q%!hqosM&7iOAeZcPVOPrqV)!wo8?24YxR2WzBqs=B6zs-g}M zfpHkD#ln-3t=gl4g^jUyr+`AK8Zti@K2mfOvAIBA{-F{^@%zu{DLJM;#-Fk%j zp)9T0e$Z9C`q;sjl~u8ZMdr>so_egxS1+xZ+nkkqJ9Wl?qM23myHU%ks;KHuao?Jg znQz9bDq@P}k~w|L8ir#dr~3tO?N=|(o z8sB2&V2G>U5uXz$;SI7hK=<*yn({vdie@EK^J@eDq#MF8?tC%N(5<*?011X&%fQrM zl9h{$LjJB)D?sr1Y8J?}z@}N)AM$t3KIb@2*_r6Mu$K zwUsJ_1XLB#IT~??C72;`ZcSU&B;GNG_kezB?4PD-CN40)Auvm_l7gz?6>I!Ki{rqx z$Z$e$!(wi6jv~}w*P_TIh1Zn<|ZnI7tUQ)j6Z!R#41U+x^`z|2-dBV@T`Zr8x z;m!R!jXBb`nBTTd#yG`OWvn&0fo^rr&*VDV!}U8rb*VNGsr)gqtFXTBgb zB4qCX*J8zUYqA=5hDZA>D!?FC`C~NjC%Fw}QN6pLMg-m*yqRCp-{ChsjH^ z>z)O1(4b9)#h zL1U8PF#u!gj%{f!A*<`vT($2Jey?IjWt`#X&Z|VQ+I%_wqZnpCxBRs^i1XY)>3<`> zl7otq1rvnKv~O;o^7$a$8w0vHRXI*ATsB5D3Q`BG8@@SoZTf5P|?CQoL)b8BJ`Qix>a{hW{ zT{DfmF6Q^&YzcLx1rx_6bJFmyp*Mu9)S#-w?w;OFN1|d42$j=dq9(&vFcdeXL6%N^ z;1`u91BGg1xky7tKy&~^m+r7J_D^X1ihYAMLJ{qaQj7SKZ>p*U-v*`llCNn7x{9N& zBKy~agGhl!v`?xN27e%I9**0AfRQw);1jy4@TpOif8kf5I_^N)Sz1;2l#-UGbOKma zHGt)E22KIvDk?A$+-<#EIrin(8cS`ywXW) zOA6by^2O4^C%G3?jLw3BUr@P%-&8qhN|N)aTNtz%X-~s$MeRL=Oo%`oUh2?Ps{CA+ z^O^h}YaFll3WlEqbC4ysv7-$PZVRx^W#|*jg>pF}O}}0~EH&r;RQd9>(L8s~{aLy5 z=??YF=Pbv;j+Z;1ZhudzSxQ`xj3B37MvE=yUzLJMIaTPliYa_ndwvzAgX(P16;mor z-d5DmWdBc#MzHixhb$*?a={uMt4`Rk413jIo|r>fnb2(Vf62<>zB7#czo5?>hX(^9 z=zQB4YB@IunL%0mxG@LJGc*+Fxkj&H)z4eEj$B8Piat~+zG|qh7~*nZ?&BV8g&QZ3 z=)E@gx|-m!JC+mO_&O+E=}8si`t_W8uY5b2g1yZ*<3CPeuA7BPshQBmk%;Y^Agwt` zM_Yp%{A6ut{=gCt!E0;daPSHP@k+4>FSVnwYjSR3Go8saCyyztpMEoIZp1ziwepK% z0THa`gWHVsl8BcWh0UtUJ3eR%H$)hJt z>Y7OSMNIxFGfStJNfEH>!c=O~)G6mB#!sCtlDc|b4uXIK^-mO^QF>u{>5Q_{aVRyq ztb7LZmQT50%G8UdB#<@z;sifV-mk2zbn>(^5X(wElun-x5vYIZ z=;@Ot!j0LVx_VAe$1&nQbwg)@(zH1(pR6aM$|DdRK% z{bt#tj~+F6)Yz$0AgO#TtY1E95|1FXd*V3HXc>5Th%kpoRU0jXq^oyK!t3r0DI8RI z!q7wzUH$vrf}lY$;+VqbnfoGCAz~Ca`LV*7{5dMA&3#iSdQk+%?lFAV6L08>>maWl zOE&~(9r_>|ft2FvVA@5s^KaZ#Hz@~or07G@w6dTr0)O9w%PAo8SDdS5HMUjX5S{d_ zq3+0`drg>`?=L~Rpe=3=!y%n1u6=@&BJAU73nJw<72d_Tk`bl4p8M_Lmu$awEeyrY*E*dO;bw zF*E581WdPB&|%L{n~LJvWU6)$U7^Jd>9kwHO_%0ji@6j{VPKg1y%c7Af3ecQixoPf z36_ec6rAxBBZP(bd?pVw^dz6dsY&6A5M!gh?Zzw-TG7?}x7lpnnzdco8Fk+v5?yDPBe0|$1?a%+)s=!ZegJ6_rt_9?8+t-2f?7e3>o z8-*&17b9|1n*oJvSY^M1in;*nesy~febxJzr9s-Vk5Oe*MGY==9Uk4yOOn%-$ugteuZ^3T%%T0&i?1hi27whV#K2S;Q z0A{AUQn0V7Dt?x`$+C-V$$tz1E%^`JL-|~aPG^>r$Am^78qc8S%c|c%6NORIzYlYH z#L@aU9+Sb*f?7KLOAhMcUprkI#~TM=e!TnO&slf6981p+R<~2F4fz~9rA*7YkJG#) z+qoN}+qux?0a{3GENr6burZE3R#Vo7!mnr+h0kF2#wM<+@GIk59A6wLe~U9Qy#`}4 zy23EWig61<~z^k>S#cP^qy4OseMeCzqTK`j`NXE~CNbPspH;3ncu zR?3Yv!8iu`{5p6+G@AGwhjP?$&1zji?WMKi+_i0ui3#Sh>m{Aw4yG`ZQ!T1evf-v# zD&=eALPc${C{l7&0IM}kmiAu`mVm19k71k*gAq*!dfD3f`fmX!x#D9asPR zmQY?PgC)&oY=3eB-|%n-b4AcpS(G4-R8gV@FEu>~o#}g13;gKa7Iw75=%urU)7k)#O_iA6_p=7bF%-^|> z7qkugd=g;-9$j98NpM9nHF#CJ|Fegy=m6Hr!SHW9R#l0WXC|jlv^NQ_d3V;~ zcrjyB*1pWR{fO(c@czcDsm);9{+#Qx@Jh#&eC_&eR(#7g-W}P&G%v^EcnQuwV(=Y&w%)pb)}ABA;>BuN@hf9lUlHHU zvF-5sICPr-Iu_yEJFES%Kn9;!9m{$s7RSrqHW(aGNYzS=isP+h7sv5>v;|plysT|C z3H&_kT)fX{em0rr*1fax&W!&fEBgMU;wiGbtz z_3-uN4Td(eq7Hi`JO0nOH$Ue(I2ScL8q57zB2R}9BdR*1X?RABOb><#bH-8g z6UWg1*gCG|6_HVu@bn~suN-p`1v{=z+D=bLKbo`BmYi4;x7=(aw*WD=o{r|B3ZZ>) zjX59q_go=cMR2;4(RR6<4l?P;2j@wL(18fA9_SDeB8?TVhnyy6R1)c?)v9)R(neIm z+-ri>wmsLiSJvIg4$XGhSkRWf7&}4CBi;N}kADH!(mu=?xZ=RKX*Pr^5Lw@Vufgz| z$b4!F_jjAH3tC4P4&KJX!e36)SufpR9&YYnT71``$uMIu%T|-h^kr5{JI{#k;}+Xj6Mmiz~GN~kA^H8;eCE(!-Fl4R~d#dGqRAqI%xN)97#)$O-hb= za7+tk>l-o}Ft|{HdKIOs%)2Pz7$i)eKBKSATOf2x{B>PZXgAwTV=ZIb5<%6eM?7>4 z3Q|>ZIjXQ3&lb;})9ghaNauVJ&S~AtR1|j%@VN^{Li$j&t;Zdf)vYt~{S`RG8!;nT zNB^3B5tHhfrM3O(>I$Q>LF-9q7g!oj9KOWqhX4$76+h{nGr?gwMa-(f_->v!(Ord_ z1=TP|e`sN?nIaEma3l_SQfNPw2cb>u0c-J`WpIAL;~=z$$TQ=pinf)wrlsxq3(6>8 z$sB@=u;O3v`T$P1%Jhn=!Vj?}!Qp-2C{@KDqFo3z1_Ul;`l>>G)DJcY({XE)f8{Jx z(jL3G7GWKYeW_V|%c!9s*y*U;UlQ!li1au>;~2w2F9o6RW&E|Tb2XVGrge+ zrYH}s1JqQewa^X!;8Je=s}4>B9}2C#s9m~mILf7B+*)H@$1#YaS^u`kGL}1PBsK&= z*9f?L@n@43?@##Q(Fbv`tvPl`WCs|<7unJbV3yMTMFE3W0D8oQu4brS0(I<}i(9L*aVden0lXpv zL;fM8hX$fqn_su^fryYdh72C`w_$TNn5;b#vURF>b?Z#MI^86Z#)VA!pD;CQ7WC}@ ztf}o|&tdC?iVUX1(zeNbhYimrh%2URwzRRaL^0!lOOJ4JXj7=^VZc>zhA*lj>9I|D zQ>y$s3aOQa-=U7e9k^8JY0l7LTs79Ui_MnPL}9#=0+(g^=9!I!E9w3j)OR`V>qSCz z;G+Abp^NU%kOt16yB}VG>Du;u2FC_&`W9GW2N1;8@Sb0 z2311SX@@262mJN#`|=-VYh7qmU5w88-)qTedcV`TjXe;$F!Bhwk&TXnE23Ml`>ms( zsBW-Fc#7_7X>%R1AJ0K8?`r?se(Z1C>87LQ{%fMryf*KD+H3VKX_(Je{hu_tN*m9m z4tC!56ukrG7qa_ZrJgJ`y*ZDTBYczUJj9b=TWPF&XjFDk5gijRmV&>2xBpugp6=CC zWYdP$7~42~;pDe(7i8JHp%5>enLB5bcj-=Skv@eDGeXb6hP1Pxd9zX#SeY#zzAzPx zb+UVJw3nkH9Ym(jDRdV`FlSID>Tox5ZTf?_mQaL4O)ea)3i)gb-8#29cjmEJNMhkv zSRZ-a3_=wz7lU&CERHG~klDv{8A_BP-pO-B(L&XbYaHku)7Xd#y3%6{fL zIXHxNBQI@fsN6f$86_|)W;o1pyniaJ+gP{)Q}EW{6-@l9rNh7i6BpLwK7dr=N~%Vs z=f8EczA~?}a3wtoQ&^uua#bTe6HUyUn0a+2){z(|O}T&0OVw4=3xntdgSqpTQB>sl z70yHVqtFItIa;vwbxzE!X$K(<8w+b36~fF>*n~sIRN;CQXrc;{ft#p8>$yTrRH0g~ z5HVu~1Ll`1i(dj;b6SPUc4w_v$k7|TjLJCoQ^vWnvH1i$b&9;XFmQJNn7%peAFa8; zfi{6Wg3V~vO$`TgDEQ~`Fug2n;G}%#yy219&ZI&7RSJ+xx9Uti@FBHQfqm6ECM_ee zAoULclU2joLZ$Xh-?GRJ)?(51F9t!{Zkal^R(upLLBAH~rTJ)Qu!u{%=MQ4`giXp5 z8ut(exB(bGtt|eO?Anx-S6!WUkhQ8E#0PCe_@T89`c8#Rf4fdcoxFev_9FbUB08hU z3;V%uD-YdiyMB_#CT|>wM!=jwmxovV;aoaxu|W!7!B4VfeRp zO}odFm1t0-s85Vx!Z3ZOaS^`%4_Qq~e{fmHo`34_-;r%^r)AS@t(j5UG@{K+=?;O; zG`djkurxQh<~f!)Bs)Mf0Lbt&M!jn>ZAO$|+Ry0?fX}NaLc_vKrs!NQXci9^p#9sn zY#N)f{JPmso5YdeVC+a>)eSfM$QGwCwUb|>jy|DK#k0EV2_2)VBLN9bq*ax+AjzMA zLAe+~qT1{e|8TTgTL(dz@5|P;#L!y>XjO|GHGKV*Vj!-&^xIJQP!`&Yph)-J(3L^s zPH+Fs+z(;tf^#sMh=b@v^D<7fC}!|eB&e*e24rG7rt7V^)h~c?j^2_eihtOs$&Iga zGr4X_RLd`2v{*)-e|CnLqN`3_;m-|z$C>?(Zt3QjD}%*8j07(*&t&N4wzRi`_!D@2 zSTBt=+NsLvfVxFo#Y44nt%X-uj?4ioS4%rGr^j*7wdilUzX=zB6d%pdgzE2`&_np6 z8CDwvFR;L)X?&>`uwo_0gCA+9#@?Ksh||IvbMOt~&EpR91-aVSVbeUG4~=*io)uQn zt>M80>K_p$)STsC?lfXU_~e~-f5tEzl!Z$$^^q5gOALe`{IW^e-U{PhPNO9)w)4N# zsKBznx=zzz=moG#MKlgoD0iS0_*Lkn(D@qNXsLSJf&E#Qs==DUh$}4}u0f*mz?Ki% zP-F2_ddy3uQ{=VC(!T9~RX$A*f>E|ANpD@@`$Z~%SDUeqUY$*0@({rMZj^Mvjbmuk zI*%U6G@_=ZC$30_|KvbWtKfPcYG7>c)Zjt`=B}T{k7%jDVH;vfeaJx*JP?C1(4e?D zOh(obMp;a>!3dSngwj~Wt2Z6&6bgy_b^<@vfKB%YVhx2P^Fk6N8w={xoGm1k4hbp? zx8RU$6W(5KXtquGzpzzl`t>b6q0{I(3OnYA@V85d;DdQqG@S+QY5DlkAN({{eUq6h zop3b6+wjUypng{!Z|W8I(Ja&W4vxuWu`wwtY3_;{KPP>e*&{hW$_kh+eD8O zr=7vrBcJ%R;TY~26M|tyHTM1oc9-@bpGWIA>atEQT!`>%11X?X1>Ua3>N;Gis)1o+?hMjm4zvnjX|y=nm0 zDU5mrhUtR+MP#hNvO$l7*ZgkTSMj-cy%{IiE%myyI&CwhR#`6lho0dgeH{V^cAmkD zlAzwkXk#;|;pN}*W`tv`3kLh+!C2wI!hvNo?DZB0O{b@(LR+&{v~_Dd9q0;w-#2ox zpALd5uUoXS78E{IG3OzVSL!I@v+>(e^*0D2H7n3{<#)qlS$%lBsn$=Sv%(g}n5uP(X09KMhTDgk_8ot+FM!w8BG90*R(tb$R204jze~Hl9Va)9 zXQK1qb>^}M7jkF>;99kIasPd?d-{CTBPM@gU1MH4f)z!bSN=zs20h!lt_q)sx8UXf zg_)!UZIwkG&;oR@*+)%iSPQ2j8RjiD9~iTm|4e=dm=SIzV@qiIfC<9%FIQuD@PA-l z)3d5^5~3CcX)~(YbaVSM-r+}PNPEwY9$KQ*nB0xQW?OhDbN)Z}psI(nsXh-EJ{hF%g(fD-7}&iB1)h%xr@r#23tM*Fw_4i+XJ;|^~=*LlvXkb6sN{L(gvf7ksgWKI5oHqx&k-VFOCC5 zUPPgXLUz3p&l_AWWQLyVv`9#rm2Ec`w8iN4s7X;zFp!WzZN~wI>C;96jRxECg(}hS zO#k=L=58s$5L%3?Rb!@HfVF7o^u8W<&hnei3m*(mk=Q8}M<6x!cw41lR_K=Ste>((Z&i z2Sf)9G$@9mH5#g-M)=w29pg8M%7!)$Cc_L&J%`#T)%cyMbj_-``C}4VX5@h<|8~EA zBm13e^r`p(&N5V2gomErY3Vn987}Ovt9)njgI?gPDLO=GBEK>=vE~qs_&>+bkRSd( z&-h>G8RiKW^~^8!5;LBsMFiR`>9GO-;K>vt2i_B&6(bIoDV9Wih!Gt)p^O4&Gr}G( z_&C{)l4g4ykr*d!W~?>Wb~s4lKy7XTWd(>9rNv(rOKEJ-(Xa{x#%e1(5CeOq%`s_q zB?Hzav*pBD9|4g+*7HPO$;Xjj81oeT4PS#jgz?}jO4Vw4e7!9Y z&u5UR1a6vmMe#ItrEc>twc%ER8Z<@?L1X=p={jv_N0oUUp{(zFx>jjSAtYl}vH!^m zO+;zF9e5zFpElw8Y3}1S{xTKEAA2TO-RFN|lsnTu7WH?$ycQ0P3hn61k)z|?*vR-M z+e90kf?#cszRlEr^8ZsmP|sUr|CTvt_uRb?g0$Mbl+)kg+t{5 zu6XNTF>1yr4Mkq@d~?pAideqe6}VPbEw!O37_f9%^1nW3B4UQxqsDS;B5BnAD%hkP z%R;l|h!cnk#+(zx3mRP=kd28BcWKx!2>bgY+NI%s-e7t);%Ib2{^b?c9m^3+MW5f| z{SpP^QSYbSd=SBMlq0mfnvRTu@ah0k&=sv)9keuW25a{q@ez%OQfFYt1QCkg z-!W+=mJLxiT=wxdM1k*#-x<9aLH=)OFQ&2o_xV580z=Ar95HIhH2kbZ`4s$A$f#*$ z(??C5GHuf6v84k~9a47Gs8M5Q&FbF0dk^!6Fb0ktQr5lu*a@Sjk1Cr!dScm(fny7Y zjK+V3M1~wWs&LS$eMXHsZ%R3r?lEf6)Ug-f$7&``9D8wLkHW%VU@a)>W7cn6Dg6e> z^npdE^qF?vDE}u+icXq2q{k>yJ@Y@OSn3G<-DaSnzG;4yNm^{~ud#7U<~z0Lv{|YP6kGqcMi^xJ`nz|ZK6=V|rK9*4Sz0V9{Js63Oqnrp>XcFR zi!9U2r?gm1n?TCt=C~pjPSk7~uOhU8kR{DbkcRQk4X?LW~ z-SWR*PxyNr|0+zA)!ft(;WkQtX_H6CHI)!9OOLc>=jPX|WjXfT$VwT$#=AIUHLc>6 zYPZz2<&BIMLyp#p57rjuQX^x)R_hh|(YaBwa3~vno>LR}d*BEAe%lHo!+hXWjtuDU zK5B4zS?R1%t(jUPqPV?A{YQ-+JGOMjj9;}-YOxuE#&j#BzYIO_3%kqn2Apuh(TOg_ zW3c=!Pjv6zwMW-(hjs5$&fmKqB#7tHtDEV)BXRr z{%JbDBV7`~=Lq^w)$ja3eqYHiHS=R5bomjIf4G@HJ}5t1@{c$3X9oF8B!4F}KN;k& zmi)ua{Bc44dl~fqoS}S2`Qc4h{rgJ3OaF)rOTNp-wUY1hvj)j`wXrQt>iD?i zcaeNo`DBLt2^r)skbIX9E|+{)EUA@z*Id#d`7R%8yRF}T*IeI4@?G{#O8$`~M)|-b zqyHuU05gANkiS6k4>a?Qwbt?sC%!N$2}(!UUjU;)mxW9nur?gCfbeL1gqmTFaOi)M2IMyW-KC8S=lA ze4DS6Eq<0djzIhm)iF6YJNuLvS0n+xzT4wJe14?=R9nejTl~5v0G9|4tr0>zvOb{p z&J&*HCQs~k7DDw|D874(eLlaM=5yj(DSY)vhw9Dij94uRB)<2AZ!f#N?bZ6ABfb6z zpIP*uYF})suGfCzQ;#6qqVG;(r1p&yIekb@KUv3@u^6t;B$3m@X7A2{y>Ae{ORW0* z_1G%m`7B-5$-LHjoupBnnx#&zwNHl~sIs1Cn=`rqPlyj?!Iq)6530&um@_w?y`_z| z(;(qJ3XCCMfBko04mkIN%rfC4e~R+Oz9fOfw?z21v-V%?N8+P4z9((?1nHpv-r;&t z{?C$co7X76t`B$3xG(KlBi@(3+3B&UaHF?JR`DE+1;wS5n4)qDi@vF*mk|M{|)(Mi|)zl;F zJhJry$#>1K%O(G4vpniRQw)`_mHhr``83QZzd`Z~%zR^g(UuMg@VS8g(|tLH4MF9* zNdC@d{y^VOl%JG*Tm2KrFA`rn7U_^3B@U2`g(Bl9q;(z8Mhg9ue}9Jjmn7fT2h^8u zN*(S%I#dVhOW8k>p7y-q_B@y0^^|;@9x6Xn@?HDNvJB;KXrVl{Lye2>>Ej>m$ljNt zw|_qKp2#@`Wwbrb^N$wlkwB4-+}WNt(=1Q6nh^ARf$-RLkc<+^53TD+Mqwahp78Wa z(?e>=p35ZP)gS96zq46>SRnsX$+!6?$4OwxH!z#-}?mp{gTLW*7hm+Vqf|zT#KkX3IEJ zb3Uz~KF?;ukzHqt9NYOD$(bi|CL*1KKW%&RpK}8HuNOHk`@JM`dZo9^pMMWf>z#Hy zU_H;)PgI}w;zxJb>SM%@p(3XOe7eptKiE>c%Ou}6=TQC)lJ9EI5~;^e_VzTY_Pi%@ z_BZPx=SigJXUVtCDGB6vX{&ljfK3hl@~D)8yHyORLVV|G3NgsKUGKLyzWrRciCu=_{F05f zNWRO)?e-wS_ytP(Pw9{O>q#nqXombjlJC+#N%CFu(83J)_e;L3{x3;>fmwgU{#zu! z$jpxo(DAt4o|Ivaf82h_cj+G_`AHI@>~~oZrzd47zc54o{gUq*LoZ2wXg>lUrz&v& zw;-Ql#dk7B&a}mfq#r91;Oi)U)DP(#{OPtD`-)+EQHJMTO8+Ta#Qck22|%+X|1V}f zjmM3Fy_N`%%b!+DzHK~`j`t*gsHww03*b!}*~H%jxzDc?%;dfXP$2oXIwl~#MDkmz z!@LYSmbIXR`b~|C=hOSmpWmNU^WheelBIN}xxh#yfKeeOTMd(Dpi$I^eQ{l*@>TY@s&>!hLtXL~ODPs@;BE%`3}D>9U?%aGqB`K~!Iud~M= zb`#ZpF5RQ~9|{zZ~ceWmk<1o_h>-xUL@Gvu$3eAhWoo#Y>8>K_;AZ<73w z|6txxXDoU7RM39Dp8(!X^7-Bb)qa%EzQ&&)sog_`X9&{T268c*H`lU6O-W!>dbM3h@uzJi*M}2;7Kn_{`78O8agFeP;c?mPCCNX>)M4yjwn+XV zX1;&K%hwgYlX~8V{7^mpv3Uzwp2kj3UO-{bYsxX!`9me&b-qz1`2}WqV-CMT@?B$d zWrqAWGvt3K`7Xb1&lh1m&t>PH8S;lpJ}7~FM&3fNq$Rxy;yj7h$aaWO1{lb36vWl`4dQpsw4Td z(T<7?I+nJegM6_@@?G=sCduz%)`2EFe5b4i856V8$M`ANWLM=ZjL+RBdz>2Qhw=fi zd+jqw@?B>@lO*4@wpl3oHhWTA?{6WW+M>oqYueH*vRvzs4s1~TxDMp%zBA5ZdP}~m zt-~arVxBH<+z&HL@@@S>ZCxz+E?caU{3A^HaxRzvRxkPIn)&2={t|%W*w4b_8e<(f zP`dAl=_~oJ{v45^{A|g0jo~Gd?;69)#J5`-!<$3~hjujvjeGd~3!k3Hrcn9DdN#p9 z+neH?aYYmkjDesJ?^_@$S;z7CQ83?oqL+(yW&E%w^pt#8`Joxgmt`n_Lx%DzCEqpgyqTf=caqxL;dmenAcb%CZOL4HKKJ6*_<3suWMuqZ+O1{fJWs+~RZvy3Ki+|GG9`Y~a zy5B01aUFPc8;m;EOa5u0e18E$b!?V=+c>8D4!p3ij{(Z>E%~nU!!qR0lKh>``V9=` z!^Ii$S4qBW?NXnid~*x=32Hx2FrLSkjFgYa+KH;{`d}H2KKpvBEkD~^M%j^1ws(&M zU+%!~b>M$;;14+PhaC6{2mY`Ff5d^Wbl{IW@FyJjlMbBUz8SLTj`)`4J)9-o=Z_!Z z$oA9|LqQR`ZchBY1yYKJ2;L_Rzff?Vzd7wQEE4<}|0`q$pKOm`iWUHp%JynZHl3gC zt##n*9ry+ZUhBYLaNsXG@RuFK-dFM@xAs*yeKmny1;Z;J%s52WGrHQU=MBFD#fap3J8_-+oo zg9G2wfp>J^og8?=f#*B${T%oK4!ny4KiGjE>c9_k;D4kcIVI34imSHK*j~f=?5?txzJ_-bu)fezLu!13%e;pW?s= zJMhyS_~{OOhyx$$z|VBx!yNc<2To5OML*fzxemO@Jk(dg#*9BfzNZ`S32+o4*Y5dUg^LW zI`C^8c(nt+&Vk?Hz;ATmH#zW|9r&#d{5A)Ey92+&f&bBg-{rvXap3nl@IN{52O{`R zh|?6GH%T~27-1#bdnm$B+1cL14*XFE{+I)Q!ht{Oz@K*Ds~tGaKG9FM_pAf2ao}qm z_<9HaoCDwJz@K;EFFNp-9QZ2^{8b13ngf5sfxqd%-*Vvf4*ahU{9OnBz61Zjfp2o) zA3N|*9XPF0qMvN9!GUjf;EfLaZw~w`2j1kszj5H-I`Hot`1cOH*@6Glf&b*d|K-59 zI`Ax6MTYwz+sk&~ISzaq2j13!Z|A_a9e5`Po^as#4tzfczP|%M(19Q1zz=rdhdS`X9C%j;ez*hg z=D_KSRP>YW^>E-l9r%$Byq5#-?ZA(A;Kw-dz7G6Y2Y$Q*FL2=f9QX+iywHK49QZT`exU=O?!e0&_)G_WkpsWjf&b2d&vD?FIq=IJ_!SO(o&&$qfiH02 zS37X^2DEUj%=WHv@L%h|s~!079r$$){CWp|g9BgWz;ANkH#_iK9r$ey{B{R^hXcRU zfiH95cRBF89r$twexC!s-+@2iz#nqp4?FNj9QdOS{4odqxC4K}fj{ZMpLXDD9QZR1 zyvBjAb>QnA_yz}F>%d=d;4eAwR~&eq1ApCtzv;l=a^Uq2{2d4Wt^qg*ur~}V&;Bg1u#({6^z_)kc?Hu?H5u73(?N2MDH3^~ABZMza!*_)Q z!fVp-LxIzEqTTlMGrAiV#PuEIMnBo!$qsyw13%S)7dh}V9QaTNex?H-=D>$L@DUFD zTnAp_z{fc7aSnXE1E1i)&v)RH9QYImKFxt&=)k8t@G=Kp9>K}N?-aq`U_24Qca0O&IfD0QJU@ajV|?ET{x#$KMez7G1j&O+Ms7Ld z(pUrEz_{F`Zs6_O&=+|Kz`&1STyBat@KYG)J2wr~^F}c)H%}Wm(-~KHn*|wj8CQ3e z1^73NtEXOmlDR$jo=S3UJ}7SVSIE1PwYU@xCmatcxeQG zn(^@w{3FKCi{Rbq#z+6{b)mdc#wUj``m%`eiz4{p!D7Qvrj{LTozBZru~ zBlr-;?}^}R8NWAz$2cV27s2~8z9NF(%J`!Z{3*s)M(`%aUytCO`Nrh8BlvK}-;dxA zFy0Wsb9NzUa|Az!@h>CzSB!6o;K#Km=<5i6J>%a*@Xd_>JAzNxm7pv+g%7g-$aqc! z|2N}pBKX7na4Ov`7XIwBJALOLQx0WRGQMMke83N1b>C`qaye?ekiX`1Ygeh(Gff+LG?T)f?vgW-w1w4 zXX2;3yuzQS7#|S9zh*oc!8`F%V_*b-knxiv_;I`h85F_aW&E@V-iwzeMG^dI#)m}k z9~eJ7f}gcNwe#`_K9lh)BKS>=&yCF%}g=PKa&-g1o}DB1Tgey_&Y z3;r^24#ir73_b`9(yaP{jko5xN z!Se`*iTqE2clLJ4k+1x0IHmsuT**{t54^LtS48j64*re@lO1X!^7}IWg2s87 z1iPKXc<`Ks!sjp^JZHhvH~5z@9z18k;TrhojMr)TJWT`dcnH-ec+R2;7=0!H?;N{E zx2vrWd-H(X`sEo1{x6n)T1<-j??%CwqC-hho#hA5eN2{? zXQSh6^644Pd@s09Rjv51U_7`#cCgfwo*TBwIRFDc-wV!Rz{Z~ez&m@rv^{xQf}Hb! z+vLn};J={*s6z8Bn=d!_I%bMQaR{K0cB z7fKCw=|*yb=UJ2=p2v7_e=oX;KQ}QR+~2!S@b`h|N!lcxy4&#)!1KM2v>kX_N5M6W z2hYnW`+UZD@LY^KaX7FC$qDWsh8g)&!g!SbPR1LwUS9T~#B&b3f$=XjztTGt6G6Tg z#cLQ3p1V=~iJ$2 zznt;l`6*SOI~@3*36FKs^-=PB9#8lM5xk7?DE}9XCnEd@!+`m*;Q0tNhd=WfkMh?N zjuJkXyrTwR8XS1re#F0@=2zoxAI7I@9K)PHg^XVq!52B?+)sGy0L?#HDW{ucc`5-UjABO6Ms4e>wQ~K8fnnNAoLt7Be0^FQe=^ z-@(6z@nf`{+oeiF2H4y6I`I71ahiXS@b^p-{yU8;`#yyj>R;i&moR>!=HFN9v)+Mk0Z#R-7W=3t?z+Q~c8)E}nzx-V;1Q8?2JrmYm0G@v zpPwIp;X=TY%?#!Si>$#Lk}pr+VJGgD?0Jk>B?$yZmc_=X=5ZCu)82C*YmEz7hLx zWd7j!KIIQTFn*G5ufq37!)^U?Ebx5exoK3JKSLRRLd(IjpFfu{J|=>{0G!(EUvI<} zGV!}Dz-@ZHvq|rtw46Ic{zTxmd3Gk@!ef%T4*Vtu{(u9o0giKZU7re3vcqt~AJVvr zSHl>8RO3HMzu&=l@I2%GBBvt`&}{V|?!YGj?;N{Y_q&=OQx5)R4t$LRe*<{F_oS{r zhChEwM)>{McW?jukAhzh+*bcbfp_+f*Y)fm{I3Jgk3FsBt9aXSBh%voP9*jTE>ItWV;I9bsWigQS+<*UB-Cu zJnSXHze_3ckJJ491s}+G@SLoYb2a0yYJQ02&xeeU*LZ>89mkXW*EBv^@bQGl>NTD# z_!`D9(70;vzZj41>xZ33a^BVaD$YN}_+K@CzR2$}f$9_8rw?O1cz#y3cNya!XgLTM z{MpQSbYI^G6KKA-DZ;;;@Yu&1SM_XS{sxUJy{DqW`QE1*S9Z9D@!%GeW6}M1HRI8JWev-jt>q{`%$;N(FJ}SI_Zl^Sk<{l#2mhN6ygeMlHXhG(;5P%$ z_b%0XPZ7Oe5FY!R#+989okI9m8dr9{iSZ_lCq+&Z$}r_)i+|CwTFNcDv07o*xUIBfeDlbEXp> zJV*Q&!N)V6l`UWO^|<>9_i{9jWha0B!uXrIJ_UluXAu83nqT2Z5FTr*@qFRGi1F<- zuKMd4meWq-O79npzZKEDYZ=MkQS&SL!wL6x*7);c=cgHOukiz zj|I;Q?y3w+Zhj@Q&#Q$nDK+PeAV7ven)av>-s4E0gSKFxQZK#fZOc+ z7W3C={v)OSd(0;JhiSdaA0{&1RpWaK|I3UYs&Td6`vJI3Z~HlRe3%2j*@1uH!1qBw zu<4!bz*jo(W(U5_Wp?>{1JCz@=ew1C&SX5go>|Ly@ZOI?vFCObB&UbAC)|lY4>R6V z<3|bpE#pUOT=~O-%SldjzW#ynUYcL&op=TD2hW2aEAm$}9y|}ei{Pbmi9fntdW!Kk zv|lOyuYue8<)C?xV_7d%Fn)}#r}C?2#)Ie06+U%7$vIZ@tNL$Y{CJHk{-P_X{?YZ% zBEn-QY5tDV-hVKEblq~~RU{{Peq6=3g^WknEiW;i)bbVoz6dz^UhrIbf6@B{`pRMsuf*)5!{K50=XA8cb z@sXNe`NRI#5P$HTyTTVRey-+UEpqn1miS9FuIxXT@!-7#sy;sw?gj59I9TNDTupfJ zJ`*)w1_I9$9+O;7{IM}wuaf^VKWb*y}R@c)mAH z^Y1EpA7lJNjqfaYViEC2=h@R4KV0*77ycU=kH+~|84sRjQ}Wy0Nb)bza#TEjpYdqC z?RFFKU#$60mT^%@c;v}{2Y{0lW+Ab8dvi2oXmD|;Rf+}7U9nLiq@-eNo&uMWN4 zE@vX}{MfY-y&o}N9l?h$CH~)Qypz=b3C6F}xUzH39mIcq1V4jtFL;l^ULxmN#-ro$ zxI2k|k(Q(Vf$`}Y-&^GD{zr-r`{?-4Tkz9>=X+89s~IoTat;^%=NO-7EvBBzn@TQ%NK@ELcJoZB^?FZid7-=T4(ch9?t|4xlh5dKRTU#4*-=S#+K z)A;eifA&2j=Vp!XBlx3)$Ab4QD82hGC;V>BujZFZ#+PfnhsgPsaPK~i({Do2=Ye|( zzhC2OKDrD8$~NA6{E6`BI9*D3>;WyOt1sT87b@q+9@6-+g3l)0GEN(q|6$Fq+I#u~ z#Q#VHUjp1V9$#Yq=(ukCAk`;2UP=k~9@X-deYSgu@Ti|JXFTdx?N$)~V_HtGw6~n` zX#c*-_~Q}&-Vc+UCp50?`6%O0YFx$tgB~INs9!B+{Atav{9(^WiGPj8m7V7@9`)x> z7=K3dA0h4Pw35d4PLXkaA@F>!M)RL5{BIK;Td(nb1@HS9;Ttrr{NxV8Eq;5>UeS^e$(7lg3XGJb?wO&2OJ${A10p>OXW1@kjl0 z4dYQiJm4AP58gXbDtd2bJnDzJ&k}#|J__Ymvl(yD_30^czGXb>S6ypJPSk&HVEjuh zN3B0!WPFRpcMn9kG`p@9!i2qy7-$UB&n-xU&D18;C#Z=Pxk+z2;YT+kYeR zzo~KMpO-uE_ZfdH!e3HLa-#Srj7P`URnJpA$&JL5tQSbm4_dw&r&lumPmQa%(f&o^ z|4HMW#6B|!kG-$)4uZc0+%}K==)iY*$eYc@V=4j1V6Q&_~~sJ{%5?<&w+RL_S3kkPoKXMfAAg>6<4oiJa`X@ zs?TSP2k#*{LgW{|LvqGx`Kms5F&?~!JGfKM{kw!KV5{L4m{rr-uI&F zGoAT&kMLJBfABsT#s3iV?-AjDk@e~;?fU&~SU+=KDL2!1;7gtWyZ z0lC7zvM2)Mu9mn_p zjjMIhOvW$MxZ=MTxJrA*=N$*W3ApXNZmWZT_m7A_`g~t+#-sPM6$7``XA<*A_gr>eSVCW0Uc8xj#K2!bF8f*=TjAXeD;h!r*n z8$Xupij^f+@IB|g?|s*^-gV#Ab*rmq^2fIyq^DnX&$;KGd+xdCp8KPIp?n(e6uI)x zHF)D)BZt36aGyRuCivlfyAyd1w*0R%_^T4!(cWzE7bm#0&pQqN(gdHdd`|zR@_$8w zJ3ikt_{$UA`NRADO3R;<;5EzVC4xIz3z=WbaCWCiI6PCDh$=IcqTy?>;Zmhu ztX2x;jkz_&>Dl_8XnbaRcBWRU7o%D|79b|h^-or3rlWdctPJ{%7T!5mtj0~v4MZny z+*uDY_dK^yo{M>B7J0U-=d?|+{H{ZW zO0}90&*wL7cusk=KCm*{Iu_Nd#iBH*QmaSOAS1!ZXnkC~q3=kA`A~`FuVa zFXu;BMcP}2b8fH}OI@6Z%B5Oe2y?3wre1c@a3YOkd)lVa!6=b!0m)WHB1S&HX|%pN zQj^N%asy+9T4`LnqEy*2GA=UY#;2s~>(xT3UK<(Dj~3)V`Me6pqS1V*xJ$|lzirXz z$rDK!!{bW>YC zX1LlhO!Y>mT^@58bX>B!JuWt2ilsCttuo#y_8eBT&XP>op~+IQJkbQLtj_FmK#TUf zQAa1rA9k&5)>ZGTL(8bpZYr|f9M5DayXlIblP#VVSIf*(sTE?kH90drS970_)`#8n zI3hD}GRqpe#EZEJS0#%^i)HadIh|aGBALSm%f(u4MCRdw0rI)VEMA(PEsw}(*f^G> z+gUkXm>nsnV}W?~ZRVEVF<+ucmlO*KkPURu@Rypp)_Bmx`U zQK%PlYZ~r3a?ym2C7E$@{f*BWvr>wFD0WoQc(rJz8Z!=s*fp$Cuj3x~NTV0yj?2&~ z^cEVU$n3GMEP-(}RhlR!6ISOMla`ptFFZOre#iuGzW7LNVLmT@c3UJ~X{8LcwvPNM^wf}XBjz13ASvxbuwH!(7ri?*CFzeRqj61Hr! zQKEQ>K-rCv$+%ME(y?2|z^%+o6d82;-9cl(ErA=!Qf-qq@|#@)nxoFHJ7Du@Jk`bx zcI&L+@j|(*BVEGT<`Hcix0NA_MubU5a$MfoY)1>84Bf}w=U?84UpBqk5+Zgpm$V-N zjRD?mINHXh8w>T^%1UupB)u>*u1nIzT5I>Rip3>iRC9pQmCY@v+|4eSEOfV&O8Tcu z`o=Jfrx(&@2Uy+p3Yf^O&KD>7A&>Im#conl_#D&+v>X+zUpy| zq&;TaFpQ?zs!I_^Z1i~Y)~wh<=W0!v3`hhz8+!t``mGmsjBJbY>t~%!36EYxtu@B5a+5o zRJ@GxSxHw&>?9c=6|3_Qsuu%E>}Wn2P1};e-R!EnG17%Rbwg*`v%au3(1MpaA{jZI zv^iLt}xik zcH=D*$rCdV5HdSb>C|8b6N8cUT1x_4=gbcO_*lDKI z_IEadhN2P41p3BNJnv+#9TNSiuMppl&_XtsWP@h5To~_e_ew2P*2xPyNiC&G{bo10 zFN8_7QP26kY43%SrO5&sYB=34SD0$FO^#JMxi~fxO%=+XregGA2`nEW03%Otq~Rp(#+TqNS(%&C&?j znO3r#jUqHz5L;cmrPXe}>Af;!&fchL#O|i0y(v$_Z0||_Mtg4bIGNA8YtIg_8V{PVx&G_ zttY$WFpX|gNulY!>EiVG^sG(wqzbPp7b`pJQ(9IFU}Ur@DCb#(%+GLed}ek}e#^Kp zjBB3VBLyqFrnhMLJW<{FKzB=|5R&)TiVOKr}N~k7g#L z`0UH%bX`iE8CN-6Hm9=6wSoTlyp%ZvC5N~4=vTQ`E)CS?wL#Nyaero|^#suIIZLEx zdE{8%_|zGZ9R6kGqi71iS83OQW6dv_$Edu>LJsFvh( z>U@7}+`(J)wuizG59o%EC^fIPDhi$`)Vo|kG*qoTMAdPStZ77Vje)@WT$0%e|r&5qOzy`=H=oQ5pKUBWsZ z)1Jse{QlOiHewS^c;l7W5Vwt3U*xG+T#eDOneTL#o)*AhS|?bd2v zXCNHLOP9~qTBf4&`CQJN2#@V1bAU_!Ocf&Q?(w{+)cA?;QFweV)2sQ8@MvXC6G2ZJ z+%z6!*K9)^S39@cl@c3X!FU-H5+nwc45i#^i5#LGdZtT8QgP>8p*%8O&gaM6py;A* zRjIDoWu!|>;&UY8j6$7Cvs3DZfoXVS{^&_pwHSZA%E*pm2TYVUZuKBOxp@Nz34-=X zEEf^!Tpo7*D;XPISKZ*ija!JGhjf`m8eCE;=)%Sp$oN5=rLU{euBN7U)2d88cE`+0 zW@aLLzT|j@wie5+Ho?3`4|2E2taN4YHV&~FH`{z%p{w~Tannr#86oY>p3NtmFsg@4 z)*ZJoZ!#y%fnRQ5yj+w^D)CX&1!ZisKx%GxC~?VcM6@ohFgbD`Hh@jM&{)bXy|5ae zG=yEeQOB)!`KqR4FJ0S_NEkERu+`W|e6oMgT%9p4e*@vhOwd$($XtMOp+mRsF>anL zE;JhH+P}xWoN#HIk9l6K>DJ84tm2%5UDo7(bm18^YNc65xRL(M%G zc9Q{YC&hy$*Lnvd*IzB}kV}e1xhofs6JrUvRlKdCC#VMX25M%k-n!(pgQdd-s*CS? zRJk=O+v?V~=yiw;uh2~=wKs{_eYitTDJQf9)fvyQ*Q#?4q{T7zzGcoYNmU$I-Bgs1 zJEeDbonrsmJAP2>qTA~977wmgAK>cB{5R`Ba42dr#y< zOWj{BbFJ?Eg*ayex`WW|#kZt^O{d}Qd?fd966rHOxAex$8sUn&7?&E=Sf1#zqPKT! zlwa$VYO2AEn!cqs5H|fugL2qJ>FV^z0*5A2I%_(AZq%G^f}B3+IBDESCb6EHK`*vFjbf@O4hwHA#VuAaUbxO|dYS9$g{rhz z<1b0Msk~P49SA%)HRHAxjgoj3)W^9~P3HP{NH5rRI#O`BX_`@_1C>b{pimhvmZP2K z(T)uES%o^OV5LNWx{INw_vV`3MqmScrBbTT?zh#YnxxQc@;FAL$Ef}0&wYAtxsj_& zL)_zQXSpnAf*qTm?5G}%Aludxw>mA~Dsy#MjtMjtfM)D3I)KslR&s;I%J_^r7RhGM z%*~p;0n-{cmB?;;qvDij>?%eS6(qLgt=?-3X|0Gc>xl&Op2u7*(Ep}tXm}>}PacCj zCa@~$LDjU_TrTN?5*Le!lGe!Qws+)J64~@zDN}(2aNUF)@u9$ElS4VVoliMBVdhoy z8c)}AiyVQI`yDzf56IyM-HVzPe(ut)DF4C-4o`MkWz zWd5;9<|iqzMov4)S*O&85@D>9t-=#*)+i2%GK6h+e?@kRGzZWWuOu_>szO~(mQ2Mi zCLY>uu6EH_GrB5vtUiKO6UBs=9!@D%<#>VY8j1Tdn~GzSCy+N_3ia_Ri%6H)zum6; zY1^c?<*llgo!vw##(=(bM9!rnqULF>WRWBp;24 zTqn!u%n!|*XTX#`W1z{Hmj{;Ok-Ax)xH3+vxUVV|b#)~Bhg-erBVO~yrnWxVh zVN9co?Av3FncNK&+1;1h3Uak79;)UXqC4SbT913r3oeJ_aJHELwv3SB@Q;su!W@L6LDnR#7Hb zHd>EIUq@Ef><<%zYg#3`C6S&7mbq%=WLYuk$z<^_;!Hx1DCF1A#tjyKk}J>bkkfbO zaIqOs-SAW8rFhxQjLw`*byz)jX^LFaB<^OoT9h!SIG;F`rV6D|@$ymzshRA1G)N6E z7rUkAsD?xt9=qY&(mp0V#Y)@cLBhNSp0*O7EtD2-3&sqa-q2f&IV9(~c%0UZ@74zD ziq*N8+@Kzdo0K!2iAmbzfM_!H8BHwpk+rhLjK5j0t>sqQ7b0zrV9eGOIt0h()iQin z+0}3BoGS1BOvnzFW(>0C{e~4~_z-mtxgqCb-6NS2ROE&xN_q&1!Wx_@0c()WYp*I^5mQOEnys z?`WbX_crC7)UwnXA32t{X-o1rt@$Gst18bHNT8*r)s!(Akc_gKL1I+5&{I%+_+g+> z)6_tyGm|J}TNL}ON-_H=@>sj$!;RC()^m79uN?5~V)SaBUd}l-o^zGn8`pOgyJ>0L zJ#oD$X>LnSB=cFQD$U?G`~2wE!q`l;p4mW(w)A|vo z&SoNG(nv(f0$jR{!&hGl>cP@mR^2Ak3xV zwK$B3O{ewRi6}&^)ag&=-}DQ>sz|rFvzXw)2JdEz$T!Ki&NJpBg^Pkhtwv5?@F_{R zV`)x(yFY?Qb&6?{QVJE$Wr>ozYlC`ze?)eVf)kngrO`NdCf)^)7@eS=Pkz3 zxZxby#-`r$$91h;E{8RcJaJ*Y|CWebJL|jHI@Ci2Jbu6gkv?0LfOGLre#&}IuH4O- zgtP2rnDdO%Q&|yica1QIjOJYuTRN=gH3(0ApuV{x3GlqzOv8Ey!MxDB=&J|PJL#(j z;e9L*NS&hJv`{EV=0=qgL$U6XOJIcK)J;rU<{A8atT{ zj_FKytgA(C4(ec zp#|Iekl1=*VnQc(@f&hS-ncPbRO-odwa)arJ&2b?Lp?u;*YFcPXRWvA_0Mggp|M42L$QI~W;>v+jCiAS&#E%Q6kj8m`?q!G#94 zh#xy8S&J-U|3<$G$&5sa0PLhalKGx&YpAQQ5^KQk3ElM#uz2gz1chB*CYLZpZCYv= zvM*V?_aM589`t~&$Q67}Q9_P>^T3jQ60pnGxMQs*a!JmiG>*xn58mlfQvU(I22In^ z8dKg}ab0}6*W4aAIbZF-E^@ZHmAa-+9w2XV_!4KC4_*G+T%8`zn9WkqkFE5}TvSsA!?HNqX^8LYLM@)#3l*g+;Or>2_}0xH?(m zC9V#PB*)gSU9vz=sKkdh9Yb%aT?KD>v>kOVMBh%3W>4Mw)BIu*r$lm)LLZ)#FY_zO zIoXkuWrI}C%?#>RcV7RU(V-&SnCxrwrM-m@c*OqI&KscSk2udcermb7M@16>uw%QHjj$@4;FN?DGt7U9)1r)a> z-d#?Ts3!Z+tl5EF{FSmbhlo(2^mGH^SwF><$$l`Saq*T)+X_x-m&D=eY=Lr-hhbE^w6Yk7w96@906?FDRuiu z%~oCR%&KLsYFM>8@x8opzDi~}Sq!=$cHwk#yTTaJVjpqS)tXs~$MIn3@)rwGBTnP+nQqx=>ZZeUWMZo}vEZM2 z+OqS{B90$tk+y7FPq!JVWXEZhypuX1U)voY0cn{SkY*MI+WjZ@xX_61U5#xqn@aJ} zhd9>UZRt{oTu!AZ%ofJwX~{T~AwD3~k`ghDn-8a# zz;V=MbBw#J#c$-=IJ+xur$l4E!AS@sUj<)O?_^Hr$k|+df>-`3m&W8x z9=XLQS2_gKw`wP1LkQhHNj4VJzOS2ku)UYGIa3|mU1rAzYr6`wl6kZVC-Z01cjl<$ zNMCi4duIA|-?Fl=%RehKb+e|I%W5**>T_~CM6`KEQKw10r=iFH&0&w0%Q3q9KkPm& z)M^ra>4g-%HzQ%by)~m>;jXvawhB6WlG_Xn+qqSPwhcAgTHKmQDX#aO)WIHyyP}lt z#oh}e7UQ-PT8*an)j9J@c2&drP3C7l2j}@Zz}7}|8eyzdS7~EBd$Q0x{#lg~S{u;=ya8LDz|a&K2FrX_(xb!OIl-(kC*TZsmG-e`?{rki%9yEpY@uXZT}#Y$XX z@9oCjxnnR~E2hT6qS$sTmOFEhJw&?_%dr*jwdlm1`mv5SWi@E%?0ZaCC0mZp<4Fw? z;;&rIUB!ytzmnXq?k{R)!rsuGsc3%7U03M&sA%M@-G+@Q(YIr^;6|1lIPz{}d3UeO z@dUSn+KWz;5g8xBh$oxotrinbxY`!j){8_FVB2ue+6)afi(tP`WzG#!)9sW07blzhR6NyW(aliu;S+i|iKu1PHI`fO>mZ)?;uLs=8B zT+7esig?u(8&elUM!rCxtB z^O^Z!-HoZ}RXMTxMMrS+c_*w!PTUY}`Ia+1p0>!1pBA3Ul{dRH)Kb8l>o7`fTJ~z5 zYVnPij8u9vJylCr5q1;TUdYKX+imi77*UIl3r!W{+LSuh=44to3TdD4)N_VrK5CP} z>ol*@L0-;1R@@ZXHg=B&{JTfe?CvgzOvtxlRcGvZd0`TmEQ?RXCz@gAtb?|igDpa= zc~Z%`b<=lCmn%MA_DVBy#qv>0&TZ@H@zLlh-Q|kqeg`$@&p8J6j5m!bOVxS3x99Fn z$8m4ZXD|5%KFJNmmStxDcIlxdSpAqSDLulGtOgpvZ0b@$&)ePPU-W#fSCx94aan2y-*b`emvl+I;@m+G)ar5~iLdQNZ*}0K<1h7<%9g$xq=|0! z>-n%WEyU zNW3lDESpBL=l3QD7hL>IPrIWw9m&e7WlSVTb7gmY)Lg{K)#@EAxy))&?$?OqlAT!7 zcndC0HR)S_TS?cSLwz@$X%Pxi;njn>Ik4caAFxxZGCfg&8P3*MM!bt8@ z$uk~>S}~)kNjnqbUad_V8%`R2C+v;2n@!0jiYl_NtHntrq)JUK3)PTJn0f$baoJFngg4f$S_~I-kbgqe=hlDIcg?>M{T{I z6R$Vl=Ira0B~W`ZoIAIx4lO$2-1}|Q0X+|;LHQ=xwR4s`liXFxdH32yq3PB9g423F zzuKlFbYEL99_hK~_@Ni!*TZ^p{S!rZmt2OP)FNjH?eWpj2Z^V!ad8m(iJ5lX8Zow_1m%1^Ke2IR?Pu27uBgGxpZJh zv7lVMl37n9YYUiPd; zeaZ879Wm}~nIL1Vb)glSSg-@tq(OQpn_d0(kfVI7jyyQhy0~oX2f|k^jYW&b?DKZP z(&I{+OmU0Ee=a@?oI3~ZDXSIr@{$8a22L^|`sIfDLQK~}N;KI%;5TPLHRhC5Lnq0f z-is(J+XY0-&JiWo!TjEKp9q_zlDfY+VV>u5iJ#s#VnL&j&})I`;PSFy!R}wiY}b3y zJ1`dHuzFwrf~rd$vAicKCP|6yD_7$L=pJZJWv~=4C!@_u!L|QtJwtdx6@Uzf5YQf`2JzB7JWZu1KQLDl4rS*nH zx>)5%r8(KTi6j0QIe*^yLbcNcoy3k?ZQ#G;c9M!H*CY{T@OmJ*t=m~1ptGfl4c>hV zmO+ggi(~SgImNPmA%MJK8UMIlgYM|Nl1+4O!`4W!sgs#=FNh} zLNrdQWfye1*;jLr?vSU#-L|Qm-up^f6m^pE>3ziu#x8l+jqS!-@8!x?h?7S=O-BBx z_tJC_VK)4)Iw!aAyaz2oOg8E`$wnnd5$-|4-9tOI$^C1;s`fH+Tl>Q5GzDglM09^4 zKRHj3J;J-$Q?#$hCU3pB&Mf^pvvkGUod1N)^q#kylJ-UVC7#tA&Fj5oE$H>F2>VhC zGARe-8#K|n5A+o0WA{PDjkIm@4G-Sgu&d#f=i+uKTBsZ32+Arwg3?&?!js@|soY1E zuUzeJ#5bi-c-*vglPWwpZBEor7k0}FW@i@d1vxpXtS_0#_wbGt4;l`^cjF1)!?tRy1N7E7&E|?wL zoAPv$FWH;&G{Sn9M-=P02L;Y1`;tWUB3o!Ln`NY`5>TMTDDd_sP;}eSGysyhQJfYC$iV({B{TbH@6W!uw2&=65Uhg&6Lw zGkar5y?cF)z8frOO(ti=K6PaDa^u3zOdSRAoo$6QY`K?mHjK2FTz%Hpd;ZO4)l>cp z+KaxZmdoK`_`zLMh4}56ZO^q25Dm*ocl$LLk$jtZwK`Y96GWa*ZD%A5+Pz@Z@>!aA z(0xyYTs^MJMIE)s`0=CEC(Z=4MJq+ddTF{C)1XZwG41NfLa97gEh;xNWJ0$I?ZfJ` z!b848yjq_t=o4SkVlf$ca(#DUtTdmK=RGA;5sjDS(eEf3rKZl&ed5McM5(!#Cgv2l z=;tP!Y&~J5UT~?eu9%j06FVzmv!Q5y%4;RvvbSbFbf)=!d!yRe@PVj~yjO%$-{2w- z&APq`DQ*X8PQJ%thaHE>Xd9T3hjL~nBl8)g%XyqhT)E}e;w>61<;ybU{o8oJlV!?F zG_hMfR-HMcs9(uhsT9ZSC3!0sq)kpjhfTPXh@FdEG@GjzcXx6tTdI$n+W3yP;fdn3 z=up3~K_~i3VY+zSkhqwfz8j!lps{UaEFsIaXsEG0ksF|n93J~pkK&sPq}1p>6s>Uf zXu$g*I@+g|$9aBz>eF02OWrK#VY0t*G+V-Ey-#YA`NjaG8%&5cT{y#iop5BoLd<>C zo6F4&9rtn)iIt~Y2NKvOs_S9U>Fb?sBk5x{qDr-A9*asB$(wwcJKgKaBQJ8VR9uYt zUMc+=5FOM=m88(~JYTJgy|uIOR^vCp&R&TFj0}{7~Ru z0R9-@Uj+UH;9mlM0`M0De?IW90N)Lq<i_{~GWMfzy7j1bzd`{}4FK{|PwDKkq)KT2t@az~@E4zYTm3 zaF#zG_;*nLbHLf&{|B7y{W0)i@cB7#+Vdf*F!|A6l;>%{Zv>y?fPWYGcHnOX{&L`K z*BgOT&zA#dy`KlpdcOgjh1^6+*R|8*Z zah>0O4E&iE7pU(iz)u37b-+&rPW{w?)81YUocehi@SlSJZ-7(&zW_fT2&ni@;w6{QbcH3;1V&Q$N22&Ux^EEiNqjG$e8U|F02da10NI%oNn)h7_#c4(3HaZ@hvVWw4{qp_v~yZv+1+%KscV^>)NV8uD}g8URi{CjtK`_&*Og<=F|G{9g{7{Qns^<-8O)`}ac@ z7g3Deo@4FyQz-v4$a#&$)gLmx`a1Y<-v2K6u-|V3PWkTuei!P!&p{16p8))!7I*Sr zW95Gg%5OyZmB8-=egbgH^L*gDQN9fP`@mlUd=~h-fYZ)D1Dxai2H?8Zc7FJ0z{&r1 z;2bZ%2Tnimw1Z=P3Txx%%kiIm&&t40w7B}czeAoErpljg`Ah)UDe)HDFEiky6}xuL zqx`*qpAB5+Bgg-Bz+VG-E(HI3gU?%0UirB8z8mH5gYusQ{xa~t9{9U}{{T4s%zYmk zD@651yM2Vkg@qY+cUt`%f%3H5Vc@je)4_-OnLv5^nR9@D1oB@1KH6U^R51Cu809&C zT?zb3@cAC_KLfuVIQ8&1i)(dS@1U*sfQM=Aaa=(?JPtVZ@J!(Qp&wrW{Jy|<0>2;d zvn;M+s6Lme5c2aHl)pd9zZp2k?`6QN(8DKzp9%cyz^R{`Ew1vYekSxE^79`kPyPHE zIQ8>{Lt;9$L;AO4fz!Wj08all1^n%h|3cu5Ki_F_C;wZl{O?D3+SNCKGj9AP@cp6x zqYrJg>#LCG`M}xUBJcyiXBY4X0Dm2D^7$}u#>3YFKMV5w82Dd+-wvGq{D6ly+Qo5t zsKr%{9H);#dFpcrILGNpz}dgsfYY9L0%yO!9ysOyyv0>cQD@?Bzl!n?gr2_xob%Vu zfK#471Lyp>-y<4&BcI0tXMX<4z`ulkISx4MJq z`TqmXb{%q9Ll3mu9B}q~893K*=K;R~`ndu)`F|NWhp`h zDd+XzuYTY*E9du6{y`XDKeD*W`C#C;fzLyL{|do)4UP{&xXq-s4lizXLvB2F`lF3!L)bmVw{*(MAnM4;){I0jK;= z0Z#eX0RJ}R%mb%9JAl(pc3ND`gLZNj%F|9>Y4Nn3ydHdLCl`Yc?c@`{sn2f$XTSUg zIQ!*~z}emdY+$DLR)KyF1K9+pC<#S z-!1`v8Th{#_`86=7WfB%zYRF;|9!w8ihjSs;=-cu$>8&8;15IjFM|*5{M*1k2tL06 z&Up9%k8S9a`acvn^>#FH>TMi2^)?5bdV4u=>g__{)Z06NQ*W19Jgv8n0;k?S3qI7_ z*ML)RzXJX@=<^T2=}+$SxQ0FtMt>awoO*s7aO!y_aO(L?;FRY);OyTI0H>e-9PmRR z=P!V>{9V9*1U>A(+~3~E0H^#f1J3y8Lf|XG|0>|$2mWo~ZTj_n9B{8xv^n zk-(X^*#ew==7AT%=heW;=R)9=|8n4rPre46>&+hke;V}gTj12&-+*fl!{xOea7057 z%OL+VfU~`2;FBnSHgLB0eBf;Fdx2B_F9Kh6?}nT=1E)L(9NCbc@;nAOcig{tu(P)_aMS|I;W>`M-ejl>ZyR$>+NkPs{&9@TdI00M0zyAHZMZ)_wnXq6X$P4e;o{*>-WPfuKmt-9RZyDkFj{VU4!7ycC7`@c5MQGZP(Sd zU8e$9$cBG?+rfwJDg$S`YT(0my#zS>s^1ln^wcfj}{2xMj%Kvec zr~ID>PCj3=cv}8%gFof}IdG2O{{qhWtM7@iz-m`4|3Kg@|5)H07e@nU`DX&>{P=vU zC$0DX@T;%Nz`p?e0F*x(_yd8j27Vy$e*peq;DZ(y$mCC)e^`g|4@LP^zz+ew6*$|w z8Ter+Z;#vbX}ymIZnt*~{#e27F_k{sjb=W29Ln2tslj=!jQTkO<;nl34E~QtdGdb( z@J{$2ox%S|@F9P$)3f*=0DT^l!KWYiGfb=Bd4Vl2kQoe;PRD z|4Ih_O^a*2&jO$C0bdLJC*Z^U!(V_Ohw@LpSNwtcAIkHr415c4<{4f9ociAmoPNNj zIn6j_zc{_BJdEo`A^(YxKLSp_{mKmd4Ztbqn}Ac!X97PN^_~QL1Muepr(G3+vt4zI z3kzdc?wrQUP<|u$Q-0dj+fbhU_j}h zXZihMC&X6+XS+56XS=omr+r4i+3yp;+3)njn;<`N%1L|Jg7Wk;T%X2W5z6b|`lI7?JMc9Ijqx$yM*=SZe-iK=z!|qp z0pE!7j5nr$Q~plmDSp8$#eik_8tOKV!HQ=3;pGSG}nFG#t z?E+3aq?|53)P8>n%D)i$e<|>tz&q&|>WAZk@}CXVNFdF?L={Wa6|ZNgevb`RHJjuf`vn z`SFp!xvoDHa$bt^4?_8?fzwVHmp&GJXtyj+J713ST#p|Poc`ws;AdsXb0qL1QJ(X~ zV&g2Rv)O*o1b`-ZlfLy%FC6{##JK44m?Fo+TfSJK~3f&$Gdw_O=yx z9_2@Ylg~EbZ0~b`b3E!B6mGs|p668HN21>6XW*v+C;t}!=lsHa<_7RT9pxFnF>hHy zdBy`T2hR2Wdx5_Y{67c$AAxgRu>5aPp7QkFEB+vD{|^LC`+pp8+7I;~K_2RJJ8;H7 z)aS{Nvw-rPuPHy*+-+|MgJOFy5J|7D_OP}MA z=PBU7132T`Dd1f9kw4>Y-pimrp&z3^VY^-cdDyPy!1YZSH%=+%8NfLYmVnb=G0*v8 z%U?nP6DR8&tUs@ef0=mrVTcnx2s{V;YT&;FejRYO_gfa%dY7a8_ksTk_^lS#@x^>5 z^N{5KNZ14Oibnybo{t93{^htUL!b1k)4hnn8Rg_;2ybhf5(9VxX`KLl2#$B{?H(zLbA0YqNxmI^ zxZt?v{t?@|3H;gK(}1(R1=P#-o&lWgod+Mb_npAW|6{;8u0IEy%4)$>%?T zlh1zxr#-uTyZWU$^vmJsudMadd`9_Qz&nWpccVPx=NAJHjh`9Ez9fUsOMz3)mjQo{ z)q}G`J!`8!jO)%u`PukmGakvMFM-c0;IzYM0H+;3!OE$6el7TOe~>us2B-;CW z;Pk_90M7a4eBjJ?T>yLw_`eZ2t1{Ck13e`ybt=Q5OMy_;%n|0DnF3j{v8i{3!6Rp*-#F7T_O4`9Arv=m;@<~;3d-LId^_+fp|{<@DJSjW z<0#K{#3z7n1D{Umc=U`g3Od%fwx0LY~(G|03`=17}=K z`yuZ9kJkGo@Nw%V#jgea1@Py(;G4ji?{awqwZkui&#zFP`6c=>=DY55ub4pjFyF=e z(j@q=MS1dn4shz>MH%>ufpb0bYT)#HZv{^NmjP$_tAS^Y(*w}1<E?GAm#RMLKRMsM9pzas^D5;3Rmj75AP+vw1F*eZuW{dm$G%WngI9QgkTILkARIu_+`MEQRNPCd*5XI#PkO|FC9gz^`I z|0jX7Ul_-7e!m6fZ-71j3HZN*|AXKsZvoEt^BFGB2>wstF_h|o=ljBPlc`iQZ{x$7{@-t32 z9&%EjTY^H9?mcO0e>{g-xoOf zusrofKgNFFAAGihKl`2b_CS08amW81Qu{|0v+}&yNPa9p#q+-v#_Jz+VHLk4gXUsE0^a~W_k{kXzwM-dPl5bP-M`DBw@s)wv>%xtV?Q#^&+;eqZ}h99kcVYd`$(IACJhT(a^N--q@)7XR z{>mD6&hH89KK2*&c`WLsoYZF?`Z)n{8uu?ae$PPp6H$H_aNgHo+`>5ULmA~i1)P5G zbHM5M*e>?VV%oLw9?-7+ZF@DGEodj(pM&gg#m9g<`&WD%_;Qq=0Pe=GmM;Q#epvBI z;FMr#xlglt<5Vx*y7;=Re&KwPtF)|SL9#G;IH2e?f8(t&KC~vgnu=I|C=-T zt3MCn&-LtOUSpJ#dla-en2A}OH zPx;HhnTOmB{0Q(l4>;peuE*J4=CPNdznq@cZr=+2>%jjJC{H^)RLcA8JgdJnPFtwI zDF540p8CH8IQ9Q~j3eg5ng8F8c2OScpZk5(Klk;r^zZgfRG;sFob&_KC->#q-s2$W zJHdzc|1RK1qWq=6S^nJ__GU z8QGuZ_P0VTz83g>?Z5TccKdHFe?R+g{dKnex8nD=|JGlZ+J7tV+NjXA`XBjG`~dT> z_&>MWe=Gh#`)~708!A7FJ71!IF9-f01?~0)MOm z_UBsQ?#!otbSv=XwygOjK2v}6 z6n`r4wZL5tQ$OAg{AnnEHt>GnmjcfLzZSSV{%hcFPS=n3x6Vl0<<2H4 z{v_Zor>gi#z}G5Zf2M%1bD;b_7x;0&F9&`+@auuE2mWi|dEon7r>XLv0Q^b7PXvAv zaF-L-kITR}p!|8jHv+!`xH}uEAKw7n?YSs^JMhg4*q;Nfb65GdI8c5c1N_;*Hv)HO zWAx)P@KKaM54elj^y4dlKL_P+0RCLyw*!A3@B{56r1GB%{21VF&rUzy2;AkO6)yvS zfdcmDJm9B0P<~$l{Dr`80Pglg^yAxsM<{>b1L8ka{_VgI1zrF?2z(6qHsH$3{nS(V zb@qdo0H1V)<@d$FmCp)0FJ7I(w_E&X;5)$QF5pwZ53|96^49-fVEG&lT;(~$(yRrp z<@HRY{!FCsUs}I;ZVLZ5>vt|s;V-r0`QyN~UN;Ba2wdwu%-Y`%fou5_<^TF~7jP|q zhb@0E8}ulq<=q%q4qQKTcCa>upJVkn0$lkxolXH)KC7%8=ce#ki@y=L@|lzW>(79N&d^(2Af0x;Mlt%^lvB34SdmkKs zmudy^!z_t8-HdxyUT+0tyd%FO*mOs`8UvCAj<=wretAT6zRW>O5GH@-w+w#8^ zxRzh*f;For#b)IH?q@mhSqIARwZL}*-wwPA{A}Pg;Fkig1HTryvjzS5R^am}zn=}h zRsLPTj{?3M_)~$ae%!sUjllPyd>Qzez|RBzV&GQ*KMVK`z+VFVcHl1sexO}EXuDnp z{21V81K$Yz<-p6pUjcj$xa#3zXNSOFiSkzhKL_}Yz+VOY4&bi_{%7D??69{8Zr12k6JUfxiyrF9!Zkz^?{=9`G*%S2;iE#u4z>qkNxT)T#V$0KOdf z`M}o$zX13I@HYZK7x;z1F9-f6;MW7c2>7poJ71_D@Bgs4kjnqh@juOfp9K6Zz)u2x zG4LtiZv}oX@V5cK9QfOTe;l~#|I1eYHv+!|u6%xK`J4^>(zvMk@1?-s4g7<^m5;uet3THRe@_gV|Na{Idx8HR zxbks(zy}=~7gDyDp?p8^_W@r6T=}fB@|+6%{V2a1_~pPa2L3_dR|EeL@Gk?`di9R3 z{@e=u!!Z>9_u=s`Ep`R)<-k7zd_C}w0-pf>G2rI_zY_Rmz&{TBI^drGejD&l0{<`I z+TOBl?}3kq3+bO%q5LtxKLvav@J|CT1OE*0^MGFs{0iWo1%3nY&jG(3_~(HibXfd{ z%I{(#Mf!n%AueM6y9M|cfzJZ}67UOvUkm(7;9mxQBk->PzXSMJfgfb!HI?73QS{?} z;9o=eEx^AHd=~gOfL{Rodf-ws(d zt8Dqxf&UxIyYEBSVm|<9|7NQS^S6c|99X=0lx+Kdf-0>J^}nE zz|RH#Q{a~azZLlPz<&n(yTDa%S6jW^0sKEu{-DRie`vAWfcFFc1@JAve+hgR_^*Ip z0Q}d$uLS;|z;6Wp8{l^U|1I!?9vlCm^4|`85cq!q-v<1@f!Bfm4){gD?*M)k@ZST! z3Hbj2zZ3W$fV=OxR{8G)KKQu!55@l%_%`5w1YQUJC*T(WzYF+P!2b;VCgA@E{7&G1 z0e;Bx_z#uyZs3E!{|bB?@V^1C1OGeli-7mp7)?LE3i!Q%-vr#f{ix;d1n%wxDSpV| z`rkN*h=B?%vYW^0xqgD9Yar{9(YC9jR2Y z{D%NP7WkpSw*!AT@UwwG0{ErC4+DNJaQEh?%5f`j_g10eeMg!9nq1?f!Dl(}Wx&@0 zcW)yohwZ@Kn>mV~4cxtjsQ9J8mxKScz}+2TEq^QUBT&BY@%m}3XZNeqc zjPeIPK|hV#>)u$?zaI%)<>|YR{zu{v;O@I-6zBKYx;xj3??!o-+gAKy;7@}*R|9u% zyJ`8Gf#*>EF5vDB4K07z6ZOAwyH=w7FmRWf)N-c+A42)vz}=lkEq@7c_g!_0Ujy9T zF<1N+;A_DDZs1P`e%~i4RV@Fc{MNUn^k+G6_lBq9Yk|AB?-bt-+}&+g{2bu_fO;Cb^T00vegg0- zfu9KcM&Ks_{~>UdbI{6pH}DaZU-o2eUEJQ2fgcNe1Mt&a*O4BHt^-Zw*p@ad=&V0;O@H@mG9ZWpM&z30)H;>Yk|8v!pi5H zz*YYzS^eJz{8aGS?--?u+x2|lM*%+#_^{3hV; z?zYNvC-5nhKV*e|8uwQT_#kk%7o_F30Y3xf>%hyvF9JRd{3_rT;5PxE0e&a&S>T5} zO{I$E-wAvWcoq0I;5Fd8f!Bdw415mw)xhV0-wb>g@VkKT27Xw7L;gL$hk>67d>wGL zs~1_jngH(J9#qcf06z5AN`yp^G|7u(QF5s^K|HE=p zNPd*ZD}fIKKL_}!z+VM?H}F>jzZm#yfL{&#T;MkYe=YF4fWHp-VFN~dBmX}E9|nFN z@Kb@m9{6tHZvcKV@biJc8@THE!&cAN0KWj`Zvp;B;CBPR5csl{jdr~W__4q*0)9I1 zHv>Nl_&)=`1o&HkUjzJN;I{yOEAYF4zYX}Z!G`>5Tgkc86}3In^}<-+idwxI|DJOH zsus(I74_oodf$qPLcP$pVysr{Gr)@Iv`wS+TyA`-P>t%-nu4#zzOD zz7+|rzv$}mnd#X=wV2;x%1db` z{+cLnnIBa#XX2JoTxnQ;6xHUV@u}kY8Pn6gDu>IZda+t4*9Q7UTcyg5Xuee36*;tA z8mP^ytd06NZ5XYusqdLBMy1N+%wVN3UCfI-thl*Iai=I#WwZ?#t*@LeRYs---4=KU0zk|8_*F(u1=*ckj;Ss)fpqVpObFXR7N5S{myq)bB5}da_U| z&sB?AOp?zt=yR*bsxxO4E7AB&rBWQPmu4zitb9ccS15Y0GB;hUmd2&Gr`7OFdF_}M z(M4sgC0CVab`@);OWJTO3&+ClG{@2UV6Aj!aYPue9xK#D0GQs$xWK9Ln9r}@HeQ~n zPtHb$GH*;LF(@^+PC3Q&X?rzYI9#g8P^c8jgX4wzz;Q$4+V%O)S&t5ijqeyAkBYm; zi?ekxzOiyqy+-f2Hx07b?p9jeS?47~HLnesiN@w8#dU~KGWgVyWlEOom_=vR=W^P+ zTK{CRszblUjd~@Qp}#tcjM8%hGz*_aj26UA%TF#hS)G}-_LJFHgHb-9{Yx##!dmP~ zf~H;{)?Qx~((65}lMQrZy({+qQBU^q*h*V)SCzGxt*X!Ywlz_-qcRs;XDU`O)7$vy zN-5nWSvE=A5MV%N?07Dltyf1jteM@RliysqzHt*c4n!Mg#?OdmXUe7VJ^2A~kgfBQ zc&>gwtBlgAs=LwRqJ`|HQeSh7i&+(G?)X;S@Z;QS6G3SFBnmZ?fJ8hE#kX-Cwt|H@ zG+Bmp%#y2G+AJPmP1-2aHqn*3W8SMVJUX8wkI&g?vPmNwwwewZnk*H|6N4Ioreg*X zG_ABo54E?tSX`Z)o9axfqQNd7Q~0N?hE0in`_oKmSDqn>R(d||zKMlV?d^~z#uP10 zY!#s!3u)gUan(y>nlW!R&8EI)x5P#KJ-4ztvn%cx=lC}m(%fnZuPU{I3Av-mnen+= zuD@E`QL0JASe$4v)|hA&i6o*a4i!!7K%qN8;Q=HdnMNLj+E*+NO;g0fvz%$8=0 zNKq@*0wznw^VNMlSoOYjN9m3+rZesU}O<+MbRYG!!>J z8m|@$nw2r$Q98*PcnAHHX0giflDuLgE|Dp|2i|CtjHKLPu`)iR<{Is&&dklWTOK#k zB1Y-^TFxdz_x5I5!rXw#e@c>|P@k)X`-gPm#M_x}bjE&oVb_;<59hdBNs^_r8A8sK zGE!kpY9WDyJF)L{PAMc=rfZ^>0T7<2k;r{rxjZu-O_d~{>uae@LY}-|oaM=$&bLL| z`lD?*nQXRfkcn;cXgVGd6>1YkvRP!-Dw9%@b2MtmZ{3y-4nkCEQ~A?Kq<213i9c!Y z5H))*6NXK?MKkk~te&fkl&ACgZrW}Xo3iupZa;n?GsP?6{pscI%%FWa;wLu zXT?v6Yb{oz;?B83d1Shr&yV#^%9X~1#xrHn$)GYt;0rowkbH>&`nos;G4Fsp71q}r)4FUX5EdHc5CrOpdlw2Iy7Uc(Zb4{Ff z+L>+A@V$=My)rYQnmKOTb4_s|^ZP1%X(}p)%A1Y4I*7u0M zx>?YugTRas^K#ozoO`8%a@dgU%3++mRk(Q9Fh&gdkV+DZSwFj3CPElyrD$Ts)s1DI zZt~V=svVe%u{#$mG<)LV@j|(*QJ^%dc>!XU&!#^eWhyjlLpnG$6K^3q(yU6w9FmAS zu25$VN0nJ&6IoJObEowr{t%s~$Lwf*v7FTpcp0yh^=5CZSviR7{{<~NpX5)NvS zU0Ks=NkHTx9R~xlA+MX2vki9_?Wz`LXNy(+cxa+HUf9!cfcaIjf3Kc!lW0H+tcga% z$gOuwJ`^vqP6EFZTBq08EoR6aWoJcCa=;aug+@nurzsn zYm>Y2Y$jE+s#K{Jt0r9}IVJ;%^lOS0-NKGalOw0rs-nqN5(eq=x?Y`=OsIS`A|jqF z4k$k~UntKN^Ad!MNqQ|s>|iXP%x(F`z#Xj@clO9ziH$WfTSm~xoNnpN@x_6HUwX-! zwZv~-YkO$CTr5<5QCC+(Y*aDlFH72GQN3*3mYid0oJ)xcTnGIJ@&Qy05suLq)`OVuR&1!h^6S8?=gScitvUvZb3mucj zZ7k`UebcbICbN^7mHm^fM&hUSAfz^-LzlZUYE46ik7!ABpVEksM^uLVyc}{Kj>Ind zt$vf3G(Mi})~}|qt1B~$NHn@Mr5*-aR%MtamodLNdQaEWEKOk5ksZ)pXAfxu^(cS%cnBQugWb z-tZy$4hDhGw|422j@P3t>XDj)%e~oV z%tB*4FFCx?sAkTQMKgNgNW7>-6)l_=k@hiZ=Z0sN8P^4%qPVUyVeR^8*xyGoe=RCe ztdp3`PpjesbSgkDgE@8At!jcCB1P&~t-g8D)_rnPi)~vOSk}ZO9l_(q%oLEX3Yq!jiL)1xdopRZ4OQ zZRBKG>qs_y&}{wbzcb8I#2hnQaOqLD1afAkj(e_=p-%F^trNM-A3Ybv<%e5LbTN}v z%KN0Fx|X=G+!7ah4{$aGk2dXV_EVvZ`0lcJ}8nKQ|riTY8+A}?knX}XS+2OJE zUAS7@Rot$*ay1U$c8Ek3>BT~Er`&1gaz7VEsU3J72C@Y&_e1rZgk-4VZTGR{I7GYs z0ZDL*G)-6Qb=yr>7xB3wWS6u1J?r45`tH4)*k2{{ncO_^OlIAt2u-G}DL>dS>2%7! zjcrTkdV_Db)<|D}kwrvVmR3nDZ5LW@Tw}E+U2cz}x~r-qnqwZ@f-xI+M2jagxv4uAOXd z-FG}z_@$C#-GpB4Q`{XS?L6nDmR>Hm=a3E|bR32nW|R3y>Ryr#dP>?Jl6KCbRoe}l zYp=tVIq63`;n@9IGXvJA#FTcG>Qj0=TlfETUyY_)sn@ETWSuN8_e4{LT2!n}*5mCZ z$v=sNDTAZ05>7o|F3M(GR4wh8s+-(%!d}MHgj|p))QU--Vkv6Zyji(8*`{)OhNX}| ztXh0wb!OJII6DFFEM_T|?7GyPPG{ejqOlqS=<(I`@^cC7%4H0ey8mSEi_R#@yI&eo zwKZQU;I8(Lmo*93d;)t3bkIogJL^GklG>h4EKWh!dDc!lzF7H6ur*c zayxt0X56ill{K73^X?FT%Di%`k`2G66n%c>YNqEa^@7|2ubM=?{KuWqovG*ow&k${ zF|0+WLQK}!vlEtBY|n1156T#iZ^Igo)|{Bl*k82E*pxDRF57_0rnjHt1JpKkEU|e_ z4jQ!NE0U|EJ>*E=#}W>;cWG!`$V zWQo?a8zZc{%NU8RtL%ySFqT+q6EoAfNybNox!vkQ8r_^e<8C_KdFG{<*L|DndZsVY zOs@ug*1WzHbr}oR_YAAim|Vo1h-co0mXkvZSu?U{s4s<_-T(yiuPz_UveuKsUDL&B zd4Eqbr14P7ysILKqf;XPhCt7|G-IP+!xFW?B=Lsz)^0`5m-b@Ho6oz=gf{7Mo*vSb z{NiU?S+o21OKhGJ$CXA-?ka-Gs-PFr>kfJR?##(sT{5<#KnQ*;wNUS-jSH-OZ649q zDdQ%-+A9i3% zQ(YjHu;ek2rlxe`D+w??vvW%rnHsv?*j9V5LDweT?A_=wTPq>{E*XBpanXykE(W6- zY_rc>3dMQfH|TvBnN!2j^_el8y^tg_2Z@sPx2d*yy(+I;v>tMhxZS^Cjl;K$wTCP) zb-lCI$Fbc7XAM_V3#8Nl?rxPdJ?%-ub<_e1l-m4~Kw37Q@S@#c*4`Zf#31(m5Q-vz5!WCXAKM{-=>oJvZ9zNO%~7d+ee{FrAD>;;F~ zWsu!G@XZ4==KB%cEujfH0xWNbwCp{}nKl!Vw4Wf=J(+i&q^zVk(=&9>t80yh&ERx* zCW_IHIl15_r($$PV!sJup_ax+BtzFx_rX$t4h|RT(<9 zx5&5zHLuKCO=%3xJ%6DG;`QjN-sjX~Da|fMmbi&P*wE;%%3S|M(TzA6 zX;PsaX7GFmPw)b)n~+xr(wZorec;ZVzQ}JCrDX2|$@aQNg1U9!rb1E8Qpe*f7vB1p zuho$#HNDo3xBiENw*HsU9)_EY!D9$Lv^{;BH+~664gO>aVI}viDr(ri+tN$2N{!QG zzLbsF7pWUceL*u4=~h`P7R+ZJ0|PGoCfvscuR zns8!S8c({$u39bv=yJyHI`py|bn5V3ArH;>#&(-_#2rc6S%@X?fXQX5bfA^0aDlxk zkF~cQVc{W5BVy61dA>DT>2ZBc*0V*zm6jPwmnE`Xmm?x>St82_eac)frge1)U8542 zl@?gNXeLwVE{TXUS8Dr0u2vh6AvWAtW;HM9dM}|wvI}S~d)?0x_3ND9O~@ke4asd-uVQxNH_X5&P@yED?m z1ucn#9?y%7;8MP$HoZyH`^8<~&1(p=hCKRyIIZ=>~{5qJU?`sonT1v%6b*ASO)3E(@et zB+k&6sqKM~QF(G+zg4MauQnsW)*DSGVNP0U&V1X3x4j=<*;7&XG11Aje3I+@#wIwN_e&em9Jk!ge2rM9@RY@Kv9^ytH6 z*DCV?JXso~Rzz+nLZBYGF3@{C%!_vCJxd~atpjQ1#hvr`0!~W7U~6iu(Rxr6OOcD`K^0zk0GzD$iAm zS*0|VrP@1qgxRm#eX~y>vdoyClP(**rx>-!((z%g&UUX-&0PACqVg~Ltan=KUNF?J z&P@%~uENtM*}9pygn?HUa|LSX%=uDrmyWrHb;iD@@rjRGwC+8#pL!)p9@uGO9Yp4< zH^VQcg_rlC7j&E>mRE-3Y+;#Eu8ovl2iwBeTdECLj~i~`=_%8Oqu*7xF!dM9=1Y&B zX2#Ea9J=%Njas^+S4mv37T*wT=^Rh$DyyWq8P>F-j7xe9DU++OY!=^Cr)Tm^muuy> zPv$3&y!%Fudx$>d?uJ|F0mVu3r@2 z^X!zYTFqOV`dVO0=|~8rvUXkdbmLH-?#jo9^5FYgTgE-ihM1`n^sQw5`Lrg@zG;I) z@`_`60hFd|S{!&j%m@vQ_29dr)Ag+d>t+&x~L)hu0m_R)^ryCXU4SDUHGgE{p*(R_d3it(B0>0+hc zw?f`sEv`6m({r9G-}pIxhW&d-Wp2f+ys0SPlI&zJPDPW|!gR53#g6LC+-zTOeqMY@ zU*EwVR%8TqfPR~Y{s95>+dcFT3ZO4r zdba-|0rYhb{XqfrXL;m5IDr0K5B{s{W4GeD+1_`^3?yd0Q!DU{rv&-!EQ)Bg1V z^b?-?^8xgA5B*30{W%`_PY$5Jz(c<|fL_O{{?Pun1khjRssDii^jCW5-zAuvx83io z`TH6V{iOl)*L&#S9YBARhyFbQ^tXEG-y1-GyQSy&dqIHy@AlNMed_e?erM@lVeKS2IL5B&!M=+}DaFAt#K=%N2$0R5>R z`VR%rPk88Sg1LTkzq9&p)0_fLz=-(=R;`Hu* zXX$^VhyHB=^ru>Sj^9fH=(l_7|8zk6%N~05Nv_@QcUJp%d+6UAK!1*h{(S-T7kKDD z5I}#4hyH^B^p|_+KNFz;t1La^w~q$Yf1RiPD+B0n^w3`&Apb2M`p*W?|Jpi2h@M8rRV&2LV*3B zzvUkK-v!Vgpk>;2&jLHhhB49o$Bv&4}D*N{8JwK`vuU~J@oev zpg-F~Ukji=&qKd|0R6=t`U3*!FZ0mf9ngPQdgwK$*lGV?W9jL?4hf*Y&O^T^fc^%L z{AUKx-|VUX$N>6VJ@uazK!3Z3{)qwfcX{MLI)J|K{;mG^DFO5cdg#9y5I-E|p+7I6 z{-Z2C?QcZ@{V|^UpB6wr?5RH&K)=>g|Gxz2Z=;7^bLyRr-%~yEzd3+@yQlsa2GEy1 z^kV_^yFK!MD?oo|d+J{kQ2%)z`r!cji#_r`BY^%=PyIIpwEqeZ{kH??ulCSCD?tA1 zJoMiQsQ*R}{l5m#-(u6|PyMF{&|l)A|HlCO%RTf_0R2@S zdfk)m)c;-Up)Ul`-{7Gi51_xFIx7A3%S-r~Wqt(BJ5xKR=D44}WwL;w8% z{omn{|4jk)-{qmdIDo$I0j=}TTLb9#xAg4)w*}B2;;H}b0rbl}^m?YMQ~N*4BmZRq z^!*yiJ{0rcxV^zR6u-{_(Lw*dRy=Ar*V0R8Efp7wKd0R5DQ{=EV1uY2f! z7*PM&9{LXj)PJ6b{)zzli#_xo4xqoxL;sNg`YS#3KMK&_HI|<7@4pAoU+1a+$^iLq z^wj@}0Q#Ff^dAqPzttoECj;nj_t0MzK!2Bq{<8t}`#rFA|KW21^apw9KOaE9%tQZ$ z0Qx6+=)W95Kj@+VN&x*@5B)6x_P^26bNqZQp#E(h`mYDjpKj@S|M$I^5B+!;WBo~Qm_2grZ1r~W?%)PJdm{?7sQ zmwV*@zX1BHJoJAFpug5b|DOT+yTQ}`zXsHQlc#=l-ktjITRrsm3ZTE;BmaE@=W z{ly;oM+eA%nTP%l0rg+$pHf%f2)W7PXY9|TYAP1 zj|ou2xa2hjIDxYhrj7(l^3eY!fPU6PuWur`cDvtM z?ceQb|7sy}bnbT+{W%``zXsHQfrtL-0rg+vY5y|<=r8lo|1CiNEB-(Bz63ssBKyB{ z3`Rr}6*VH_5K-~MaEO420f`O@8ily1XaXca6p|Pc1Oy2NkTFE#9TgE36>s+E6%{oi z3M#A7^@xfZT~~v!8eMgxvdjOys#o1L)vxG`;vWBx{Yg*Ne5+o4-+Og*b#+aL(SLg! z^7V{-b{zVzW8_bYL%xxbcjEZ{#3n|5bR7IGB(IPEd2z_MGW=uWkl)7e=f)wQoGQl| zef&Qw4*4`jJ|PbOcVpzwiG#lv$?N_-v;#-V)*xp!~TT~e{~%EOBw!( zIOOXX{-trquVDCR#v%Uz!(S7J{G%kVKmSjRqy9HA@=0;XZ(`(=4Sse1UB(Gopm&YMr$H?Cnhx`gg{}pk_Kfv(c5r_PvjQs6! z$gg4azcmi|4GjOvIOH1{{+r^E-^B3W9f$m94F9}1#>Bi|6m^=A|#-ZmW8`bBGBYE62tRG5$h3y6fVwq55?5Oq0Ke_{RnCA8O%W!SLhz(@p*f7XG!w-_PJT{k+g3{{zVv2FTC1=-y{#qFS;rovjziNM@Ed1XR|4}*_#36gkak7Qq zDUvz$@e6%z@?T`(4-bdrkZCoumN! z+V7>rA7sCJCo8V)=|?TYkMHj_`SG2W9REYaA7uX<7W*3*etiF}$)5n@GsnM)_=D_M z@1!&BZ)N!L{i7y7z7vh(-)*?`W~%N~h+|&;z<0uM@?G00KMLfz{u{mk91Dl)r+EFv z_fMJn&$jR%M*M31MCokmkH1Oe^go{DyDLEoP5I>({RcAoBK*{?8%(l|1?%-``{EznJ*V@qfaJl9(QYyIPq1n@Qfh z{+E#abVI=S>U;+B@aLHAKkGv2sX7us{qgtrrv71g&njjy_1`o?s@%=hTt-a(sU&ae z-$wEW2gpwXc~1W(9N6K|+duw(*VO+`3;zMxlK6HRxSyu}%Pst^#9vF2=s*1Zt;vt? zdBrkK|2<3mySvOXV)8#k@}~b@CHadC0pqK4FUWKLtDG+VhkMrWK>hLed#3*Tzd#RlZBXL_CJ&VDv~$#KZE3h#*ZsNp3{F;iNF5w_hY91Us?D|h(AM`;eML>Z?^E) zGW_`aE0aGL04&qA|7zkt*kzUxlONv`#mPTT^3x4@=@k#G0(s7Vt4M!+{)NBaG4)?# z;qMud90z$+B4+YGVc~CL{D*U8lYduuPXuRwg!m5(;7${}Vu-^Z!8N zr((qTgZuwY{(~+2okvRI{suqlsvltse#kt#LfP5t406SO#R{hc~k!b;CGs+lR5q@CjP?%_|rk2tG^8lKkk1w`O7W*tBIeM zA6+d>`|)?aocgLBc}Yr7X6z^|9q0i>mObVP5s}s@aLQ&1+z$A1t$NS7XB=} zv4unL|G0nI*#2-|D2Z20Sf8!W_+`nw{pJU;FiulJU!zncF&$aNE62IR6 zaR0B#KhMJ7`BX_5bpMCHv*hew!SG|}Gx?WU_=ggI(D;9&g};&UKaMdb|5FzJiNsI0 z0d6gr{(sEE-@@?Y{sWVLH<+Mu?eA{l54!*F0P>vwoieGZ-u`inGWn0U@W0hg`v+S1 z(;5C0hQHpzpFT>u{3zG+G9s<=z(*|nnGAnNh97^Y!ukIs;y=ry5;2oM734YpM~GkV zf1McqV=es4h(Bol)z`v5i?P2m!+)BEe+}`Q&ks!d@plrO|K23|`2qf$Z_&S&^pB7{ zUO)C=^ncsJf97Z@7^Hs^EHH8UPbK-R0R8`E(Z7lDe-}poc^3Xv#2+;N%>sF@{k1au z`!M`}xA1Qy{-EpMR~G&h{Abf}=;Kd1!+%;D@Bbf&KdAkW1bNQ>FvH)K;lInmzt3s1 z;)DE;`|LRWfee2)hQHCmKbZJ~?0?n5pTqFuvkr6oKMfvmaP9w`cJhw|dCvZ+41bv6 zUuNN-(@y{2XyLD9_%j&(^%nl+#2+;OT5I92BmPX;jKuvH?*BLazuCh7E%8q$c@;nr zF$eCm;rzdW`1SGg5Qcvc>~rAiKksx&1Km63z`Xi_`#d=QH2i0caOnNN7sEf%!e31M zN9kk`H|;;q!rzPGKb+yOw(u__{-Ect^%nU?k`Ed`AF=44#pr(&qkqy~eEt1I{Ko|N z?_U=Fam25;-=i7+Q!MjQ(fC1X<|s6)9p{iT~lG*aYO# zkFg*x_;nEC;h9oX{rZ!|@Rt(5Y5%fZS>Vw|xu*RWDt;qjD)H;>cR0g;qlJGX@dwTS zuCegf5x?GkM=<=aSopst{-EbKFIxClGyEqp{7L)r<45PSq~j@YYr$}{^Dhhk2FCvp zhCgiKFCbzlKISm_Cs^d?kbKbmc|6E-{ilubAO8PwbNqSK!haL-(`}4vgE{^@Y~fG4 zSX!$0pV18e?$E%nOtb%dPW(abCk5m=`^OQ#-hNMK_%F2ZC;vg3{H$xaj7Y0IaI%HJ zl=xRsR=ob4!SLT_;a^MqLGzCHBf&Akb{(o8ce<1!B z41Ux8A1(Y1#ILuXa~S^9yYl{j@@z>Q)PGI^dCvb+XG=|W`^Pi<_gMIwh`)D${dZXS zD;fUt8U8I6{to9z;-K;Ka|?eR!=KOapSVBo|3ip>aDe?oL7wyfYU0=X-$aIgxrINU z_=gAZ-(=x$X7~#j{*NvEcMyM80RQ_I{aNj|9kzHQNe9OFOS(q-y@@BzI4DvAI2 z814P{pJ9;a{8vi+5t7I86SowZ{M8ozXNmvV0RF`m{(7eVa7%~DzsADQ7XDL-|8}W{`)Rh{ITrp* z;$KCQSpRrSXYwaO1Ly4DO8n;h$K)Svk>B$?No@L0dc`%zx!fY3N%C-e8grQPYc298 zwUfWiB45x>{{CU!f3r!xkKr)mt8+BSbM2>z>TfCuVExTy>hDSm|9$66x6xx*`2{{r z{wTU+4jejp$_*3S~n$qk4I)?vnXyBaxClP;8`=4)-kCOaRSh#i=U!6H1&-pJ* z`iDsX$IlxX{lBpAKR!{C_RzR7D!t-?pIZ2{@L~an?!TKD{(kU)2URr3k9UbbsQ!9` zJZJwnhW{3Z|7HvS_r#CCFVzp@t8=}Dzm)iO|KG~+C-&m)&nS?rLH_@zg}-(Ikint* z|2BqytcCwX;vXl~a6e7^PX~F<|Eq{!zkc1$@V{%}zlHdVTxJpwh23RaT53Zzx)o8wFbd9MCzak2HompOI+KgRI)gbL=`UzZCcMbP@`fgsQMKLsc2aOm^* zCm8-*3;$`vA9VkcW8oi2{QCI+B*Wig;lG{ugWBIf*kHu@Z#~Hetv_CDk$;cmPnFf+ zewyvC4CFcgS2FfL!`T0-g}>*8lCq!6EF&iWHjDfpNdA}r`F~jS-@vq=21fr=-~k8c z|E0vAZ72*y#2ncm&-t&7_$x^s$IrD4f4znOjcJkww&%nghB{6882ul!@OQXK3YzyHCjV*+|2SN%gF|nB zA29p}^ylsGN&I_CHQZ0L{ghke2ar5HMswv&{YyZe^Is|HpGlJFzmFLG*ID?lX(#`4 z7XB3se>1~B6ebv4`}wM!^*0FQIr|%#`umjOzuLmzsZ2U9X#IDog};U2|BT_^WZ^%u zo&4`w_?;RcgF|n>pELX!u)xpx|5V}+YQNPM`SVCVOK9PJnC*Wt$aD3VPWtQZcQd1Z zPk6x1>3=Kn=Xlg2X7V2h@*IDJ;orjW7hCwhBL1N9r^v!Ti>bfAG5k+j_&d#zh6mN( z(F1w^btids{a0=T6=IIVL7wwpE#tpdM*k}<{FB?M|0@>xS?!eXK8Uyf3X%_+zwQU} zoc#@q{ogV6M=bn}#6LR5+y43Ui5C7=hW`hKf1!o{fO1J3)P6p-$Y+xLSw@F5+s}s< z{loaM3J!h!@kd7gD`0_x>;H=@r2fNX;C`C?i$I>Mza>}6oT~lf_48+j|2qr+2I9Ze zWtI_>|7#0>Bk|{xJo5jO;lK1a-u{zjO2M~DUIixqY>?;d&%}pya5Rx1@^5GOw^;bQ zT`UEI#=p-k{3%yU{&bBW-&L1F-xYrB5Z?a5#J?BiSAo$So!J)o(Ih`s2~udvmxDa# zzcA^qx1VH2{|7Dnw-bL>0RJir|5V0*9T@)4E&QJne}=&?YsCXUvG7+i{3#6oF~{@u zmpn^y1ht<`kmvkg$MAP#_%FBcXApl-{a^6zfW8EXA*yq{~x#Tw=wp2 zX83m-%KN|0;(xRKcK~_L|7rNJ9gcKajbi;gjp3hR;eVX?Up5GhuTHUrzZdb-GN9n! zli~l^!askGR6JiN7F*-Cuu0 zL7w9;W%$Dkf4znOz`2rmNdW&N7XB5)UrX{hf5~9@Pdbse{~qG+AHaXHMSc^>cQ@n{ zjqhb3&-pL&2ANYIKM!W~PaMJP{}b_3H*{G|{(oBdBg9X`uoyq_UA^Y@YqW*Ge4eBX zYX7%b@0RLKxeDbAIu#X{cxXIc5BwqgkByaMY@}n&BIV2xc|JPaMCzAYZLx0o% zSAjfN|4mf?`6Q41zb{k&!%pVy-$eY!8vLgHQH%Uu^QB;r{fEH~0@r>HA^D*72YgQ` zXa7LltOtia{}{m7f47By8u1@5&2T?W`){}KPi6QAGW^>u{Pz*RdH-heKQxl}-!mj1 z)PIjWg_r+xJLMm;$bZ>R|J@7nT>aHC{yU!WUmw_Dz_p)Vm9olA`%VAdVv!%(PWcWn z!Q=SHl6;O-!~Hb*6F{D`e*A)(`Hw8}pOX9&0OUFT%w;mC-hT2K{;w_kUlD&$ z`}xwspHKYy_&t%~KPi{DztiRIvws-KbN0_->@Q&WS6leU6MvBX_gnZ^G4@Yp_*2f} z?Vm&ZFujgB%<(e`MR{vwte%|1!q@1h~L(?QaS3A05EI&B9;F_`jUt zA8z4)qMiPG)FS^f$dWFm|obsu_gCjzM$bSjLzu;Wn{?~|q zFv+XHyYXKcC@$-oihF_=EcY zu=9BR7n3}=C+0Bq9|H26{yC(-?!U_z{hzY%e@gsE#IXDK-#ljFuVnZaGWli{H-L9?RPQ5|Eh(*p7>S!S8AC4f62nX0)MOthwlF+4FB*v-hQV> zG9D=d_tWG*9^^Uu8;M_y6KMYx41bM<|48D`a+zhsXpZ(;bCGW@Sw_@@#7J^}oD z<@5f#%pz|L$IjIj`MP$>r%mAbA0qkg0s7Cd$ZsThbNn#<|B^-iqjt)7oyhCoO7i;$ z=zonxzSEUb@WKH38j$DOuXBgARP{e>zt=PE=eS9{{AkXnfh+pqNH!}S9 zS@@R`|A7JgcUk!J8UC9X{?r2A{-=q5n8BZ5eD4VIoc*(iUmw42VfgQ`@NXmj6AV6C zs~&i(g?|-e|E&yvw?f|jAy-L`43A30O#XdAp0mG!;lGXHzt+NkKJlCV*Yy8e7Wq<= zpBkY5>lXc+NdJ72$NqB%qyON^y#Jco>A%$$`JXKIoBlsy3eVrERw{nDVZZ6WLqMLZ zzk&F&0yy;kdpBeMatr?e;_n;4f0Knjhv8qv@b3W?j5e9;$5V-amSM2zzfK^}**}%| zSCc%}|9uSq8y5cNtEJ(48TOm}55e!eIsN}m^1Tgt!yM;ckmvMIzsp~L4>J09y@2QM zag8KCK7fC3kmvX_iC-W8@Lk|3RGw;Aw^;bkC;p)R-w`g5oc~JODW7kVzl`LA+RwQl z&)J_(_UrBE5yt-Art$j!bggt$s^NdL{mik*cf78B@?Tlx_aphB_O}`2Is4P_Wgl>; zddB|q1Y>{sbl(05@dw@imVi9R-;3dYlHvc}!had@_mysRKh6HvYT?gf_@8F@=N0qz zKT7;T?f)B#{7WR?&(&N;%=WVtIhP)Xn*GT@qvXullU`99^3y$hX3X=-u{WiA9Vk4J;-zR=QH-d#_%6EgXh14 z_%jUq&Gt6{+SDThQGza-|J?{pB`ZURCvI~UB9zP9+oF!4zvCyfjp;w)BXPX`zxdWCl>y@ zh=0!*cB!ilojr%wznzN^L>OU6bIsFGdAag4JVf$-g^#8!Zzm@op3gCao!k@$N zf64HtU&7np^%hCIR{;O17Wv*JpBfBJLTuj<@Fy;^1TgybN+HM$aD2KmGR%# zjQuls*H!~eF0|Bzdy;cEO>ZZPeidl~P)p(GzP|G60CIsYvo{quc3B0{}l^=I`KD=Jlel2!=Jy1xBpw>H|x*z|4SD6 z6c6UP5$r-DHz1R7szw=k6Z2M--F?=vha^1{$8ZN3QYSiweYtP ze?AGK{d+O|4_WvtS4hDi{(CL_kv~fNb^g5>{$>mRs&?{!VBufI@bAm;r!C>@zpudih|L3=VKZbv(g}<$x{DUm~QyKpK8U7LrfB1GV3XWbfa6ePrn2g{)SI+(o z4F3TP|MeFB2=NE?zgi1_FMQcG9QooC_MQOufeio07XC`&PbYa5q^Jmm?_2nn5PyX7 zA%72se=_Vd#ql>$s_T}%g7{&1Cgupod~=+?k-Ry6rQabl2I=1d@}QQl{WdcC_hj@R zeFd+77V)2M=o>b^KS=VX{H+#)3Sje?IB2&tDH`^uNubf0+1>G5AgW|7y{H9LWc@pJt2xwT%CdV)Rd5 z%KN{R_&Xc=oBlh9B5Z)~UkZ?Nc} z@|eH<_ha;b-lBgi@$YTuZ?@+zEc&Ocl!8I+=TnRRIgI`T82!7{@a-o|{M`cdA4c+K z`^jpj{zE_>)bfp=b&URl82xddEI0n=6MxqL{cp7BU)fImud(Rg%;-Oa(Z9i>{|XDg z*?u-#^sl$boBjVYi~hYH_qYEO82$IYlJ|cj@$Vnt|6wF=wx8B^>OTbJK`meVDP{B@ z&gehUqJP?5QgPGY=JzU#{$Y|2>c5v-^si_1&t~-BV9`H|_|5hEuu&hoUnT3$ynihx z`J;^dvQ>Cs3dnQ*cbHS{xcc=U2FOFe|6%YT=(s{F&5#u>YOK z@b7muZ~r#pA0E*Dx_~@qe;s50IEMdz3;)o2B=I!?{C8XUn~8swX8$=1|M5V8^9OVM zYb5^30sI3&p0j@m{<9)D^2MjTe;&{9H(U4zkm5o8?*j{e3-Rmqe?G%M>{{Ob0^&cK z^jCp7{tf|o&i?eLWKNwwpW(m5!hap{_fy0an*6s~_#?!xuD{s+Co=rIU&q_Of%w6_ zF^9>Y0`i>w`NU7fi1m{KhJTiY|D1az?ddV>{^##AEc_`?OHK1h9_^pZ@PB9FzmNEX zo}Ybf;h#$Uy8ov#{L$+z{wIF(`33e>{a6U{P^@qKtz`HwVEDIL_`hwZ{r|A=*D?Il z82+g@@b;(OC#?+f|0Iy->|f3B7c=~CSonJr|DL+DA#VCV@kU<%tai#@WRX9UW_(|6(Z7l0&HSeRH(B)WwMN#oe*Kuu=)c~ge=G5)8~U31 zv|98}xnByJ@}~YN$ByZYl>i;&# zbNa7f{6C-3zbow1;`CoZ{O0_@)c+ikH}!99r~bJh&*|UD=zkfb|3?=6n~8sh;crv_ ziLg%x?Kkxw_ka`(^8a}t&*|?x<8S|q82zh=-+ca2YT-BaSqbu;QGcnf`&miyW_wZJ zRd}1y-<6b+OwwQV9~^&{F#116`kVe+62PzMRx5tv!VqEjuVDDUu<+NmlmAl-e?G&% zl;Q6J`*gVWQ`b)ZRFH>aee<7L4F8o3e-`m)Du+_Ig7^?jtz8KZ#Y#{lt%1EJVcM86U_)Ym1k{{S#<&>c*KMmxC|6;Q_wdB9d!({@t z-)kBFp*KD60vf1}gV#yiOQ%`*%<<+O@KfFG3@(o`| ztu6!m^uv@dE1Xd=t-SZ7S+jbV932jaGvQQ+jLXjf{rd~J?=k(4?Kc3U`5otHk2)za z0skwDJQAFtZo5zzhB+U29?B94S@0~mdot>h2Ok*b!^Z@QPo!`Xgas5Ygm5y&iy*v! z;uk_V4bJIs786ziVJXEgg0PI@GaxLdcm;$r;k+15{EaC5IkVwo4#h8la4yB?L3k;} z=R;UY@dXfGM)4{L7gBr?go`PDIfP3n9)<7RHH6nt{8|XF zqxkg@-azpiA*`eLO%UD;=PhvJJ2&CaxfMQ^Q~WjvS5W+R2=9RNPB>Q*b{B+q!+8&! zs|dRn!uu$GKZFlZ{6PpGg7aZG@%ORt=ll^q{*U61K=>%dAA|65ia$YNJ%mqE{3!~b zhHwqVpMmgMia!To1Dwy(_q7ndK=E}Dz6j?_^nE>q8z_$dH{=zHzY5_-ivJ11*Wi4e zzBfYn2F2fm@Xv6*Mc?0s@EthcrSDA?z6as^6#oFiO%(qS!jCBaF@((&{{+HMDgGA- zKZEnH^!;-Pzo2*vgqtb;C4^fjz7@j1QT!_izovLAgx^s7TL}M7@$Vq~p5i}1_z#M= zLHHxZf1>bb3b#S{Pm2Ew!tE5t!7Tw#sAHUC;B^|~$qiEP`o>Y2U0u?VGoLD zKzIh;(G<^wun)!iLfDVu{V6;K!T}UN z7Q%rP9|YlGiXR8z5Q-lU;ZTa70AUuzhe0@;;wM5lg5uc_o<#AJA&gLbB!#Cycq+w5 zK{%S?r%`x1ggF#H1Hv;YJ_f?E6wjsbEC~NV@o^BIP4ROmJQu?86h9Bb^C_MOVLrtt zKsb@&lPD~Ju#n=DDV###R0xYGegT9RQhXYO(6rTy< z#T1_f;cSY}f$$QF&xLRv#V>_$KE*33Tma!^6t9ACA;lL#xR~OXQ@Dh}D1}#0SPkJ) ziq}whC4^T|ycWW%DSi!v*HZjC2(O3p1~_jdtPaAPD1I}Aw@|nY!dof69Kzcuz5>GA zDSiipcT#*Mgm+Q=ZVK;#a23VxrSLuq@2Btq2p^>QLl8bp@zoIik>dYH;Uf?}O7X`a ze4OG>P*@M)lN5i7!lxlzL-A)Ie3s(RQP=?C^AukT;R_UB2jPnpe+k0%aBhI}Wx`&8 z@KuU$gz!&rz6R&(gf&9=2F2fm@Xv6*1?Ss@y#wL96mNp?J&L~%;RkSTg7ZVdK7#OL ziZ?^}37nt8`4_@IgYd5u{~W?E;B0|&GhtssxP{_dA^aP~zk={I8_uH%%Y?8G z#rs0o56=E@9zz)Ze~n`)J`ln|6dw%Xac~ZS^LWCBLU;njvmhJ>=Wsaje+-~sM?jcO z@sl7tnc@)$@jdvM=M)I>o%9$V1>tClp9bOS6wiSW-r)9FQRZUgqKr%358Jzub_A}g-ao)UIk$-#jmFD8VIkY_;nOs58(|IzmdW^ z2ydeJ%@p1O;WCQfO5t({Z=?7M3U7z-4vODN;YtYaqWIku-UHz(ir-7&eGuMH@dqe; z5W(LkK^D^J6%h3Ht=XPvQIvoSzZ)R|r3c^9wjz2-^(dmvC-@ zb1PwggYYXjzlO7wux}vz7S6xJ`5j^3L-+%n|A4cNupc4(3C^G4+(y_xA^aD`w?l}F zBshj7K#0Gi!gvyd$rKMk*n#5sJ0VO@p%8z!gWo$sxEsYgQHZ~3=}d9_eF^4EgAjk~ zf$=>l+#AAu;QV`P_n&ej(Z5Ejwx&g*^V%ZS*=>>N`WDFQ)V};et(Kk%=`E3HMRO#Y z+Y}xBRzajX`QToVFA~je>(c;|Es^S6NPR~YAfTF@Gzgm_(U&68cSX4fSLePJ%?Z~+ zw5=d=ge<2#B$74OF_8sZR|$q^#%laOhyy9ymd`4=rS65$;P^7v>uti@} z#YSotl|q7>EH%}Vb5~Oq%{9>%TueF}8B~c2KPcZtsIsMdmCz%hS_H>QU6&REov;%8 z-2(3GBC3Jh7pXq4?d2D=ddq=&tA~19t@{lttR@?L2g+#`R+9@*Hsto|5Ob*p0cpPK z!u&COVbxAdKDL2y<+a3=_rI=xn&?;2iq=T=XgIUmp2B7o(Han7F&6J^4@wPyMO9>E zQA7DYsEP|v4Q~mFb{C@!E1k|sFKVdRMYKz|7=8TE{E*$Mh@)#G)##b*w&)w=7wQkf zDX#n&7@*Qs!-DM1s(_kt&?UXEqP%86TB2`6-&dLNyRTp9`oOrC3p#nN9(_~QkS5@& zwUE_KGDbzLD{x~)YczK&(0GPDUyXpYP18fG>0x8hs(dJ56%?={n!8NzF=AxPUZF$> zWiOjM^ErInB*#!3K(e1xsgau8=R|+5+1+ehqW{9!`>~YMx^rv+At|^vQbRFMraF67 zb?!1~zMzdau7OXzp?mn2<8a6s8C@sTP|ax<5A<{;RYpadmHJXOpovti%RhJ6`19QH z%kQJ;=(_(}H)*w1_n)e*>d|$gvMN?UbA*QFb|U9m;tU$JjOz1aF&~F-HIQ!j6X zcoeR#T^5NRB}=YOPK?w=YW5aTLgUcw&A&z+7@88KN~p%d+o4pUPekZ5Ds>_3;ss<> z>Qw^-GO&DPRok%CMZMtLb2*Uajv>{fangqVYp*+gsouYq7gU6r^z0sxx)2w~s@evm zUNr_D`&G5|PhEJ9K>DX%HB2CV%R5%J^()Wb+!wy?6a}aT<>esjpWC;?v@vVvm;Cv* z->T%LzgfwBf3uRCe%?9W__g))pO!bfK>yT5<2&r6hOPCi%<|4vZGBT0UIaH%oBsu~ z0l^#7@=y9{=hTS50?Fun0+8W0-GnT50q{=d=;=cU&{qxj6sKvw@u@g$p z7bT}I#D)A{t9R{Yd^97p*ScE2)J6Ej$ZynNfB3DsLG^D|avxdpFP>-_4SXk5;BDXk zR$k2h%}U<#-OkbZ*Lt&dOUK$RyVPz;uHBMQ+pfZ@?YEHXmcf7P_j`(5gvC4O-@Ws@ z58`bH+6vi%t#xo2k3^rDh3nMOHzIhs{wWfDB@$hfFCejkZLXfwWLHM2ua`3JJvXf4 zRH_^5s@8;s4XF$Nh=tcsN%HPmq?FHq)u&1jfYlF8ejeNc!-7$@6p*XqBcm^mQg_;* zo_4cMi&L=tEQqyoyya&}q1H1NNsZNQK9n^Y>>$)zrPA!E#mlU>WHoq8KOB4_VkHf9 zmnF$X5DB^-h(z7h1zN$-*VyHHM2=d=GyPkQjv+P0QU=^I{s&j`TwQd%NWZGKUFO3| zL1VvwyLsw_7fyGJf3Fm+tuEQTeeqBGu#5#!D^7N&aK<=r4L>5pY#y-+(lf| zeo^a4T~vkjueoYa_R6_svA)q#qtD}|02PV+HVObfoHA z5rlb(*gHUtNNY5U=0bASGx+J0_o$X%TM}ZLedoZ&GJP9ztA&*IfAj`5^@ z+Wp5B*x^7XCe!+aH0HM8FPpJ*{h9){WdAB@@t`nhj=W$Ub`Eo{lLdqB2ECKOPL%c8 zZ$bOV=lC1cXo{^x?8zCeqtD{AD>q9N)+wvzH96&nL3e3_uFQ!U>=>wm(vr6%_YFaSDZ ze9!N-0_>O3*ru)xx;2sQND8CwD9O9C2Vd|)J@{L@f?u@df`FFindHBk?@-jAJ@(@7 z-YLU;E9{@|;S_pan-e_8Ls@UfhnncQ_dQ^9Yjswynj9F!vs0?I{6! z1YZJPnCrPcUAUi14BehS;;Wjy;9VLBvZ+E*@BUcs#>4#Dtg(ICt7c86o1PD_-H^sg z$EmLDn&|x|eC)4}A#$%wqY}iCNj%V&R?AH(U%06?xnDps6!ONX=%*3yVhoP+GQ}(v z9K5AFY9U8FFOUEB4hE!k;g}&0xA^pm&f65NXfiaenztz-brJpmZNa=I+-sP+2!Gk; z?!WP>OkHHPT4Q>c=4 z|A5Pa+6uHiZ52xOGJQemS!@mXOHHTcG1y{o-U|?eLv;i({@^Wtbyf;g%#gz?262Ch~})v?0U4%g-gDff0qh zEnKm~ZFZa3VMsUA?)~GUZ?`h77njqs=@WP~9!v@mel4#l=o|REZ_5 zRd?7>i1gdRGX{tA@=8l)gnL~)wP@1RaM6tL!E-7O3l9Z&M$w!?1D8^;FPkDKmQ+kD z2p5->hbNVk&JNEgFDojZGB`Z3V)Ep|vT%7xNqENe3Dc(a4u_?Hp1*izVOcqeKvq{6 zrKXh>PYF*hDWj5lD_&22MtMnDA<5*;EGoQsu%NRDo(38g7MD~^nW}V~Q95B#p`^uv z%BO&nSeJR8SZuBZifi7fvrN$9gI& zoKO%hDS~ryxCruGILd;rRQd~HzXhwNqF}7w=&Ca2{o!sIJi%TvpR#5ST>4k&AK-C1KqHMVnCQd61 zj~pS|u_}=48d*GZ!Zfgj;G*J!!dYNdxEy8jB--mRaO_~x9Xlp=v!ddn@*)rgk3nOc zP<&`PnOIU*GzAI(J9MhSLa3my3@V@?Jh`l7x}=~?ZofJM+*AZPNEVF@mlQ)6m^RII z-eJ9+aIfhTW))4Zn2zc=h7q#AfX)*q%qW_aC&vQWH3#G9pgVt3iR}G?z`^RBKz&)N zq!%%GaNcNeNih^yF{xbYgsu=Cbh2j^P8w4_p}b^?D@;|z-NK*)Z(zyzCq|NEH0$F{Y0A0lsnqGpbfo_UiGhY=kt8V9P`j8K} zp~m*OGz71@sYwXI%Xgknz&E$CRYje^t0P#*^7UX`aEm9$@AV9I{$E+ou{GJQdeYiF zKIhUqB|c}N?&>Z zI^mvICWPR{RktRDZcT(Y242qfLOBb98IT%5V6``z2>Q0c&<=1;3QUxtEU*81mt@$n zg_q=3SkE4~7B(KlUR5*UvKaF`2H%IUKD!lHuC|0CRoSfxFJ*rXqZ2$=#zmC`c%qQ~ zwb-B|H$jP=uNCizMD~HQr;|QvR5he1Ym7O*Z)CBi$5)1LXcJDAFCtJk9s1Q1A624D z{raogps5b64xu(!8C7e+GPkLN@;tGsx_0DjRgKm z5_?DM)uFyaQ=6R``NQg-9o`)f#h<(2eRvC*TSE_Myp4A*KLpD;xv z^|&wuFS45xg16^AlmL&HzfB0i3#S$&hL$Bck0s(P31q)YJQ|YD3O&8AQwEX0CWPMJ z7xUl?_CjAnGzp@&CWWHu&XXAZFe!9ry7MDOKS~ZglkWVK4AJ^f=-qVZtq?@7=@9xR z-Fc`3M7MSbRqy94*#)96?Gn0cKj%}7u1E$Iv}poj-Sk=>P2&dcLdk+HMeC+9~uwS7%ixh<@HF^nF+7vfUxNZuiht z`#a4Ty{&WT-u<1YJ45uV&OKh(-?=*#qMxOPKHT4_OoQmNX`z4Y@4S!EWqX9K?&j3* z0nuys4Bg+&d3aBV{%z0Di`|^)UJ!k5uh7TcoDVR%eXr1u-JDyxK=i#Xp=%FtzQ^bz zdxsu8z-Ry(>|e34sbSO^yYm-KOf*czVFBI(_V1-{$~JobwUW< zmiSUa2;S9rQzFK{M5jaYkr#yEy`MHEMBB#O|loCSUCOe-bgg#7mS`$JWlAV=_p+z0w?Tn#ELhug6(DIOT zCA5@~vo;CwPm@C5gq+Ic(58@cRdQ&3$ax_d@#WYyKO|*0`r2{KTzHf5mn!eM*CxOVf}<*L{=3-Ea!Eo6-jBHkOZhzE{40{2MM(z<@{VKY!V8kOsN%<8n*i?~zJdzqg5B(F z?4EZg91T3J2`F^S!3kZ*Pr?^8hZZL$e2tZ&&J%IB5fruoR@EEy^%MEh zGf1ZCDePgc#$^w=NQYM;xz!(*P#PcwW|9uvz&F6x7T9zPCvJDtxIsbOkm3FM8YWgy zT&FZK!4eyqv}F#=x}%+paJQPNE|;LaZ?+3Oc%jK|7HYS|UTK(JV6iXd(xwUgl*7H| z;*~N2ih!*ZV0&)8?n1F~>%0x11|;iltQQ+Oz+8H5QPsQ#r+jb72SvDd0}XK70`~AvP@qjcy$#d=ss;^0{k(35YK>Es7R_A) zO@B2!P^upl9lgp|e_Gwuz^klkM#D`cZbPhC15LbPWE6B!Rf`P{>PBnynlSF?6|EoM zMWa_0-h{!DkgDOD(T!NHR>Pv=B@CLn6|cdodAOd3SH-}f%@J51rtZJ2U4gx^FX$up z|FSVMW;FG6L{Y8Q8#I55mCYMk5H=sZj$mtS&~08!i-Cp=9v=si2*!|F*VbX%w-w4?_yJEb)^^t!4eTjUr~ugzmQ^|J6Y66y3qAFke%R=}tSp zoBcM<@Y<(7LU|~)ecDba8?9_R-X+|0B#vV{b|y5!(d1CCy8qn{rA8-S3F>KqGl1W4 zB(nD49XkvMeCoNLs=vL%+SPe~dxu4si{uXd6?<{~AGtFAwtkG6F-6TTELY-7!Ou(Z zIi}yamCA|u+p^1HF6e(iNmFwE$2Itt0ySs%TCf;W-GwAM!qSyV`*D`LvCi9Z?#YM; zlO%)BS;;gxlK^A90b9>0p2XrKO(mIIOZNbkFvivDQxo-Q_6UHh;75a^*XadsnTWH* zU;D@t%aBhUJ*~W-K7dlpc6KnJYF(-Cmk<%vUDz7|Z7zrpEB?(_HSxn3uL1lUM%x%~ zwCB=PjiX2G)K}E`hS?hhaO1z4@V*NRu3}HC zcj4dhm;$X(-1EfV@WfPyf1H6k4%e$NDa`%|6o4BDuNT*3e+)BO_(8Y^<$f&ZUK#|s zR6$sXiVH`(eZCnVIhprL?Cq`4A~xriA*##j1YVa_srpTpmul(I=6#F#y9{`80g_NN zo~g>TD4Js4QfPHWi~28RZ+GA~c+JkGdqDnX*m2S_Bj$b5UUj+Ei?=K_Shn&U-pE3` z@U-xFaDp=ss=i4r==kfnQ56KwYEg+s*iO9xUdE0~4D?cKNJ({veZ{KYpsLx9>k)8P zwWZEH9;Qh6t;zT1Z{Zox$CHykTaAUZ)c{J8eg#YP5KixeFvVcRgo2s){ zN3$PA2UI)wGg*wJRcAjcns`$bqV-$4QRZfmc}+Fk)qwk2Q=dfDWxt<6xVd|$yTlu6f>(Uy3;!N&C=w!~h5L-`fWa@7ac1hE#y!#`LW z9G3#k8d`y>FEkTUwaEnz2Ka2rZ8}ip`j5zyI#?)^~#9J!sfj!*b=^EfZ96`y5>68emyK zGy>N=|L--mp=o6FMWAd@nMZ;Xw6StjLhGo6mQe{XVB(K2Ghxax?7U&;dwPJY!=egs zsEE=a1r;WKItCA2we=$S&kj&DvMq%D?%1r?z2cV z9(@Rt>(KzKM&n>x2aB3L2-^|lNQ2e|cB+hsLZ-A@2;0oH- z!UE(s+@_Icv<@u!KWKtcn^xb6KInESRN8b0n&`C-)y8|7Z5*vFSq{# zs`V$#BUZg(G(5r>pk#X!?}WgsJdAWW%i3iAv@Ivod>u*vebpe>XB;nxJQ4#E9up))7Q{ z(!2$Yt*h7(Ow5I;b>Vb5nkZDM#vd4py|?bD>btz-Jlj`wdd2&^Dq4x_I3PpEwSn29 z_C&N3Ms<5FH37TvbYI8ZH8n!1puRqgf~t7u1r{;>7r#M-d&wlP{+X*ds7rnt1Y3@8 zY)E~)0k^)0H&}Izs4{keC5_gZ@{J#|>!F9AZw@JG)x_WMfDxs&~7 z{8CeA+Hrg*>tXyhcE{X$>VJzKx=uTa|F`J7ll3ruslFo*#HRhON31{E`)w!t?SH=i z{qB$0mh-zme)mVL2Y%VN-`mkI^V{!I|63jyQ{HD#-k4H&jaWr7yf-edpm17Yd12Ye zoKpvtPRWz+qsuvI=9s>D*<&V*oS8l9v_W}!Q;I9{Ce51Fr*Gb0AA2lvb<+<~0r^YRy#m6enQ=I@*7+6C{QD=wT=UIee9+ku$tam5Gk zCCn?CoHxC2dP&*r9SF+&g9?gfT$nc*Ub?q~tS*NhA%FIT7bC)}H;X0}!AlIWS(j9l zO)6}M#;klPyfv_BTH%x(IhK?ldyj$IE1XzaCiHPAo&5F zynK^k`=nKS?$dY1?BenXv+{zP2etn`gNo#P9P=hsl+7q9%ft63wwF?`KGmNFsPeE+ z&49NW7EZ^C3@(=HFH^~rKB9>BD5UCd($qp2>1Gy{Oq+mhy*;AB4$uEZ@W##f3n2ab zz$;%1i>4IkU066fu0n`^AiNhc58o*nmoQkMW<$Mg=O{4=3!N`>eW0n*C8iWw886t>^K{#buy#S^9l ziBS2+7Qjnsr{UzF0Hza@+UI-SE)|#M^&RN-`AH?yOJR~FEQ3Ze=i-Y9iJiDo*28E8FuRPgPrVmV^!<-(*I4h8pg)sJ`C2M!FkV{ zW8U&29#_Ka^wUAgw=*OQo^EdN@6Eu?nNS=(I*j5=hG28J_G}XN3Dk^+UFEnt&wYLk zZF++%B$B8AA+4U*`ggAF;He<>0FN4WId{dr6RV&sn>IqnJ~{Th;yTUOREi>^=LV!N3rJr>>0?ACQTt3h z#jAfxxA}J)rQ7`5jXH^~eGLgnA0LoDm(p$iT^5kOhSF{JZK8CWecJ-c?}h^f95(%i zP`ZtOJf++C=LX0x3y@z!=>vt5RR1Mj|J_9CHvP8+@OKLd^BtT1_!1#OEk1}}8=uAp zq|XgVUlzc>hSIz1{JEO_lrG*OqsGrsUi!8G`EKyiC_HTCV_L$ToKfP+vCA#^b$@mJ z=m}r&#A7;)Gs4wMhm)5kRV62#mjJ4CgY<>Ob1-IBdE{k8lrar)I4&ysBw~Z48lzuXjsCIX$ zr{6+KKT=Ph7QMdgi|#v ze*~r5{8vEfHvJa{l)sYFkJI_fJpZf2uSQ3!FiqiK-9h6_slscd-wKUGpF>S$iS|r;k=BuZC zLt)%a*2|LDdCJ0Mx6N%J~bg z*Pl_ZFyyPJeCVqfKJpiGb-@J#IELeg;+id}ME~p`kUo~uFVW=_<$#Ulms7gvPpbS0 zUisHi`tiDaxtIRv4${#V%V@lR9O5xH%DTK8OF})iQ8~8tiEewK0*+(5ZVjRI(U?iu zkvKvqisg@|^k-wzA9K^^Qu?_u>9SL!{4z>EQctIO0ou8c#`G5;9%Cntr;DUyYq8!6q^uC`LT?Yh!wFEjv55FfGkbExNcq~~Z(&l9Acn6Dd+ z)w?tK61RK$&Luw1FQWb_{a{@m?Y?Ls@f^wUBz5=nd4Tfu;qo2i<$H_rMYw!}y?W?R zi-z2_OxRE3@ylj8a@>CsOTv63C|_qYAJ)6$={1e=9mVB4(9>%p>D5>Fmo^95x&yt@ z-8iK}&82HWHs_CH zJ%4PXa!_BlUncbu8Bot{l+M{3hV*V?V1)Znh`aJQw&?eNlxMo0N4vkwr*zSjRiBkh zbi$TON?)SOpL%6dP4d!ERfj||>Z7i!C|{PIPa9)41f;hFq^InQ1@m=}{JkiBHfBfxMP7J@if55i6fzpfh^pQ15OOvZYv?MRa$X3dirRUT9 zn3j$S{G1N$%%pUjOSyi4Hi5V6n4S|LUrOoR*bxT#T1t<(mzCFTabd+gj|SvHJ(_l) z2l}gx(u4dJ-VZXv!L?uH$)a@59!$@tbk1L4NUx-Ho4r`ZO3EXeuxfkSbCh+IE`}$S zp6y*{KBIJaWw}>pXL#w!BEfO`=;>3v^q!P%n~#m4beoR~DE%nCeC;{RLQ3b_wy>Yl zC+YHua*+zt*HQWbdiq#T|Ia9$Tc5$UpspLInB%FuUWqFo@*F8{zU*yb6s3#HjH(B@ z3?us9G)g~6*Hc?-TT1D+`Q`(ZK1`RNCG89Yrmh=!@13mYq5E&Np_R(W(9^Xw&@{{h zhwYk>N$FEDld=)737Q>aDUXe#oYKW*OqFqxS6|l!q(4gOy>%V5`RZGgK3Gq`$SeOl zO1I4ux`>9v`v67zQ#yD34nz7_NA0XcpAm0`spB~1Bvjh9XBH6LpPwCeB50I}5kgpGrZwioa z3y@Fm;fTYg|3FH&+8-c4D?q+3K)yaez9~SyEkHh94Bk7ae@eI7A0R&~K)xGb zZ!S|1kiL-8ZF8BG0qN@k(m$j0{dE0lE`|_yBmkJ~e6yWPOLES|WZ#kGoNvMNEO@>J zpJ>4+S@1#&KE;9;S?~)jIPT!^A4yJ$1;?El{v*kmVZkdb_{A1{wgtb$g3q(y^DX!S z3tnZx7g=!pPo(}M$%$HU_k67@>Ecg>X93Md>I8zeD zT8)Uyn#N}yh>Lq#4UZ5m?o~B>8sXypP{WrJJ`h4Y#5F@kq5X(=SJO8yNOHtm(L4ZR zkHCrg3?VeOoTq(uVYVda84LcL1%KXxueIRoEciCZowNZ zIQ)}8=16kj-z+jmlJm9&hyMl097#@-1%JeO`M{SSlat_|*=yO{ zXp-}>1^>i?<5O<`kp%xk)Q=+X=N26Pb0u>m!9QwbU?>Ov&na^xIbT_D_$QCdkp%w_ zm4TuB?=1Ka7QD@Z!@t*LjwI)23$Av8#|kAm|FY!ApAq?yK++&v<1N{MONzACr=tP8Phg1y8l$dsy&2EqE6TzK;b@x8PkZcsC2)-GYZL zc!mYkF?;YSnyF6{4@)Gx&=SOf{(G_xfc8^3qH<* zpJTz#wczJj@H`7X!Gce+-~|?ZvIU=F!KYgA3oQ6F3tnu&OD%Yr1uwVYGcEWm3qHq! z&$Zx}TJTB>zQBT4S@1;`{BjGv#DYgH_!Sns+Je_u@GC8Ntp&fvf?sFBZ?NEX7W`%l zev1WPX2F+R@D&#P4hz20g5Pby@3G+bTJZZU`280A0So?+1z&B!|IdOyV!1>a=Bn=SaK7W{Jy-eSSO zvf!;2{5uQ&g9ZP|f^W0nFm+)LxL>f~DHgn=1@COZ(=2!w3%-v9?`pxjS@5t0&#>T! zSnysJ{74Jl+k*GC;JEADeSBy0~!7CdCZcd_6p7JOG9jw^xK zZflN^YKUi25S1$=^y3^?L-@fxu~F zyN16c@ZB{;Ml*y(Vy9tD+5&;6#$fp61A)^IEwt4BA^bu=OwjOa1TLNgYN+G7w455HL8$NKOm1+Jbtc*&atKF9+o775Gd51`mt0w3zbmkIm?AO3>CvwZjm0w3nXzZUp#AD$+<&E+Oyw@B;<@o(~@?@DF_WM1ga`Tu@7G<@K1gC^8)|O zhyPXJ!xPMePqvx zz`f_H)2aL~E#-eB@)x@0WK;gVU`oO1(-rUxr^wB(M*K`m{xKr|g>L?%sQl@G_i#pt z*&sr_2w!X|XSt=EdVx=O%RidRdDBwP`yzjdn_t;G2&PJ$z14vCaEAKydE{!fG{ z9cS-;fM+=V{3i+A+c%~BJVW5#zA44~I^aE=OrM@#Tk@Y8M&3(YJykjP0N%qn+*i(e zOa6m;U^(-Aja*jR-%Src@ zGYaqw$DjW$fmiv;NrEYI4`)wbIR^ut;rR1c34D>SoG(NgqFw`tMzU_i&PZ}69`GJco3EV5Ecy3149oHM*Qs(Y z0KA9ut*@NRE%}=Te!Xj#s;{iWv7D{GatZ*?aQyk#3EbPir^@Mh1eWuqubc?r8IC{y zDuH|Z{ZxJZ$%20?@LOE{RekMyB$kh>cJfgA6an7D`OK%!d`tc}1b&;ZoL-<<59cFa zIVS?1;rR34Eb!aia+F;Ui*nBKwdWTA=f>epmU6xk_?>R~$`2iSqds@JIAjyYA%ORA z#`$=&E%^%t?(J_>9sfsr(NC=k)Ijf<2rjpWns;p5ge*c|hRzyXC8TOv=P^ z-tm>w9qL7tX8>BnrL?}spgvt(d^F*efOF-%W5Lq~U^(7;zG_!}0Po>E;`T3b zn*$tY0M3R}UsXydrRK|Eij~9(gS0_x7o(`mGdr zSJ$5~Y>Hzw;GDhBi2U8${4Y@cBp5)r{Am{a3=4i0;2F-#Zu`lg@>>P|st-ST5a$1r ziz|C?6Zk%^p3hP_O#=7!&8qST490T2eY5zS36Eld%hh%KuKaV0z~6Rx!R_LBUEtpS zSXD3o5cmgf{(~t0pyQA??CJ@_uQzv7)d1bO}V zn*#sD&9BNo@OaGc$EOMWFK&KluHsk*_@3JDUsO3Si~Qbx!r_#EyTCtp%gG|VWGM3X zbp5072L$fV-|Ym<@9o!x>5Vw1TkvNE?(O4Mg_x2l)C4H{9;P(mK+lQ>$=W7E0If29-g?}q>Zy)lBl;I#~NZ8)C!uau9pNhfg@mh_HB7g}v5;`J(?peXE8$m=pB4TD;2F*#u3dXm zIokkFqqrV)fDViPNl%uj>c0mPo=-RoQ{os1I9JXeDE|t|uk|Cq|^6<>ddKR4-=(&gruX@E*=;@{Z%A6Yuj>PF)8HY^HLW5KlZeLA`?! z-;s$&|B-z8CtL7kfcJ1-^YK0nc!uNcKT-3&k463mefbkl!TjF-D3$+EzTm4B+pf1fY^LXqFwZ=>?xCGxNI<$qD+_xAIs{GW^bxBK#UI90Sm7gzZY2fT-~ z+{IPBj28LBF0S%V6Zvm(ah3lHk-w{ptNg1({yG;|`Ck>o>7b!8j}!16weq# zlqAMKF(hi#L=&R#^Hf)L|GK+sc50dRec$;gyZi0us_UNtIF?1LVj*YewC2_ zMaceoAwMT1|DNFULVTB*`ucgMf#(hU5(B@D_z*a^rN#*#8|3R~fIS4xb1C^Hg74v` z_h6^`Mjj!~_4%3o9k58=kG7+MEA!FfIU#-bjMO}e_yDPkKRSpHiB!Axr%F42G{_%% z3fZUo{z@6h7-{ST;yU}65FZ?QF_ize803Fz;O`jte+_)(shqAFH(k5Sbgd+=i}RmC z-rLuw>fxTJar{q(;y;===ffhI4@by+IElE<{;9-=M7&*``%3wr3+|oII$ZLxvmE=I zr2RoM{ubgo`}Y&4d9E9$ivQQd2S*-v`2o`Y+Xg%D5$AMmrRR$Lq2Z1A>~*@{?;!?0 zggD!oaEPNnQra0~ke@8&7fX3H4@w*4yQRE(PuM7Ff4M>a4k`anX@9Gff7T$sp7@Z6 zcRr5aLCc?`&d}$>ImCxVynVAO|CbXV9C`pX8PR%*J4>(X_uuydsA_iSnZO@sVq zX@A&}j>B=%?`~%~e$Ni@YROkievXu%O?*hiJ6HP^$*(f-wbIV8VUFPOQhtl%?E!v3 z+==IQ$sd;TIpVr}xPHpqV>$g_gc~S82y6*lhdi!S?_-f)qBHlU8*mjPC zfvwEL>zq>s_s(ys_IQop;dR1wf_vvWRX*(8#`aHj(?x%Z&slTq8yL^G&vUs-*Ea<}-sQ^g0>PKKd>`re2Ek8q zxvHP<2tLK-lcjuJT3=6=5g!8QP1JquZsLO@5APt=-F1?m3;FY1`zp@O2K!Z1foXq; zE3fi@q2S*6Q8)dv2Gf$y8+ zc)auD^)jAWf-iI9+(YtJf_vv`50ZShd2HumSAIXqM-U$%f5#t927ZHqzi!}%|*(Z%g0DN7YXj2m)~3RX9VwXjhV<&yk4Qf%*Y)UA@|_o9%e#od-($CklR(>sRH^dBk;g9v1S~y7Gre zJ0B3Ibsm>DNPZOEAcjQ3@@;}&@5+Bw%HJkk{e1$82n3O+j5!+ws^0AV?BlsOI zA0qi_G*BE8xy$9M94{CAZkN+-OMLz=xOdK4+4<&Tw)1^g{sbw%UhrF8uEuXioXhgz z_%9Xw9#?)(Y3D=1!*-^g$9BAP+)Dmo!B@L>hD$rqZ?XK3U4ES8cMBelf4?Oxf1fK~ zBjuM1{(#F>zHN6t%ZKwVA-H$$yH?s+L40szt!qcsllO$YcOLvKDSyfZY(JboPYNE+ zha)d!`8BS68V-riO@fE>VZc(B|EVjl(si!j-udx5Y3C!s!|D3!MQkS=|8;^t;o4XI z!+OD=a=B`Ep9=1se?LI_&3s$m9OT0=2 z2|uqQJ_OF`t9TwFuIt}k6!PKq%#Q_s-YqX>=fF$Zet5m~c)?!@$)7IxODr^pD6f0T(0cT z75rZ=SMrw#{*lX-{M~|Yb-9vXC-{F{uH^qJxOaYE$@jmE;}1Ud*}C+{3gM}&!Kj>oZ}o6if6Fk;pbl`2=1NVSN6{mJp6p^ zT)~Hh?0-*i@4Wx9vTgia@Zll(cLWbVAKd8*j$f@p$@dqNtzm+PpFcJVK00K-UGVVp z%?kzh&hM-A-YxhT*N%$+*Ti-0_Z{McBNJWuVKTitUdi!$=j)aIBZ&`=ObW@zguHit zU&*%#`IAEOON6|49$(4dBIKuperdX2S?6w?M#;!?i4)ka&>=vMDT>m_mJ|x61>Ib%GW2v)$htD|2&j#K!YP~uKdyR z;#9#qT&~6g7YV+5KV?JNTqF3|uDlut{$B9T5dTc@oXhu@1`qr$$5ROLI>G0=T+QoG z6?~z~m7RHlFLwFf(*DJQf6L`nlK)Wf3qt$_!7p<8fl_{p;LBV-Nb=pT<@mqjay2jh zir`ncd_O5aLGY_xuI3j>!LN1sP$_@8;5WEj<-@&#-{f)?=X$|!ak+};UBOqnT$R`E z*Kz!}yIiH~Si$cK@u`CUz~!p{St$5wm#cbvo#6MnT=`ui_yaEASElzx;;N2GB!0Xj zg)&$(RX+hKzL#^tI$#01~qa%I0w@Rwb#@}!%%`dzu?pH~q7 zUgQ;5zQ4TqghBov%-zw9XX(EN`TooGe)ll&fy8y|fwczt$wEH7Up*~&_<7kS20M2O z`SA12rwsD13Hk88mrn%`?_)XSMow3FU&KHZ%I^jD-p8Wq z$>^KdulGI{#cv}%II@e|&sWK!d`QT9?`cu}>RW<)?`cu|;G5aL_nsETrx4fGw<7Vu zk=XU zPf&F6bhdSFJeN(US{Djeb-8&Y(U48G#WUGV(qj#&Ofi|yB+^r&qmrGu;=*`qwlkM4 zq>9OSq3FaJt%;vFW%{_WQ{wSy@o0T=URNR=n=!eyDH`WQ3frTK3vINNIh5vNK9MRG8e3!Z(V3mr6t7>zI)>{lLamN6 zp-@Z|$xSMgDy9u*|Ahv=4($|R{svgxkQiuEMX2G4SP zS4MQX+n6FRL3IC9Q5O>}>57$ZO-(9O=xT3IwWhe@0AeQEaGNgsWe9YW_?NVuF+k%P`OGN zRVm42<6;=mo~8CwsT9??=G}tGXBYIo1iXaB9ceBT{yk*^o0g4>PXWlG3pQIWv_yF431O=136!A z@j6!OloeAEJ7P87oJ9`v9bO&cs@914O?`VRnO2P?E;VC3g^+jITB_wf4F)08HBsu7 z3Po9K<21|4CyLoT$<3g7foIn>YgU*!xd~!6$oV3w8Ks=hPv#3rO%T&L2!kna+S9Wg zH#YmJ4z=E~X_~&q=cL+_?xf1z&iMMqrrLOn=cyD;t*RV#ZV%E*y5YgtrCHk~So+badtqOuORM1`z-s}#cw!{}KRPe8^ufcMD+<_^AV z`YDo6Brv1%UGwITJ{*{Px^rirP&7Dm_g~el8TbW4%N731y2TlvM5!erzo2%d$|n*H zu9Eq$hF0f%mkn!!J{jHGWI!OiFzOcwEED@K8kVSiGSLwl04=dN$x&8!FrVD3_C)iq3qY*P6{OjLm2zgPjpt_G!&6BtddqP2=nNaj|~f+3C1zD%Q|ws5pn_LvguK zKO>h)6;uE6qWXA8LT3l&M&zRrohGA$J z<7+DO>}Hg=h_uZXRqhx?z$*rTx1KxL!WJqWB=Y3Lp^dL^K{TB%&u-RQTyw^4nA&N`+` z^8mC$Ey*y*sa(m@6Etzsz(4r(iyprC0;Pw-Nul4E$_ zT(LewZ{JIp{(8kySL%Ux< z_xBlw)cE)|Cc}FQ64-0t8@G`bRf zokriBC6Li>5WZf@D1`l$w>nz6O!RDe+2*lIWmI6zw{qbJ40~w^T&Pq++oUjjSh3{>{l>P6CCGa?=X>zxCCngDsnYk%`?uEhK>~da zbP4ncYog$;j7rD)l{r2q!uOlX?nRwM(Wa&%~ALE!`9pS?!3AH(a z?sw|ch}%E9hk$CT#S=3&-k!|ImggU-(u$PVs+0#oqKt6qguZXKQ5)VB}zv;9^)rzos{X4wda$*(mExx zAVr6mX3_z)PL`pvqEi~Jb7(g=?UeR%MpI{^QEo`GT&Ynw?MvNM{B^7sIT7<$$_Cyd zGlI*?t@8G{OWSr0ZCSJox6VdK(&Nu~N1o1GQI!>k(;7R|u~>_$ebZ>qP-~3phI}|` zd-!U6RI`(iO{(&zzQxw2dVbm|9y|8N0GFqeB5g;}t3nLb5>bZwT2g+08Vi|qcE@Pr zwlM4K2S;#~bL`r5_3|;cQw-XG;Mid(9cABAjBOLF`;t@3$${gQUTv@A+MZ4p=x8FJ z!xVipRQ0k$qW0iCo-eT*phoO5X!Ul_2DW&5+h9xYF;wGJDqOpLk*bA}VsBl$&ECBA zUrznViD~P&IgZ}6v$8WQkmf${Wyqc0c#1(O`|`1O#$;roO{(*_BRdmwlg^oyTvlwz zp*rkULbsK9t)-?lousqHw4g($qC>(ZN}M}=^S16jFBmaJ^>#qdiMaO z-tq5IXD=H>B~H`elAHk8Cy3)U!9)reOrhaCOD+e)Cxc99XU{TJP~o#XPSRwak93aK z7QmJpJs$e;^3o8FxM!n=+vAxOf*E9zD>Ki0wZve{S8IAYDpV8e>BteyAb3jDNbgM$ zmB`>V7Mo5TTaTAv^mA= z!?2Vf+7j#)wu_q2lc2J*&1OS)??~I5|`7 zqHWX#uA9De){FO~Xp&jqp3i1jS8eijyJ+mk!Wmb`JHA0p)|I-#f<%tajySi9-X}=e zG2P62)1FEX9+XFCnB>d6nncm5I-)xIHYkgMOK*aq{C1a}@GUi>^@Y8M3m{tW?AUg9 zE7N_uH-Ye)-Hemv0G!{GGm#I{y46ARc&s964nM&1`W?e=X?f#P*=CReGlsWC1nn5a zJVU{q%mD+z%b=*)5F1q1h@gS+?$3~cu!v{Cu)#85!yx6E32$f&SO^P%a&Y%xP&as; zRaGhXv;o<3quUJ$@4}P3$~<}V9X_jz0jlK^G}tES7SO5q((wS=DSTrYsDjW z@oG9c#U+LYsuBD54??O!oA`pBLjs_z*((=R*NA|D;MTODcJR8V>h10c=y(@A;lMVU zfJWe|r>5U*5zy8Pu@RN`rd?5qq&TP|7s|A^0aO(HiF+cl^A&s}L(cEFQV~JEj`PhI24fy(6;M z&l-7o%$b#l*?>Di=aabf(uBs7=&4Ql(bA)vQq_P?-8=7>q<3mIjf+pnIc07CJTuYc z9(tF1Cgg;zp59QHU+BvfkuJ5HuGdWlx*%msGyA<10{nXf9ZGc#T&eDUwqY=`K;{{bg92pshiCK0Z#X z`ED^bJIg}!F01fL!YEoiiqmU9yOR9AtQjZMpW?4@Pa0*(R6)Ft)s;;Z`1Pz|;c6C^ z=h~HB=g+V#y>*LUZW$K~!5l+7|Hg9WMwt??kE%pN^uGh40wo!ItAg`fM2*OzfyORr{yJ?Wjo9fo-ggw8AZ3^e0xhMaCJPH__8W(bJWZ zp{Iw?8}{%hj265LxS^{Dap&jRFU8=_Q(2+y#>CwRE)^Ua^PuvZ)}&Gc+w^^zhm!>seJFGN9n$o zhVlq@R5HV(?RcuaaaJMURHW~>;V({UJW2e@j{^BL4!y*arfFg?Ks=qAD|Xq?8d^=1 zsMvqw_8%!S)<`+eD{KwwYNAk}ufU# zz&%6cB(yi#+jm(q-kc?LNs}ex<4se&#o%zuq?{^qWtEz5sl2F%ML}rerP@vTzM+9R zJ0VJ$EfrHP4Qsj{o%0gBlJ!L|EsdaRPYWW@C5CHAxZf6; z9~Ok!eXyr5U0iAz0ZJKh?fjv6n}n3=vsi{61M#(7lL(d zpWo}z--tvm$6F+McJ53*Y$rL&g8Q(|eh8{eI8S$)iVgI=I>iKUIp!%7-MXUn>gyd; zS+M%M9^Q(Mg@Nr!bxEpzr4skI|jn>&1+bd;KY^HO3&%OwGtSC-r&k(Q0wKouraukVNqLq$XJ9C*{G-)@CUOqIYWrQZt zqUkJfB42P`%j+JWv27Y+QKH~ITcH*vPAH3=#FW@#>zv-TIWcXg>PTC7lH6?xtNEmJ z^4a-|8nyC3^NJQaa8Dc3X*NPK^m^u`*fvTP$!KYHm2RxMWm zIc1WM62(GzaSkS4_~ChtT&i z1ZG4|8{$r-mw}cz&sNTz&wqMc+~vcu^r98_@VGX3cEC4(b&iE#(U!4rBWCs9%1^Hz z_LkvhteU)zkY9E|Uv?-*P0l=}b|l`6>0AHkJNWXl5v#Q~-sVP~IV|$SGDngg(OWDX@SeQ>Qq~6R}8le&A*`b5;XS*{A&$&j;S8_Zm7kZTCw&f<*Xq!*% zg|2gtuy^S`&ahXNZ#Ak=-7-`JvR=XOl;P7+{%_wQ`wiY#PT?=1?Ke+*j-;GjkiI(>jI__IhDsP!qv;A!aUtQ5hU%;fE(pEm3q-B^u^-U7+ zL7Q$cQf~2=+n^hy6PlONS3Jr2dAO&ss2=5d=0yqrw@Q5>ElE`oy1#xA`5UdKud0#X zpysBRvzZE#CI>Xwpoe+1z)~o?VV9Y|GzXzQ!t%ae!FwP*zYO=ewnG&%!n0>FRHQe!X(t(4axqNDVDxK^|`gDy#Xes=yp_t#{t3F-L5nW#dy07C< zQzoZ8LT7~i`r*qy|Jv^)^~JB1KpQ2$wG>U26!cltf4!;CmRi^BK_!_$|;>i(b)8kJSw+(Y%1eU%!H1 z((22^;6?OJDWvD0+!^w|yh2wlm*rz*z66+Lq#f=SqwqM^>lEEr+-u%z3>!!^SEYZ~ zK&kyFp=&{9-B~85Sq82I75yjL)Lp`NrY@)wINu1V3|t8+hF_ily5Wlf_0nHc>scx- z7c|=A%PRB&K{MKSgFsB$>z)zbfzaCBooGqTkJj*a!=~b`Y1;lNwm!u9>uuRqb5msp zWnz5c3=7n`Hg*ysJZ3F(&m@~Xbs8pzhuo&LSQzD`+mC~s@e@rJx{Aqe=ecp|2h}2% zOOBMBf(VNE#yKbw7^dhixo=8PnXez6_?6|C`qI15Y4;0W@&+16149Vvj}o? z#vO~GOlTb8yQmpP_^yXW0lurguRil#(cSz}pwunhC#St#qeSR_?7JAc9phEQtrSIc zH%kBY@O=`mm-8MbRf%*j#8TG`_d9gud%>Ex!2N*lyQHDD=)PybXDxIK^GwpdDSEE& zY;;1Cfm@fW;J)!moft-?;0;a8pzz*}!hsu>FW~SE2``tv%lIVqcMzY5_V$1h)c@wQ zbCbLyF_WRqiM;0l5`wRG5DE6r;YjjC`32!+y;@TZ1H8xQ4Q2XU4fDjT-rpn)8SCqm96kjCJ7Hmapu=D0>36p4uy zX7`DAc-haeT1X=oaqM8G_q05$i_58=g4lW-98=K(tK2&p93ciH7EN#BeBbsjW;~v< z92fb=bv#UM@5+d-C>TW0UnCMafd1!CKl=Zq?IV$`pF5w^1$Fpf;5pz^fL{r`AMnk< zPXzuy;M0Jgu$^;(26PXjwUaK_Vze<0r#_$-jG29EM$4ZIOJ+F1;IG}ylm_&0z*0UYc3df;g1 zPr%X6K3@{a73n<-><;<@ht;+!hpnNpeDwo$3F9 zvitK^>w#mr{2n-#%e%m_Tt1bYT>8qT-%ehBV!7-C9Lwd)z%d_= z29EhqBRTuUav2RA%jHC{gXPi$9P4unaLk8!z%d_|NUrkXSXn>61M-*;Hvz|dxC=Pu z!vnxEA0CxFm=8Y#j`{FB*ui{w8+Z*FQ|+#Qf3F-do*sjjXnz)P zv_Bg-+Mf#??dO1F{a*?E0%+GS0LT7(Bk&~T&j-MXBidHjw9EAD8tlXW&b~4#s&6aE$Xtu!C{l4jkkBG1$R4KLL(@_uhqqrVr=O zwU7@7O3wK+2lC-C;3?q4!4CRu0FHi70*>iD8SGnc&T~C= zA5VcD^jiRqelG|9Ao#r&?4JYnZw0;>_z%Di`h5;K`h6St!{GOCVEdzVOM$-%b}*hzAkXonWjvpPJjS!no}7D5K3@d(50acv2pe zSHTX(a~#NXJb4+Llkw~}fc~Hl_g5It!N9)*=^Y9DQL>@>jju~iqLIgd zPXc}!*l7Yg80T3a&v7o5aV`LPjPq*XPl4a%VCQo1`+eZNmZjqV5!k_a)_^?6bE%By zMUcmM{s#ORi07YR=SuLq75G)aciM}b(TB?gj;|&kV40 zHTXRP_%*2jcMzDkN{2$13JS${8 zk-g~;`ULCwLBL;ucm_*OE+f~0-=l$F4}1jJ!Fa}kJje5W8P6FYkNJ}Z{zr(X0CsKw zzvlv94tyEd!Fa9#j(%4I|26o15bXa3_!Gcy1i$OR4*Go=#p z!FVnPd5-5H8P7_P$9R4U{C$Y$X|QuE`298T+kn3Yb}*hzz|rr2fWHlXw;M=7(}zq) z-T}TV@Ri_qKgomr+p)mW?}@;_2X>}O{uT0jJMdYOb3AtdZv{J;-aK$zFFF@Et`}Vf z9OZ8Sj`DW_NBR4Kqx@RnDF18VDE|gZBGl>Z1g%6|?V<@eZ^GLk-AUMPPcaFibg z9OY|)qx?AFC_fcA%AW}wq zj`9})NBL`kqx@~aQU1rkQT|cjD8CLk%D)U8<^Kd6<^K*G<+lPy`JMLHm+yYSQGPIR zv|kMz<-Z0T>%b1?|Hr`5{w@bQ@pApga^D*`_CJRJ$NFCl9PN(< zj&@E5j`D55(S8azwy$e|V|m>K{HKsVj{|=U_=~_F2mXfSgd&Z=cNyg68~QyIIM%CU zfn&QKEjiogc^1#v_;Vu2W4k^T_>&M%3vkTO3~(&pF3H*5Q()&?z}Eu56zpKVx*j;@ z!>z!d20PCH$2flr9OHZoIM$zcfnz;+4>;D7frp4}4fQjFfd35Q90~kc;4Q#0yq|Yy^(==a0a#{v7jVCqKBK z{0Q!YUjvTiH4*qr5dZ1GG5@oYlc>o5L2{qp;sF1$|JDGXAo*Qj=QZ&A6W~}bPXot%TPHdD#d3KGIF`#Fzz&v6zrkdHKEd(r zzQD0us(@p;91a}IWgc)Wmvex>4*BpjaPDK&^NtO`G5_BNj^*_q;5bj&d5Du<&NsfF z7G=2%l$`V74e)yyaNN)KRp3}IUo-G=l5bD;abMpQ;4O4frS~++IUX#pcHo$w=K;rj zxE46(!|jr9Pv$uvZjt$LPk{ea@&~}q?@39;`804GZ~O*0=Fjg8e3RtcQ!F^%co+Cu zx~TkqEO{`0J_nBZuh(4VEXy*_E9}XPt zOazX0P6m$s(y73)U%D1JwxfFt{1M=|Px4jZ`%$5(`nehSM&R2YF0w)71IAMi9OH=r ze-rG?29EMY;8_1J1dj8IYb59T#{EFQeolP1fc&oDcQtUV=WBptxjYLT$L+tCoc&@w ze-${^^G#p}>-oFDF}y$I=^ZB1J21eHmi*uVA0_!=lJlQ$LH^VL$NR}&;&_WKX>;v5I^hXBWPO#}WHkUsl>23Q?-_rToeSkYHhu<# z`~>Nj&z>M3FZrebSNmpouMWyjmhzhee7fXY0=!9b-fM(*PLrJ1=#YOy@=pRhF8S5~ zSNn2A29P0@4;@mT>j2uHD|!C_&q~g94CM=w4+!uDk`D~X8F6`BA|i*YqMcq2^73)9;5cr_c6}AdSA*YcfUEY-$@nh# zEk~aBuBtf8k-rh-F}=t!y}TDyZ6HtNPFN9OL<#tcP6R)_^?L2ju0{2i!kzst+TiUykPy@~i6A@et3G z5KlSsPg~0KJ<+DU{L)hXIgrQvL|#sQ;=W~5eqww175P>9iS3K;-MaLeu)`#hFV={4Cu4C>okATNivqMzrnhc17xy2duaGW(xSzy$@O?hWXMjAezkLHZ&QoRs$9am}#v=S;xv2h`^`Q+o)(33YdqDii zF;3+FB%7+9VEsYfSM_JL%-{b%)*s9ttUr50{$u??d8|Lk|G!XwFrFHy|Nnw|GS0wf z0pAz$p&dB(GhM*3pIIt7nGpTV+w$)#K_2^=TY+OggZB|^k9Z%!_V|Rf!+x=!`6Y1d zXI=uo*w6e8IM#<_p#5SzV}WBljli*gzd4V z5ah8x;WZ6qAN`u-`JHk~UTz~2FV;ph+<+UA^-VqT0aNy{d*Itx7<}I|^|ImoMVx2PUFc>O>($ZrQ+&A(V4$AJ%k{PrNP z=1nZW1Mp1-`F{gP`8}wP@rUi8{b9f(VE=gFcz>J(9Lw=c;HGl?64*aXMB~J>BXI1` zcLI*`{ehe0M}vJV$7bL=gB=_fVLo8H#&WzA>|i;nada@Be+KfqfZsQOW4U|)d{>a) z74jM5tOAbZbu@4+FPs-+d3_c9V!n+7z8l1Y`HAt&26@akY!{es*l%Dy+z)nk2fx1t zj(#@*$9%wXAm+p8AdmT=#y?z+dw^fOUts>61a|fWdF($i&N(2D`LhH#=Fj(mWBy?O ziS2!ZLH=Ff7!T$H=G!iY`g167%(n)xkNJboa|b~FBtRbH=>(4XgZCZGpSwXG^XEz6 zdx76qfusC;z%ibFkY3E6J%MArIt)1G58jVV`Lj2~`9m~RII z$9y{iIOf}Nz%kzr0KWqve})6!2lyD^IM1CXIo-lJOn1M;DZqE8-&5T1=`&mW>)faI z1^Zda*$&HJAmtZ<{C*&R3Gn@aUk4oX=X(aeN^wEV6Z<1%L;f5Ceh-Cw!2XTTqN#d<^$O=-CxV?SkUs^8E^M)jx25&i9vVMMn{dV0$?l|lAJ{o@Vxk)wU&Ci^wu_v>IE%NOH03gj{W zaUL`P$`Si*ls^^h>>p;ZkNJl6ZLC4Q z96S4fUy~h-pZ9jEdRtDpV4UTY3(8~uATKBXv3$$P2b4GELlxvR_DlF&V?2~E`sFj$ zD&O!v7z2)WCIZKG4{R6MkD;ALi1S3SgZDMGv!|4&qK!0?{BH7Z%>R?X4wgIaBb@+# zr-J-x!1+6dR6euhzG44><&O0>0e0{?V;k@)h_f9y-q$*So9aK-bBqVa zCuf5ljDIe0j3*5o+i558X%K$~_*uZSz_EYE_K4+z@%NW@xEkfjj`|Fczc4QVSM`T^ z5qK5IcL7)B!t(Qht8qB<1;8<$Zs2HtA#k)m7C72Rd9;5US33E@^xg^_)4K@lS4lmN z{~X}^NX{m3U!ofKa(n*^DXD%>*=Npv703F9<%sd~`)}0;<6i+>+2=UVg*dCEVyXCX zA7(l6vtOI|Z-zKA{+obf{NJ*SANQS>6F>X4iGL-;iSfU~nJPaR|NjB6lGlUzkLA1E zVE+c-X#af6{Mkg#Rey{5^9FI156V8*Pxh;LIrZ~;h!gYYI^fDa=fj1T@#8*ljDNi$ ze)ek<|FsY&#{XU582?3<@ozBXzbSt9YZL#C5GTgZ`}Wlb<9{A_l@wrv{TtTLxd!`Z z14sK8Tjmd*YryhdK|!f}Q1-cgvR}o^sh`(CoR~jX16TGrA1<+s|5;MfwXdHV;%C1$ z@m~dTV*FPE$N0Zv89$y|!TdMH&wg#J@n3Ek|C5&a&wg#m6rMQ6GQ%(+86t^$)Cj#C+5#Nz%l--E#rT{GJf`J z6aONJ6XRb99OM74W&HPA#?O9j;$Hx9V*K-gWBk`y#=qJS|INfzoXS4;&+J$6a{A{k zh!f*40$29QW#k6S_j_9=YV7UH(SPk zyJh_B*Czff#EJ1|fMfi(SjNB7GJf`J6Mr|viSge;e$@x#zZH0u6kue!zjPYxr-7sW z+br`3&wbT>Vx+023{ovO4;9F$e$O0qx~OP z+FuKHF#e~2qx~OR+Ft{9(EcO9(f*Gt?OzIZ(EcUB(f+*#`=VxtB4!Fs_ z(qqwwDZMIg>^B~Pd{Ea}9@k^bvGb_G&QF1(oyQFEJZ_LT#s37zWBgA7N53XJPk}tz z!F9iK?5wSjou?~g=NW^YJD|Rmldhi`>|nbn$Ii0`JGg#Tj-8)Z$j&bec5L(Kmld+J z&R_@EAIiy}UscG?a}~1lYl9uzd|qE6JHM%ro#!iL=LLfuoEMZ+?i(s(=fw)yd8tBn zUapXxR}6M+>*1>vvh!Mn?EKbX=XK!a)SushJl+R!{9lfpHw<=u54;>Z8$ll9`2+BB z?7Ru`Xy+~9<=EK-^4ntPj|Mw9jx8siKUK)ipDSeNZG#=#_VpKo9ULc@lRxhm?ED{a ze2#w?aouyA_lT?cz8Z(~Iw#M66*sMOqWwDz_WuEP&_2)KZS1cy*#D=&KF_ah?B8Rs z|B=By&#!IlKV-0PT8H8JosInm4E8@Z#Lx3n8~gWJ+UNPTjr|{6+UNBF8~dvb_D$u> z>l-%qao-oN6HYSZKkrBC$-ZyD6UgJfudTq3mmLSU->JZHKQr!sn+@_9Pa1d=*y#q| z4E!?S{UG1ed#(sY{s;1yKj%X~a2(kAFUXGr{uyxWPd+zr-khlNS(*{Ya<(I`?sK?q zusvs<{3!dpZmy=0=_!~`56Oz4+ZJxY~X6IBVS$uT$L^JmB9C6AU|t?@2w#H+yq?RdZS|S^~UE%JPquzy||g3w#LhO~4NWt|~XjKNNVCtn|#) z9$mgX2Ds{Tn9l}&Bm?VInHB1z6$uUz{dbr zdt&+WY~X6oJo6>Ms~O18O5jli>E~MDYL7Hu-UPe>emU?a;H!YEF$`Z`2V9+bWWE{rsSM<&|IW@YoGx{C zgUK-9vm6oe?<@D;t_kpV$zKof+a>=aaE||78Gl4hmiW)KV_N)M1-ujZ7~mP; zvw>%UF9Dtdz7qI6;A?^Bf&U6P$ItKVQa=;8z3ZIQNkEm-~P(1o;iX7Xg1C_&LA_$jK_FYccR@;O7D#1)SqKM8-1<_<10o z0M7FKZV3J?0sbuqiGNoDUjlqB@biKH3OL(8PTJoL`~r~w065F@SzrDPkdt%HhYJO9 z{y7jh%d7i-1MsCFKMVLpz!SjPPKU||;1`4ZCBRu;oncr7d>P2!51i$1l=e3OzXasp z2YxB=0dg^d^Wi(dtASqzd=zl@%WLlZnFaiE2Z?{XfnNc9Iq)liuK|7)@TY;Z-?h^3 zCg4|td_*p$aJsGmUIqNSz$XB|7I+)*>wqr>em(Hjz;6J)9{6(LTY%pPd^b5B;rMR? zehl!NflmRx0(ctuEx<1Wek<_Rz;6S-9{5V&9|8X!@PP+7e{lTY2VMvKcHqsx?*Lu| zekbs2f!_su4e+~xZv?&y_*URQ06tWX?>PQ@fKLGaL*Q+|R|8)P{71l70sk@Zb-?ch zz8Uy^!22KM{K0YF4}2K#2Y^ok{vhx4ERrguLAxs@O8i+0lpdd8sPoqc$VXT z6!>1ixxH_e?Y$cKPeFbL@W+7XfIklWD&S85zYqA6z&8MY3i$7UbDaIY0{H8|e+m2(;Ol@NAjkC_|F3{I0Dlhn zEa1NeuI3qRXFc#0ApaZSj{|=m_(tF_0N)CH1Mop|p22=!1U?%0OTf z{^0ok3Vby1cY&V?{BOV)1K$FC1@ONEe;oKffNuo;9`LQe-v>Tui1P=>{{isP!2b#S zOyC~^Ukv;s;46TC4E%B6{{p@d_`iW~1^x-}L5DeiY)?Nv1wI-$UpxIM=VA;v_s_e@ z{<#hKXJBV3@XvwY0X(vuci~y!+W~(Y`1Zj24Rv%mM)fXJCPRU%ckD2q0Q^f}rw#ay zz?TBw3HTkr)pygd{bzyi4DxRSSMO?O`F@A2^DOYafWHlVZ{U9i&h??HA6uvU_7TocE|+~kei-n9z$XFU7x*0D z`vG4De1G7pfFA&S9qUVgL_cVu{BVP`SXLO+Xn=jR;tTRxdi3@;|Ti;>}N ziDDu$yrocx2rxW;#t+5g5WTvAyCpKepYruF|wyrgsTNs3ww=d<|k+xQyFkZDcDk@0vdyNlMeBnqk4IAwn-)6v)(PGD1lawHaOYKWU+uH)p! zlijV!Trri+^nr`o>Qttf?8v8z3*)WX3iJ(Ggvl)V!`_-#V!m&9+Z{)KDFtpGc?L z;;mizLN-rLGEq$SL1U^Jp&S+Fr5!JwNoq~poA!ab=qTk*rmL^~)D#wGiivKg@7%_O zqyqiE)9?B`m^y%{U&_?nsoJ(B+f$h&m3KDX)!7%_X0*X`(%zM6?W3+TTJO1`yLq}V zYEey1DpTlcZ%?(RxUS~%srjjNvf~SIMcs0?E8m(dY-5$u)u=$KTvw*LWt2D6vQcfR z!rXW}_4a)be6%*(Rg7obEw44I^; z{w7m8QG?Z*>S8tIHEJxje#ALLAp>&Y$Ve0D+a%U2DYc}_#~lcr*AXDZX!NyG5wcvB7k z=dS@x#kxXjQL>Rn;v;cvPJ@r+0^I;T7MsxAnrxh9`W^y}4`?<++bWxe(ZYdos^+$Y3$)-S%c?59kRio7vQ8x@atWV)PX8UK1zjabHN zZK@5{I^qx+;}dVPPHzK)lhdH zUXP;GR_jd}qyw&d(|2uikiBuLOOCkljBs);I!j%2OTja<)WUF55z| zw)S~miqTcms9>!N7J9Gp)3H5LV>^&6FAqx>ykjubF$aV7%*7lH{f%7~iX&1Tj1o&; z(<+=nPVSR~9A<;aVDEW|BP4(EH-+CP#eDi&OO`!fZ`ctd`2w9ZylM zOcb;ET#mV&n0$kZDMxBXsbtSj<_pPS@+r#c z9Hqf(ED*F)Lb3pBlbJTo5_&4(jy;_x61=Q6u3jvvH%9AX-AP(Yrv>;zGd-?|1#G%w zE38PS@pAAk;}5T?SfA|76&E)4suj932git-I$%%ZIw=3n<_-V+W>t-|n2|^W!6}JT zyL&8VS)qF2S3J`Q)qVS+aI_{qHl5D4#^q=;x|qwfIo@0yZ;r-e z)Zm)x8}@7(?0nOt5ZF}QW++)nFnFXd?t~usTNDpa#9q}Qsc^ZWg63+v6wkf z^AjbJgh0@KhtZL(ow;~No*rZ+^YP@ou0*=AGaZYy=v3{?W_(Q}4XHQ>TdAUi23LVt z>Nu8kvQUtLaIy`7MC;rERx7Pi6dOz5xisBa$-7n~je=)PoIitp#O71@`rNP#!nuR+ z%}^CSx6)qTi)%ZQ#Zcq%=jRCOqFWQi#*--bQ_t3d4xmP&7erBO#CS*CKMIu~bm zVJE%J^}51>L@qW{%p9=?=Y$4K_9pVul~_3sjTX(tPGOa~!bNqXRKz3V@*y=prydt~ z>Vq!_%t3^2)!SYNMc>=!Ij(JF+-PZ5=*`LEiB@`cQE2SdL;sRRKBc8P#{b9K!kaM6 z`Mu5Uyv%a-=KkB-v6SghbYk1ogM}T9Oclhl`o*>I2NoS6mr=TP<;VsN5@|J#9`_`B7%S2)vZ*v$Nhe8^M_9qC#p6O)c8Zlz zZ7RA3Q|8#zI@$G<>_l4|57a2TXvdwGc4wUD_El5|C^I|qiL|N%snCLTa1lmSJ>Md~ z9GBM6xU`1HrJWOUJ@%5cd5=~HXr@Ayuv1nCR+>pqutJ&aukC(S>c;0QMcp8@&xaPl zG3pem)3gArscu-;>_^nxiPD&r@(Pyas3nd{W_TY-Jk{PftB`Lhj)=z-nYMW2N#a-D z!N!kA>*H~{KNh=kB$-al6=U}pHN7ZNF{&44eDy5P@oNJ>_=RR z#p-GMRTs4?IRThS3Qd!|nFaSRb`!giRB7dy941!oZGe}`>^EYT(W1u&`Zh0{d*!gt z3S_*wKE;pkgm~no?78noE$iTvj9~llzpXcj(BHO>qbI;ByH2-UB)zXQIi;I zbLHH3>E>7JZmY|OUUZ^gfRDhyL1hm-v!zY=a)L)sS;Z=ABaLHYEwrKsw_2XhyTe*q zGD~*QZoASW-jN}B?(lfX>y8)sIKnm!pXo+Bf(|RR(R|8TV(@|#BVCnV>bI;%dpyW( z>Z8W>o4gOZX9A+g#h#Vdy_a^*$LGmCSm zco(FKb9hutPxi#@9LF}9Vj(|`*6VmEGbceS%Z2u$GYg>AeTpzJA`$f>m>DC)Esr1T zsqwBetFIl2w>;VzO?!>=;^s&H@DU0g7iBYCG4#(Iy%BXZnd$0O)*;^wmy#BctkAR%cUg6Kqhek6PW>c<_1m7gYHvyV?5; z?bfOY8!?+ zzvDYq6WshD)(#9Oa5Q&~lH%U+tzhDUA^DCJ^$?Ozw&#%i;ys1royrpDsI;L3WK1Ch z#maXrj+`mihOE;bfm1qau;i4ER@4-={%jpgyY%q{jv{IU3CNft2#WQTZ{870tyk}| z$stJexb#*g+qg_8kz$sPxi3#S;y_%t9MVNXisNSg^+csCxQe*`bdhBxVdD zEZI{Gh8L7*12M>&qA`j06q4@MEZTTVfVJOxhp}vZh!};ys1rd%ctj#E^Fl^pt>)&(Jdh zwbj1|4c;ZFG|Cu6M(Yy!jxO=)nR29~U4?{tGgc3Q)Tt8-&g&C;kRC}(A#F6hnoEzI zinK={*;ZPira>Ho5P`R5X?Y;Y&rxXMd~SvgarK}ZEhO_Pddtru@!qPqe8EKzO4YQV zAyY_*=QZ(sHl1!sw9YN9Lt7Stuf8a)px&inkScoxsJwL*nk$Nzr16Bd>5G`qHac@Y zd4k#JK6r&+Ko@8eocc2NfcQ*XsTutCVjAwt+Ft1EA_>l!L(_QAX^*1i*!NAGxl)?# zheXZx1G8eCU5!XN_S`Nk7^i2?6*1e>&wq7cnkCKF19MxQS&fLm)HFHU=S%X{&%c1$9)~;5ngw@a# zGMKmiSEI4d64rFHL2Z~OL9^{r(>a}sp5#k-(oWH|K8%uP>!GQa&ahUfgw4=gN^4Xr zWwvUV6X{Hs5H;J^O>=a{O>(6yho>!i%X&Gp<#OgW!4_1Gj@e^0Fon^kLnC9hXqbrT z43`i!+Ye1xf*BGLC}GPmqY0Tb$d$0Ho%w|9YNbk8)y$7VHZ?LOEC%OLA#*{261Fsx ztdKd4ObLtniCD;}Ud(K_=lNRDMb8=~yqRZsAvb2x684Rg!H{{Qq}jS*+88u#5Hs7w z*=5ieTyx&4apI}Y48s1s8jfBx)X+@pC>lv`3B|ukr0EolR&}x_yMYF5v>B8$*~1oW zH0BdBSfUArX4S!D(jaZJt*`k;;|6h)^^yxTMkl4U48Ee_-pJ%YCu*`9=s1lggK}Ye zm0euX1X5uKeVqbvfRZ-8=d#WL%HZyf3T~}%T$#7ASJG9TbKZoOFvVtE-n$FmlptqX zszC#-(-D5@Cr*={CmUD#I=fPT4=Ra`f*ykX8jV+`ysbV~l z&nFhjs_ABnv(IV5X|y)bKAhf&*xencO;&|0y?=Fl^WuACI2{B{4nJ|) zDaX=+eCu5KH@!n~crKqMrJ^#PoD*-))9bnDC4Bj8S5AHjN$-CwY>Pzp(x{J-tiSv@ zh`z6734I@m{Mr`xr%8X3)Y}d8&$rNT*7(2BLjO#S|D_iCb2R!FTj&=x`j=SfFOm8K zLcc-k zWBohILVt?J|5q&ZXKD10w$N|W=yRTw+kfXY`o~)6FV^S}x6ofE^)dgyYN5YEG6N7WyAaeN6ud3;q85C2N89Khi>f zphlnDbh-7vN~1r@LjM@4kK?BgEcEL%{{LyAKStyKLks;$8vk6T<>p_rM*m+H`m?3} z0H+#6c>MEk3;mqN|Bl4UjeoJm|4tVAmudWSoi5k^a*h6;7W#K+^aohz-zW7k|M#-c zU#s!IkA?nvjel;_<>uc;jsAWX`dg$vw%`3N^gojN*#BN+QGX*lI29lDkF(IdC zUrwX{9}EABHTpYS_+O^cpK9U%T8;j`7XDXi^ru<)U#-!fZlS+Mqd&t!|5>Sz{l{q* z>0ht$|CWXR>l*(PEc7>N{GV)*{w*5)vn>37qS23A==b|lc>KKDLVtip|0fpugQPx| z|6>;VLpA;%x6rTF=>Nt-f3!ybWefdD8vWNS^qV#M`_MgIRtxv1ssEm>(f^%=|FlN` z4GaBljsEW~^p|S%c}`ny`mfUHziXktLh57vecwX=4vqhPEz0jcjsAWX`j2bk|Ii}- zXEpwhwD7+{qyKLU{~I;>pIYc|)};Tx7W(gN{Li%L|F>%NKeO=Pe@CbP#`<@hMg9+v z`Z#|6+`|7LjsEr){)cJwcd*c})95!@GG-vd}+Mqkp`G zew!x#{ucT?C0{3|v3F$?`wn)pw%i2ost zKJRHMH~-ga^ruZKf@yaPc;5#TKJF1z%l-B zSorU+(Ld8de}L4-{_Av$_y=k9ziHurm`49h3;%VR^ncSrf3(K`Sr+k6(&)!6^qV#D zr!C??Q{$hXX_njm=V<)5Tj=LB{yQx67i;uqTjbv|P5cQ9{i}5TE#hCH(QmZSU!~E1 z&m#VZq(0t1TP*a~Y5Z@o(0@haztuv2v&R2lE%ZOq_~$*D<<|fHJBP>5f40ycsL|hK zp>ZE%Yzb#6QPE zf2GF%vljZRHU3i;`fD}*pSI9nuknAjh5jau|0gZNn* z{{X3v?LTdye~iZe0~Y!X8vmUZ`cpLi@3qjMrSYG!&`)dpueQ+d*7(m_=wGJs{{svC zl*)g3;it`|0^x@KhgLvSm^JzYq1Tn@0Z*i}80(qkor${$h>( zDhvH(8vT1L^sm+E^Pb9b`;V0x{U2NCuh!__XQ97FqyK<~{<9kWhb;6rX!L(?QU5k- z^k1{k->lKkTg3m7)R)sBaem_w3;nGc|GcNR-1^gBE*zo%M=kURNPS#?`l*HfAdUaW zE%b+K{C8XES8Mz~VWHok@qe4e^YaNB|4&)?pQ7=9i-rGL8vnefy4?CRTjT#`3;$`2 z|EDed7d8G@TKHe0@&Am4|79Bgd?u;f{JU1;|7RBdS7`iSZ{dHH#{aVx{_oTHzt+P4 z;~M`zxA6b0#{Z2L{x@j+|H8um>l*)aE&RW&@&8K;|64Tvud(p|iN-&li72=JMs^R6 zpRcm;znj#@`_Hc|{14RlzrwSs0{IAydf6>DKLmL0{Ec~z4_4S84oTYTfj(eJjPzo^ka$3lOZMt`w|{tAu$xfc5O zY4p#t(0^8=|1Ass*QLH(1`zAdT^9BCZH@kX3;p*s`U@=dw`%nNYoXs?zBmQbztuv2 zpw!3y<1-8WK^pzfE%b+K^ttmZxBojvlm7o%_;1ko-`>Li7>)lYE&NZ>`0r=ozggpd z2Mhh#8vi?5=+Dvk|3uS%tLQdGI3kamI5#c&wQvAR5ZTNK~m2L=?}-MM~|Uj*=A6`O6srlM8$7a zfxn~lH{0ZQli^3{*CM3f17eY8Vmke1=|9Rr$pEH=9r}|MCX^ zk4pdh1^hc!J$R8p{{^Z4bx&0M7SvxtR2Tn%&m75Wsn7BA{?B0i_tSNj4Cept$2*EK zsjq$n{ja7AI{#y&f6PDLKNlB2>%MmpR<&ISur{N zynj*YtGNC~^6WpD{-ee@h9*mU>Ici>=NHI8^`6D%1a=q_6Wo zTjQViPX+z+Gew>MJEZ@f>fhA{|5s`J^Zuit|K|<&-16C{~dSG zr+@ni<(2<-q_4~W_ci``{uK1zY4AU(O#gEX{;PJNjG+(Kf1W=D{qveI;ZXg%qD=ql znMSbv&CvMg`BTvU*D3RK{$DB6|0vR@{~|&EOEms@{uK0oyTSiKvf=mC{%@xjtPx`v_Z_@a`P~$&m@PAjC{^uI}59k-JfBgQ>VE(^l@V})@|8E%l zkJ0$QSmXah8h8^9)&H7_1nJY{{BZwuQsw>`8AtlM{Lg9pU!w8<1B3r>OaDFfzjqk? zuhjVej>i8B2LBI9|2_4;&l&u0(D=VxFdhBTI2s}jsK?&{uh_&|8ax=*&6@6e>m9w4kw^X|2pYkHbb|< z2lKy*^mXaKO5^`JjekDpr}MwZB*$e>{=Z}JzgFY_295v!8vHj)|2?(8e;NG0ukp|O z&q-W-)coUUIwzw`{{_;2Pwnpr(%0pGm7LJv{r_f-|8E%lKOp`0l>et1{Lj$%zeVGJ zjlusXW%_^6;D3q6|7{xo2hlkLUH*T)(J7~%%70(d*X93x8vozZ_&?6zKP~0e^-KStyKZjJx@4F3Nk z{Wmz(!2LJa|NYS5Kd14}=Z}KfcI@{~v1ncNzS5OaDF9 ze?F(7^S?pk|3@1CD-8bclKy+D|2G)?NBGMI=!5l-&%Xup|7QmOua%kqPa6DJYy97@ z@qaiypdcI?e+-%|!jJS+{#B%}%m3LL{|{>XUup2)Ql|e)4gRmv_~-MN!TkTo;Qwyv zKUn^pSNPd?cYXf7CiM?RVfsC&KY;Xg`L|ZaukO>le#qxfgYhQ~{y&ob_YL?D_8)f{ z^mm!!CVMA=|LdCgd95lK|8oZa!wmj|`S){!|MxZipV0W=hs0laefK>)$h)_#Zd;|491hHAnme{){|g@V`d-=Vw;@;r!$C@4@`zeF`iR z%)jJxp%w|&|DgX{q<*mc7fJnK{SWFdCw*Q1-M3pf|9+{7pPw_c&7l9~(*F=A8ScM9 z|Nl1lU#Ic^D~*4CPN?($)BlIPFM+SCDBC|t8XDGyJ?xjTm8~S{UJ%mK3pbFI(giBC z+^lT^X%do~5|&CJEjEN;1PWCa3(99zkSdEswy;;>fnEs`P13Y(+>V2 z<~QxzfvlF z>#aa~oBlTBNA>qhi~P?zYH-%>~VN>0DnB!@p-{^OC} zR{l*~{vu9K_4g}F`BM)57nuK$H2lpD{sQ_~6)to9c*Vm1xP$*a=07M6|HBUcA`Aa- zEd1{}_;;g?eO&3v|0f53!ovSs3;#kK&;uOl|0ghiy7E^cy{-N$E&RW;@IUI{pUeE? zgckfiB&&Hn=-}^Qe$)P5xA4Eu{NetioB7kVzvIzC+w^xWr!O^yg+JVWCLp~{e`_rI z`=dqv2ORt_F#l0$_3nCy{-HkE&PA7@Ygu_C(V@w zPgnl)9Q=b8{fk?z`P22E2O+)9{#RM}Kd|tZI`}VPer|?Z3t{~q@8Dl+;itK5xcuij_+McD zbmP}@NBZ|NOn;vv{a$CwBA={FZm<7)klv>M^;~|l{e5UD|Dc2a9Oh5g|7>>f4_Wk2 zN4moLKLiZ~aAf>m#{B8*??9xtl|O%XX(?v=qrof8Kg+@YE#^M+^6UN64G+XIB>5XZ`e*X`L{3?CA=l}N| z@~^hkA1z6TUp=2D!6}t7NbNcY}=d$@SQ9AigLVBD1t+U8aOEO{k z?{x6rks<$T2mb~OKRwci`Ty?V?`M8GpKM-XJx|`(-hN-@^y&JKaY%2|-zJOv^hh0+ zzuCdR-2y4~UZ(Kyhvi@ENWVX)PuKr^&mq4@AN$1x^A;Dif9ev$^5;Oow*K#U=I3QV z&PB%6H}HJq;4fhQ1V<)*g2Mds9sDbp|51|+{;>YeMtWQQRWkn?gMTjz|7r*SDd)+A z=Z5%6SLSuIgFlZx)`!dN{|YSpyY6q-|Lx2lo_~e;cS3qw`6n^IS^xW5_{$yqFEIa; zW?|u%rSid39sDzy-_-y97XDiu{9jEEbnHLuXEx5*)Y3(G%~6Hxzkghl>22ioiJ zohr$S<;lPm=D)|0-m8|$(v4r=MS5HP_tVGLahdjaltunMFu;&Z;rYi=%%5)mcofpx z_%|}YX@AF9_!l|&TQcOYcJSv>XN$|^A7kPFgMFF4KO;Tjc+hga35qr}s22j-yC2AKnf#M2{6BQ?uURDd6CuLTt#`MBe*+EHxJ>&!-on2h7APps zaQ`t_FOqxco&r~xe=nrBl|PRLYg}gif5F0E>fqm{LDJHmsdRI8`f1PHL|3L@;olQdh9v?%JH~1T_ zzxy2g^)%VTl@NdB`Hyl7|IUZo%Rk8cV>!KY!u%&X(jU?+Q;b&$*$tSIC^a6^``JaQYR2)Y10ah4eQ44YK?loSy9O zT#Nku4*nT!GGS>N{)Zg=_4KfX%hcZj3;(|y{MTm4|AB+Q)54#$@Q*vvUVkq*_+_bl zr5uO!HvO-%@K;&*A9V2Vl9C+h+FuqPFv+I23keqE^cVZ03SZd%K6J>xmgTSH^khG^ z7Wu#L;Qu=FPYm&g#PmLJr2kol<*z^5UjElJEPoBs+v+cWw3O5=f4!yr)3Ly1)BpT- zS@4;m@`v?*64KlFTbSSMzt6YuU+dt%i}`sN)>4G|yB++iE#+^t@aG?EFaN$vBxR{) zmYy*Gj!17Szjvh6zuA8@S@>HW{O4rIzu3WFVBv4E@W1BZ|2p$ePE-D0Irxj1->m;u z3;%&w;I!G_iy4-GAEdYGztU3vl!bqxgMW{UWWmGpcVrQ`svP_s7XBp`{`VaGCCoo3 zz$SHNLhm^E`Zdbu>FSR|CdAlRTlkSVUd4~ga1M1PuG7OiS#!6ST`&vFa@`wsq7c;d2`wjAjR>;KSVd;QJl^t+@2y>238t`e?~y)_;#h|Gf_W_nAN3e!}uk z9c!0=3`@*zlPIec{p%|%YQf0+vAmfA9o* z`JZQgY_A2bF#rBYZ{r`Z@ZV5lZP zIemQ^`Ad& z`O7#x9&Z9ys5|s>k=~}ib(Z?S%c8$N2Y(0iBRFs&i@??6;NM{3|GtHP*W>Nw{~_~Z zdK0+9<=+YEZROu&;a_Xv|C)pU56qv={&zmXF8>Fd9@B%s71m!K(%afTqZm(z#g4{&T#M-Fuyr}y5GY8n1g=>^DFt47~%4t^aZ>AR&)9~m5|+V z`YA|n(_baaU&-l6f9ovruXFI{cFKh5>c8kjyZi;59@CS+6_)>Kq_@f6Z>j%>Eb{-* z!C%h&;rV-*|858WMhpKV7XEh~{Fg9)c>WaTKLP_RwdtHtKp&?^_a3GGRLYUI%|C9X7&MDgMg+*C#CeuR8d>D`djaoL)KM^1tlh zAF%L0W#Qko)Na3{nLnNV?1c0-{g)QY@|*LoXDs}s4*s*4Ki%`k@eckL3;%ixe>3xk z?Qcbf`aj>nznb|gJ$aG+{nWz$Eu_yvl<@P%+6?vo4Wzf}-=o83xJ>;&Z{dFt>23V4 zF@HM!zku{M{vr$i3l{$DsrL4teg@z{<9qX3zxh;P15XZ?y2g#{A*>-^Bds>i<^`{sHDU+uyG({5wsvx4*r*q~g-m z|45{_*mok5)kV4k~YZm@R%pcZ&3-hPbf3<^u zwWa(67XE7;{I_MO|858W1`Gf1E&TU0e^~z;GSvTC2fs&$b#YaSzf%8yu<-we`NR4j z%259s9sHHdZ`$7(X4Ec}}+{0E(f$AL(uFuiv8o zKUw(CcJOy*$Un=$ADaL&T$SRltpB$y{JqQ{uKzX6pRWC_aPW6Bzgho(w(vjV;D3qv z)7Aev2me|N|Dc8c9p(?Wzr5vAap~%RlY@W2qW||S{QFP0_y0xApHBaKBmD@7T8g~Q ztCSAQ<1+RCzJ)*T;6IP~)9Js|!QW!x|G>iE#Qb6X_hqR61_%FY=C2f5koG@h;a}}2 z|GEtIf3t(%n-tamKP~*vJNW;Yq5hwB@E2M5KeX@(d=1nEaW)Uf^cTgva{M9)9Wa_~1Xe>(fGaPSXW__Hnimoa}>|En|9 z|3wb|7`?25t5W=x_CLbHzsAA8K12R*I`}&+{PeAkJeEhT3%8!9T$K zX8)IG;m!T(i;$e{{{o~<`3(CV}|SMr)Bg6b@K1K|k753F_CL0e_sp#V-EfYGSvT%9sDyb{QFz@H!*)$ z|C=(@|LYF^PUbi5|3C|WLBekT`Q4e>|L#a{v;P50`C}ITX%7AqnLnNVf5E|@PcKX2 zGTUFFg};&c!}@Pw{?Sqm`fr~0NzWn&e<|}w(xIZ{;>XsGSvS+9sJ&j(f`)eCPV!{;NXwZ%gVS+{g+ty-*oW5l%f8A@8F+l;U8z=-~BXce_{RS^+*M$)Bi3= zZ?nHn=C735i2aud7XC9G{6!h^mpk|eEc}x!{FgI-xc{5S{OQ`?B@X^lejqjLe~N|w z+YbJ#m_J?nyTifXV&Ol*!v83P#Y+7{uO<4Hfb?~ptkpE8({!R=3X%_wi z%I)<(kRg8o(%bBBz`|c{;ZHdD^LnM>q_e-19sH#yNA*9$!oS49Uz8#Lg%1AJ7XFzQ z{%}{fUvuzRTKMN!_zNoR_O~WO{@sz@W`F$_{sQ!k;rk)_=BCm&(>FW&SfXB0aIteGR7%k6(Qm%6}fx+w5obDN-O) z{-j0zE15qm{~G4sB_wZN=>B$2AC`X|r_T??52wEc>2312u>9uyquL_>Z7UWA3pyYmj9caKCJ%^PM=Qx z+mPNS|0aw4^sQ}Ge=6S>nLjLlAM+m+(s$S%a%S4~zcxepKXS-lbZXT8FR;izmifc- zZ^%&o8i)LY8Onbi(%bakVUfSdB7cuV{`@|v_`TEU|6YguqdC2*XO)ere|7(Tq_@f6 zZ;}5(i~O%Je^~#e%%4vFoHOnAGcQB=KXS;Qmx$U=$|8RW^M~bcVg3V^qS(z3-B&r} z@5@mB`ABcm|4fVg7g^-*cF4b$`P1qD2M+nyXDI(&4*6GE%pdN52AF^UH1an%0FU?T?A3NkvoEEkJYb^5r(II~&^Y4{L{+;L8?WZF{`SXz8WGnBv9A^%2;{MT9Jzs({40P`Ojl0O!@f6*a--t{tKI{T;ZY}xc5 zJ3VSYD=qS8&vo?w%%5)lP|WEg{eOn?AA|HZ`Rgt6ud>L0u0#Gx=1|5}IqtC>Gt|MQAN{{9T*f5{>LkVXF6Eb{Momfd~^m_Oa~*YTV_Y(L%& znc4pYq_^2mX?fKCZ@0)_?~p&n{OQK8l@9q!GnBv2A^!@C{NJ+3|Aa&S$_(Xy*CBsr zhVuW(A^!%8{NJ|7Kl*ID{j6sG(V_k_7P_zE^kMs1pP~Hok=|xM1r<^I`L0F&s~z$W zIQYZ!w|gD(4>{6Do_`(kS6bx1+amw#4*By}N=2t@zq`+~&mW37eY){$7o@l8e~m@{ zwHEm&Gkwg|}$iF&6`R{Yc zKWRqP{vWW&{|ATs{mh?k{2KK|yZsDgDE|&fZ?m6Hi~J8-3{A(QY=bsU^pT{inzvPg=(!n2Y zzgrygcR13A_5V+Y{PQgGKVgyo=yUAjS0D55mq!0*bNcZ3wKhZfXCb}K{#RS%f7&Ad zwGR0QnE&vQ{ISse(+>IbZjuqh?I*1Neuw;8J%4pMi4w77KjpK$Pxo)xwK-&y!u9sHA+Kb`$AcJR-$@V{>1 zzsbR0pJDm0bMUXQ@V{ZuKz#J!C!CT|A&SDDF=UJhUI_E!N1DF z|1S&wVU_m!zlHh7%4*Pm!}G5g(%b5PJ@XfEO4|SYw}rnC>234R4b0EmSWf;P2mb)` zuQB+ySor_t;IF<#COm`FD<@q350Ktg{uOg&OazOI%AbY*YW}VCa#5AN{6A#=13A5N z!u+jBZ{y#@{ECP8b1eL?JNP$b$p4yy-#bf6YVzk=_{*#9<^MDD@1_dQZdT}isUy92 ztBjZ~{bP>wyJeXEUz|St{56`>$3pU|`d9D=NN=mZ0@h!GBU1hCVA0vTmcQSvt|Br>r^O!^awHeC) zV~6~G7Wwln@((!V?|1Nr^_f-cdAp!YIiYfG;PhdAt9#{ssN@f&@3*wS-7WI(27YQ& z;rid0hF{U`jP%Gh^7|qK0qm;wuiR5PeJGkY^0qJ{?^QY# zdN$IJ#7(vW*v;egu`nLGZ)W~*`q7F%Q~*_PDx33>egtkx6~OKw>u=y72~hjr7yngy z)vr={!rYW%^wTokno8*&fV7>698SMIg2T2)DK;D?HMKMM!!j3XE6PtU^)J@+OQckt zwPx&S`r{@~jG0%FaU=cm?}TyVL`dU+bzuU8aN4Pt&pT7M~ z-w(z=Zxp-vaCc?@ZtU(3cMtaO$?jh4?hUtq{rkY(7ytLe|NR*|0Pcb8KZxBJy9cvd z2=@^79}1VM7XQ4%@#hHkkA{0B{vXBnN5iFWZ{wdw-yj}?|Htut5!_<-m%ts%{&8@} zvws5IiTF?7pT<9LGP_gY9?$+0;C_MqC&E36{iSfHvVR)fli5F=UHT>~{&}b1&#CNB zz%64xee>gV_Lsx0VE+ubXRv=J+%wrf3+`<8&w)Fa{b#{F8~^9={TJb$!~S#O&d2`+ z_;0`@n;UCjO_xXtWuVfR9~t?X}u zn__=E+$HS42yO@aFNS*w`!9ui8U8Qj`!B)0oc*0}uVDX`aJ%q-8Q(95dlmkF8UI%> z*3IrUaC_O`2luP^e;xi`&)5y@u7rCd`)`7~iv3@M`*rr;%`|pPPefHl2cP;yW0QZONzZdR(?7yGg z2jKpQ{p;9$5blrJ{}9}V+5ZUKN7?@v+XZLlue_;O`aR12uH{ot#|66eX#Qx22-)8?iaR1EyciA0;`xo}V2lub+ zf1lmIvHJnLe`j}y-G8wAPq_bL|A*}U8}3K!-vXBgRC2P|rMWfT(;SK15pZ+aPx~f> zjbt~E-Rl5Gz#Yy0BjFy!ei}lLVgIpk$FTo6xJB$Q zhFik^v2e$+e>~g??5Ceqq@T7UozYLM(a&s=pMGwMesYKW^wTT!^Bd%+pJ6CvKfMw@ zjr}LHORtI2tBMqtUfCj-UcDigUO^z2j*`=HTJqDeLOL2oemWvU#~jE{+r8w{wjH^& zeLzdN|Y3X5&P@mHn9JExEHX$5$J{~_j0(M?7xEDE8%vre;K>W;aZa4d{X153KHSF(Y_gc7LVSgXH zUxj-e`>$vB2DmHPexAPO- zLy7LcB)Wf^=#CF2y5|lhdgFtS!oa;m_p_VG9rb`W>e2qLp@vio{*3wxEe>}LRi$?5 z8mdVZztuxgdvYmeqDP$gN%SloO!TxP-=8JApAdO0>rW-Agx==bOyW+U5!Kr~DU-N6 zucK#x%{%pN9?`cst8X1{yq`Sz*HH)llZrTX&g{e$Z}%g+ME4_;KH9P+(S3gr9EdUE zu+fN$Vs9$$AN7DJz_R{PH}vDrvim5cR~CxZu)KfNN)fgSVN)N*AMeo}qR|rF%Qpy` zl^eLnizGsvUSPUJYatspmtQ3XpUEZ>V%KDP3L9RV_6hKilAmtf3j{@AmU@R6eBD%(fuS! zc)BQoQt3)@+q-A{acv_NA>j>%#YP!R;r(}&!p~tJkkAPqI*N4 z`+pMM&ulvT!!297mzN_(*CX`TYi|!r9!L(oiE1YmYeRV^D5G0yx0pS*61%nprKjbh zmi$u7`q7~q%#yMFapdleiJrNeY7wF-sO-_J{USxe z#7)(ic#){yNcm+AU-1<6bLUQ-zrgSQ=E@F`BA^2-P}YH-9$H49zuXhh$~-t`pSUsF zCtgW;So_4(`P?5;_aBOa{&h8ml{JZ8IX3jtEo|^*wn~f91v$d`^(>dAP)cC8XC=Yi zSFVK!{`R5=Tb)RQ^Qo%oezao1U?uS-aj_1G~;Ao{8+9w8BF z4R6%7^Wh85Xl458J*%lhRk`V*t+X5fGAid=wAi^#LuUp9EKOVS ztPr%x^6r5|_pcLO|IA9|X@QmC-OCeDx6-M#%7i9aQmIvc+#xs}=@FpLwo*?5waD?U zGyV-Be3`_QHdK`yidBQc^y11~|A9xPtqAUvt5nOC1G!Wgg(=ATmcy}lNbrro2lezH zikAtb-g@gc@ic|<g7qyrFf4p%G98I$<3psh%?mKW8xUp5LZ%g)q<6g`KBA9YhZeA9^Ersi z5hyMvi^Qd>**qrE6(7nHxg8(h*!nfWycyj;q>@P?rCu+=Ov+GvOq2mrSUeaGDUqql z0C0ob*}RLUmRjwGv|UR#dF|Vg9GedWIqHU%FwwnZ(TwtY0?R0(H6oM4+NQ*k$(H7} z*yxMu8*1uf4Q;W*E@?k9b|T=mhD+)~I4O`8EY)>#b9-ZLtf@H_t7&ezIM$YGZD?9F zC05y@)-|O_$l38Zv6Ii3F?-Iesbw?f%#KYhFOQW~RK%y3O`Q|> zPClceqHKS##S2eL1l9t(&kR0V~9vAI3Axa#6qbzQ8gy0MNlTvK0Hb3yE)`l?i{ zzN)3AuBon;;1mJSMh%p~nm!UW&_Wr; zR0pA#)WsH7L6BO|&#AAARaezqP=}Z-eGJtD>R4M{D~t>A{SZ=9byZtK4QiE)RNBlG zGFxcO44E<|S&>A^5wE=_6>DmTkYwRYsu~+=&EAq4t>5gZl^q`+T7ubM1=`$P>O;}m zjKyrxuH`t0$bt4xeb`2NP7e)&$Y%rc!y|Vb-J9+_kTtp@>X|BN*w{%d7e4C?5AZ=py_Qi!nv?CkR*lKD%ONU?}lyX+GJX*^jGH z1-U*eY*WbL%pcs(mgZ4J?z@N!vTNP~k^b4z7{vh*Igv|ut#X*RjdIbaV4F;a^hzhh z|0oqx0fCx~s4${IQ41`$k~8>dnJNj*a+b?omejt&db;K8CNzTy-WoMPYn`$fFh`7% zJqu_=gE`58h30U^Eyf2d%BeMcJU2X*A6PrJJ@xwv5L{1n!i-jc3+~De45Ow|i^ZmR zXX5BMVqognvz%g(U9vnhKS9VU2(>CPIo>y__X_Ab_&7wXc|CIxrJ~Pl6}|EPMDN_y z{B#oz2|UE~YdWzq$dgH>!zZ-@l z+m)!THK?uCm_MzGR@G`$6@s4>uEDHj z{p~M_Kn$FiA;=9yJwq_r`~j=0KToxaz_@Q21D)Z+%|q#i9$;wxL6aMvQ_xfj(+y)p z(-WJ_VsDH5+`^pY`(GGNqkjQZ28Gh-k4dSXhrz4nT7bLyVGBGGQnarA(dPZLrSr%F zc>*gQp^>FtblF@&9hw{{B54D8`-^9oi(rEWbca^+5a{(WRuSp+_BpN!nV}#yUv-eH9zi zukR;%E3o8D!@EB}>c#G34=ohxT9PriMvNSoEI5riZ1aJlPUuvMLFOA08zo!QE^!!A zODG=?y`3;+Cr!;gQuuN)wnfkQ^H!$A<2?&nLRE zF^oNUI_?IU=B_ghLdrCtaz{oOc2LETuLnu7TfC)x)0XxDNU7uCslg${MpL8WiIRHz z(mcm=XjgwsWg3t^AJT(PtW*xFhg%*nXbhr3qw5LOkv2F~!?0>nuZGevlr}e21x6{U zr6rWIpTJmSOzHl@P4v!-!E)YI z%7S^kDVv!81Y-tM?p^(*Iy&9=&a6b1>x_v+AMUB&;a&AWGxVuk&2Yz_tXv$Z|FgXf z+V$!y0kxYStTR}GUT+zI649&UUN42f7Hp>$LixyDXjvmDYWrH$$ZBM^#x(hjbRuHG zy7Hd7)#W{laY~1JGu2n20&!BJtb0Rw_wUQQ-*P_1s9kojP;J7IIcz?`@5}sbeI=?; zBT2#!MNS+28sPz|>!}29t6(h6Pv&Cxb9q)SUhKFt>kwQ2r!9??gB;;-=?s6U-^v%- zH^M31qb)|aWY|2#rL`G)m(INCy+ZTa(Y%4*+Co`2WRJ5XSrtFX%6)L8*OQH&{hsXH zKaceOo}K&O+k4;0$-RGj@3%R*w{GvfG$QxgdETZGxnIfi?#SKagFJ6A_u${>dADts z`_nw{C)?!$d28fytYjm@{lA%&yKw}L7bC;(=j8q%*IPCs_oETsKSq2}gzs@00-AF- zX5kH*T)Y_b7qVxh+hYpcWG-GoxiKpjFXa4A*g1l3uFE>}IzV~e53+Ng%=4bh$$cv? z=Vv2wU)z4GWX>jz4aq=pV-m+aOBs~&G&CV^4aaZ zUu{3h^WNQIWap0FbvvfS>H4MFmx@E@tTTwP%h-K!?q^I-7GCs`LXluQ&c8kjFNR!A z1;XtP^De{dEbnrJ?Punu=rL3T?R0h4yIKFr_HM|b`WqI8XjNrV|oCrLevinP!Lcb9=M!t`KsG*09qS zKd$`=yLOK(Y*p?q2Hgv~d~|?;bKkn9bcg4i#1|N2N{vn*BYs7{*~QSPN}aB1co=?r zXrV;*8niMZH)${;%ZOOSIhwj5Ok{h-6c}0R;Yh5X(JHTzV-Gs2-ks3AMJX_l_|q}5 zAZ&Xu)a{SkuX#`9^B*1bGOhVs7TS!nlvikNKooXUKp@+MWs}jPs8JN9Zig0vQxrL~ zhMrK`(mWiaM5ipLgfy$caR8cE8^y0!Cl0yE2WaHz&zp?V&US`O&+o+OB@~OkQ&$6K z$-V`omw3T?=v31ugjUvx4LZom%Z^=3`@Phj!ZwttP{n3#*i7?VniGnxfB{U&$WD-( zE~h_f4zTz(7Z}{l;znC3)jce5In9>Yue9cuIH(NT73qe%vSC?$pehzc)P@t1EZppZ>qC)|I8bgiM-sIp=8jk)+7Qg42tCs#Fij zg2lwor&F*vePh7L|7hy&$(BrMhS%(oMdY+>0#$;XMSr^%%8ER(nB^m7i30g*iHH_Z zNcYE9)Mu}e(P~JKnvHLu!e0HyBQl2G3f!9uJAKfVj?xFc7z0nHk6EO@@B!!gaFyY} z_Zl4dUJZ(T7~d+mF}Ri`AJnuo;qu;!g7RL9ie$ZW@%V$MB&u3*hHz=$*(xG!4o2K((FKHkeA|cUU@hZ@j<`_XXfjx24H`uYKT|_!gWOT{_@>X;-Ll z0DGUC+5)GjEK4Lb4e9jROgCWvLf@R z$k9Zh7IpmQaWtgrY()PovlP=r8Tcem88w}}7j4X(D^x;>YfzpwSV74{NjE$jUrVRO z{7rm%B{FraP#}6atQK^~?;{2Dc->eBAWwcz{60E<7T?$n@4C(VbL0UL`Qe_q4+9t& z9QAm9_l7km4yJ&>#u4UI;{yheYJ(#Y$g%C?rs7Z^0^rDKLcz%}9u1J!=cX(XS@p z1zLI>gguEDNK*$R3JdqD7$c=j14^dNm|chn5C{?e&@=ZB0EPy$^85N|r9n@bEc309 zG-74Kh+iZc1=$1&0_|;{qhx_Q$e{3QGo)r_nkCQYV3Pa>mwf1o*fH94`yG7&dA3#F z@RM2B+vv~b=Fa9aNHw6XT(mCe)M#C1sOT!FU526zK?i8K=!n|alBkBJ^1(zUM-wW0fDZ!w&b@-#6T6LOK-OYz3D|S zx8$h;nB_CK$c`pW$)lK^=!u6e69+;s-@IRf4u)P%t&8BxM^dNQxp@RB#V@(saM$&s zXV%(&=ro0{D0u=0w!*`2)<7Z)tFuqV!Uu0YmNsejTc9ij^w7WRR0GlwcVJq9bRUZt z=_7WNK?~4k$0p}%*CLQn7&OHSm>JoqIaxNAW~QD!^(=E4c)eOupyvT&z69LVP`|pB z^|j8weHwIY{aZR`yT-qL7PqU_EsSavmaX&U(2^5hRh~6eo;6sWwW(ZHyIjhhdfwEe zQDjm=*U}*m<3JD%-ifA04e4mp9CZy)4x-OSBc=f)PxjeR6$X$%ov_k*y~kYRL5Q=z zHTE5YJpSq1Gn%q~3piY6RVq;YX&=|k@ZSLGto}fRgtRd{Z6zJ!^$djJ$)GHR-hB@G@mTQ zUK(Jraj(lIo+s(BfL~MrX;VOl+9OikV?-(MU3?F;-l;664C_Zdb?CGI_*fCfVV=J~ zS>F9#dH0|75^DDXTEam-Y-V_r4KC@^p$2;KIk-;;2nEUxh-I8UKy{ltadS3TkYdWZ zpEi!qmUnLsGb<_NaZmAk2U|JO&?OEKPF*ndJj05}4rD6~+FGC&fOJF8mgb2iV&UD1 zyy^M|qphnpX7n6pE7oI*Y=f{_sohYVSa1Ren}WTQrMnGY*;j}GWwtW-Ex-?VWHCrT zH|ME*L}QEeRHQeD7J5qaXaW2nijwF_P)7k*{I(r3wU0-p7AZZ;Xkid~Ow&SbW%X^q zR9^gzDG`f8VJ?Yn9z)e850KH}1QeEq38eI8L@ylK2@lR(xuuATLSsPX)6=tUCPGzd zP#X0U?R9|!+L64s+nlto@WO}Lt49V*JF#e7%V?) zC{P|{N10e;sC}DH6}E|ZsCPgWqc0=fbBT@8QOLUQ$}8LG{UW9IQ{#zjaMVrs*{XiD zQ@O0LZ(`kCdF4{*61mI83p=z>=8wK3ln|zlS-!3D%RWtw;mCz%Y{*%+kzj4hGN;w8 zKe`q{NoYvXT~9Hx`sYe87@~1v>r)yJ#>$s5RqV%)sXP{g;fpfk(WSimPvzYoly|== zm0+X@jc8*xA44{c5e-?W_;N(kB*wuMnO)aYMdBn14OqJ8QMC-{|E~Y9H849>GB!E8 z1+UMwH{mtQWJ{_w+0fL|SXEP3He+^bVlr9N(NSDnTw=a(S5`ASRa{(CU)7q#dy{zK zudF6My9$5ebAj8{J0sX6}G+Uks=doup`OXvkxcdotypvZ}) zYQyAt;BJ+IJ z<)<56X{1g2OjRv%CZd5bS<#-V>qutOH8}Ip0jHjP z@|4)kMm`ed;{T~L=F)FG^yBjw`a2eTaE4iz z%<{52^0W5aX=EP#rv3iF=|5fKyIApE@~_H1dFSoUM+9ILb^-PSK&-23{CLGsO^hbqfKcx9zB^=j@^hbra z`{_R<9GB?bRrqCo`2Mu0fa`Snqr$VN>HJUN@OgpoGj#ZT4nNKeU+Cw58HXQahM(n! z-@@S&%<#p2_`@7dKZK#>tMtQPN0mi31(8Q1 z;kYie=ToKf>EnD{I$O)(g_N1%`J%704OUKgXA|gTr06zbZ}ob!pOXluki#Xg?eyWE#Y*!z_AE}2yKc5cH2k*l8Jk5UiDh^MW;Zlv> zXkZUB&ztZEc*=Tnt{KsloBc~auRm~Jlg+$Z{O}R{GLy}=s7?;$@KI*^Q~dPPIsCU2 zK9$=*_OC?*N?*(2wmzM7wt{VP3knh_%V{*0<-9!tIZ>I{a=bS%rUl}a%QEL|$kv=2 znbS3P4{^Ay%p}wPY$y5Q@e1uJC!0nqIW|t`c=Q%gKqhK;?}=z)u2@gs4#0H={ZV$6 zEtN<*TEXEqdFX-aF6P+_ItcKnvfrLFCN_JFms8>E;8o7k)s{ZwaGNcYO#AaoY!&eP zGEdh!K7qp@4TRsX!{>9j%Wf{?@WajY3w)j3!r|wd;n}l9gcz`gIs7U!ob=w|=P|%> zjxpoZ$Z)D>W&2N(-;6`~$fAh)8%-y`aJk0Q1c#SWBvrpgzf;fQN1Nf*zMLyK+*KEA z(xhL{;m4c#xBB^S+DiU0q}hpWfyRY^9*nW!n4Kwe&lBHSRb?#mIm$WQRfa|mKbSI6 z>F4?Bui@}cGdx==F$U}|4!_t8r+T_T=0WxO3ogg8miCx)kl${V?eAubH^Ps1DBI8N z$UC4H;=SJIE$4Xjjj(XMobSl|s78lJVjDEYV>*TW1hH;XQI!uk@G1= zJe^O@Xc2+r7~=57CXX?HEf9@%EAu}NceU+#9DaEqfBEo5{2giXUzH~Rb!oyka`^cH z{wkqJQGO1$jY$+<|6MhYcyPi$%N|XM14tL4-cAD^=crkFASw6G}8Uo3N zj^XeF%oA^FPnwHu+;nGstaV z3jBdOzEI{taq`7t6uvnJzb*rfb;i7G9LI6l+8hpd)nh76`WrahW$X8GxXqTSo_@jM zHa$_lF~n`5BRqzler-8#&z7FI>anuC{U) zhl^q;Ta?=k;u-CE4sW7DsPJq#sS@Sqa98p1*aQ`TDFmN#;^Yb+W{lfGa-${61Pr$0)U z##lCq!(III(xmT5lYUj2^y@g>RaYC+q#xpN+gM5UQ$T-kT}OXZ`Lnx)f+=Vchc66- z%R!QY=5e^omOD7yW=j;bio;#@v5v!S<3bGSH*&Zzc_sf$X&(r7USw_~yuWO*Mac2~ zX@jws`fmsRkps78k9@L-K62%F*$zC%fsb(D+c|J?n%u&>gCqWq4t!?^KFWd9>SFZD z@n}^ddgXY#JMcXtICVu?-VRygI2+L)u|LP#I})Gf4-|hA$59dHGd?+lU&8p55Plou z$A@sb&GGh8*>b3Ka=iT<_yG?5AO~I;!5;+$mFom%4C+Djt^rx-CdWHGl8?kkJMg0% z_|XoWR;Qv@j(3~`FLK}|4t$&gpWwhJIq=C2e2N1ci=M|_)G^r%Yn~v;Ac7Tc@F%G4*XmPz954C9BQQY@_SZij-l2ZFByqX z!8u-)1Fv!5bq;)C1pgQE&%*e!nuu`4#9#R*$E%OTr;r@){0M$L5GvOjoL)ts8X^3T zAzbFusG@PGbaK2V2j1eq>9j%g%JJG9c)J6?$bnz%z%O;+OC9)^9C)V#ztVv(bKuJz z_?I1cw*$XAf;RxcF9T|vm$N*|nQ(Ql+;1`-<7!d(Q^2#0dCqS+d{j2&<_Kjgq4ao~?R@W&nalMei82mXu$U+=(w>cF3O;4e7v4G#Qg4*W$2{!0grpGUP^ zIo`_-{8tYA6$h?PSO!UQyw@D@2ORkC9r)`G{0#^GrUQS=fp2!;?>O*x9r&OFf6sxx z@4)}&z&~){e|O+R4*VYu{GSe7osbRJ@4p@Kw>a=DjC#=v&-D&G$AOP<;M+Oykq$i1 zfp71?cXZ%8J8+sUM6VogR|meE1K-1e@8!S?9QeKtd_M<%fCE3!fyW$pp#wkEfgkR` zk8t2eI`E?%_^}TBI0s(rz{fi9@eX{V1E1``k9Xi-aNs97@Tm^`WCuRofuG{QPj%o4 z2VUmDPj}!I4*U!UKGT7p>A+_@@VO5BYzIEifuG~R&voDn9C*@!S4Hqwcpl!*-A|0& ze=$A~!gs?tQhFXapZA8%6|o%e)=2)89P?xce!Bz5Ppw-n%#$7Xw;lL*9QgMf_}vct z9tZvd2Y#;uzu$rX$bmoTz#nqp>J1NHdDFPQt`!>tp2u5S-Zj9ngXc$N-wy>YPPGKW z{#)Rji4pR9f%8V8fgiOU-5g>d(%UHTLnHWC1b$cq|ChiIkKhS$zV*lm{#AjCU6Mf9 z3j#knfYHqe@t}H41fL>sv0D`gdq?16M>T-25a)x%?pFZM-+^w60vO$_61X`169~Ik z;3WZ!Zhk3nacUqC_Gf{Q4`6hYy(9fqtMlZS*Pa4btMdx=yu$@ftNOufrNB=Lf^;WL zr!<1k6!_E#ev81TMew6`Cg|h{ewM(eM{s$jGakWngvp)~!D9k1i{K{+{PYOEOyFlk z@CO8bW(41B6hX5i_*J~x8@T;OL#@cqOB%h?gULg4cv_|*dcVg&z!=&#R- z;13G?+z38LH1!1$e6_&OkKjKS_yrMsKe740ID+3K@TLgqjxVeJg;`%`al~_fPaEaQ!7lx0?eP-83Cc=Zrqm_*nK`CGag8 zuVdeBz(rS}L!{?U5#Qf87iNs0y9J(|rJ{>wh?@rlo}=+2IKoQ;AEEK582=EsjW?%| z$EAK;Zl7{FUCGbL8`)h<|{NFPcB{Kj1Ku{~(QvZXEb*;J0VTG(Lia!F8#? z57xMt<^jKx^2sjL_E7yw-e2W9$9aGyv&)<(2#raPbxc_uDgYheX+j#pO z_(vk2=~{kew`0+e3%zLmmkRuF9bf7527&wgGOFMBslZ3;_>0;1FW?7f|5V$9(&yfz z?eZ4^FZ6EJ`KTGmjRL<(;}xujKREK4f`(wzPYQS;YMzsO%5GNzKiFHLaWT9i(*2Hn z9(UkBap12x@N9?t?;w7m=brp|@hUoP+>jjQ^4QQ)_0{20zB=V-fr z@_`q6{{GaH9RDmw{2B-TEs;-&<}KuWav?yWH!gzD7x)B?t8(2Z@ULn7QO@Tbflt=B z($Ai#&_d5YPlE1FTxSdXP90y_f1e}%&js$EKT-Yj-yC=WGA#5;b^eNXnFAjb_%t0~ z<^KhAbcJ3Nzgpm@MB=|FaDTr~<&#@P`9$N-5O^YzPmjR;{X|rsxPIY?ziTn&e_AA; zQyutHftN?(-z)IDHLiFE9q|t@AzuIdj4JQ11n%!wDts;`NVfQSIN(<3&D6Xq{x=2g z?}r}GdN^ymJ^o(=J}Z*X#Td8?y(peFk?=W@_}v2c_f@~ZyoXM*$G=P9XX$*t!||U5 zp3i>MdBYLkn@stCQRfrqM1>A~y1>uX@vAxh0^l~@OC0#s4*V7eei!hAv+-?3zVg_8 z3V5LxmFG7CPii?^IsV@q`R{}Si8lEU172vHQ$lkS*JKA?A@CZ_`#X-m*^z%P46M*N zKX4VtuLEwA=ME8nq0V2~$s3ON@e?TjdL3W&OY4tdU)5)GG`$i!1$dzs z&1a#&JGJ}?PWUizTmE}ar+lLEFA(^ZI-fT=pC<(VfX0euu(vQG=TX3IybB!o zWxxx)DDR5`U#@x49f@nukO+2U@(Qo zJ`tvE;+hZqVDDO8f&#`nMEu7z?{4gS8@R1pXXeuTPXF{?gG(3vwg_DxiF_W{`P?pH z@6s}RKC2!02M+v8r`hwl9(bYGr+HO*?{VPI3H&-8U)j%_z^PnM2c!oWG8}LHU-)B5lX7BX@KiK=K)|;}oyBzua*n$6= z^2vTi=fl+_ei)|ETdCz#{a6BuvXyHta9jLa9r1rF;@_|H-;K*PeWpGCD}dX^@p~Qd z-w^S?q4U3r^N*it&;Pp)e5YCV_zQp+dQa>8)p}`{z@yK(KXK%fKii)FdB6+3^*aAJ z`<@Z_of;p*<=P@}{~Ta3$Cy5c@`=tjt`PY1I-kXy&vOEgKCkUDm-6w?4Jvy$Mc^BB zKBG9FuLwN){P?)Qf2QMK&hc~4qWq)JYtsZCeQx@j!2R=wN}dbPrhI;>^H=h05co?G zyk;K7k3Qf1R^ZX+rc1s^@qeZBQRCPC=Mes~#?R++{X*c;`9SPkia(&^t9tAa_=6hn z~~lK2Q{wpIUz~;yrXdy|1yEUr}29^|9=Yn zHI1u$Mpsfk&uDx+$GZ0n;|EnyKK}Vh^}J99+@}A94*a_ge6s^D zsOX%Y@Mya`ppo*))AFnMDS>aV@o6moNDMTE-rse(upB3@ za)C$XUoP;dy}clC|6Hr;hetJ0{<~^krMHCw-%aBs%-b*UER8GqXE#$m{&`m=|L!e> z`{!M!a6bPd@TlGnzmVcb^|MsqQT^n%Qhfj1EYvQpCj{=F`#pg1e*-_*OKJHhF+RSH z@`=W85x9R&_&ARLJ%Rh@a(83=9fAAja+TdqPf`B<`P)K{|CGS}^SUaZR6E7@&*dJ) z@e7s^?w`voVfg^u_KT^k6c5($CNU`6c@k2PD z!b=GE&)=TN_>%&U%5&MJ6u&r<&-RxQ?w`M%%K5AlxPQ*Jknx#IDZYQsR_W&kflt-> zzsK<>eu?7y=VnztF9>|Pj<4{Ums9+S8b68i`J=%7^TP)*zNnMpAED!qW&92Y{u_ax zqT{Q2Uw8%ObF{`){?9q^qAMwWRG*Is{8XKfYNr)l6hA8e3j$9>;-9yS;+JWB442DW zPWb5>SMB;%fk*W=77rAKo_`)#+3l+W_s;_>Jv4rq;z#Rut-$?r!pfd^TtV^u^VLdk ziyZiq0{72dtN5pMQ$A7rCjy_U%d70F@oMT%sx_|qlRpA4^v=|{vd;^82%oKS)jtdg z+&{Oh+TGdLQ2b~;zA5l%eO=T`@%{76=&r@J>$QYO>+Aah_s=;i{ZIP}#XmP9=YYVY z`aiyp;z!HdFL3`{w9-TDs}$cq7yTT|`CWlmXb^+{xlYL`bvs_uf`#UxSkWZ ze?A%0Dsk1^Nb+2)<10OU6?lx}n9jF=TlFLIxh#^;9|eAS1kbvOc+c1PXeK!rIQFSE zuF5+NxQ%y#$fr@qSNU8j@E(n;a(zwYf2+oiW!`lH|AxjD@5>^eCXK87|0?2tTjMHz z{wgY0i^f&_V}KWW-_y8?Uk2P(u7x6>n{@mFmh%#Ue?5Z#(2>t8B7TRCzl8Id`!$mD zQjM#2)FtpQXDB}0&_)7kF9r1H+CV8%p#Q)t4 z!f%M+2Z{JMYJ5K?KT+Uc)3}mt7I5V^<*XO+Z_)9`ao}o!Kdy0=_C-fNBW|(hzXNcb z+tK-`_Hv{n{!|hF_DK9{f&1@wsC+JWd0?UKK&Y3c5;ZopVYW&@Apo&>)DHZ znQaU{Am=5|F+K=aUQ(P)*48boYHv&>8;wuHQM3ukWJ_DBadKTpT}^um-!Cg!Qd~Z^ zt?t6OJG7+=-zRgWos7_Ad(&2P81ILR@6DA@YHp}a;u~@JLKyN5euJ*Ocyit1mej@g z_}Jo>=C+0uJ`|La0*Hu{Qx~_?C7Y@i*Og`dbvJwzPZ5R;Qo%9K%l!;=nQK_odpmPBSAvLi6sw^1LW*@WAFwP@Dk(A`nfX{f=cH5*b5 zRgDdo;0~W=tZJ%7M+nWe*NFR~h6Yc!>9+RjWLZ-63h6(A88#7^2HMsn>S|N?++p#= zWO+kd3cXrwU9!Hesg$*^b!L`=a)HUFHsQ6GVEGId;uCcBrRg7ZIo|XhO zt`P&E_<${a#}-h$c&w5rNh&RyeM+*tx;SoB(&tWOzYZoXMnh^?T-7oxZKly+SX+kf zXHSCW;-42ely!+-tGLMjWGn=nd3p_XM7AKmZ@0z>lP77uK%!lczIEX7=o6IaA3HxKo2=*w#o4 zuxl-km@$<=43n(nlfz&vc>9@{L9`Ag!W>_<+A^p1 z3;nqpoL%#YpoaWO2hG-@GoIIMt!u%Dh-)yD#w5O~A=Oq^LsP;U48v)Lam4r>tIHQH zFwY;39{l-8#zv?rWpXmPsHr`Pg{X&0wk0-<<};XL$4>V#X)qr@1CRX5+ukQ#*lle>!)misL6f&qL0HNm{s2ZjXgj#qX#jw-pXx*6-sjV*Pp zW#tV;Gz}eAcN3dAVKpDwGADA&{N!stZTBl%55(}7@jmhHK^9Uj z6Y|m?mUpqf-$uJ@VuM80y$r@~o(^tCyw>)nU<7QUrRrLnsv2#n5tyuPZm&)S13!(v zJFR+^*r(4<$qmVdriIO7Ph75N1#q06KsTNAu+vzxxCP^2(?yGC()_=+apn@>Vy7^? zeo)ewLaG|Q1{4mTNar8$07(l}h_u*ST(?-}4ucIxp3qp=v?x`t7Tk@VA+%~?MufOX zW|wYUO>@h|@tHLsm&`2}BcfPcO13RYif!q|i{<)0DhN}%R6Um8lg;g^Wb?vgYgN;t zy5z#eDa5!$GE8d3QI6KC#>kJ_r_xLQ(6W+Qu}wt>KbwI?gkFPEBKN zYGF%Kq?BvHBt4pCrYqAjB`H^JP>q#`Ex3Q9;}=D$uWP;l@#rXw?B~+ObVT!#Smdfo zE^4o8txZGp1uecK2}hIHZh!Wk9DjUjZ3g+j&m2XL6_A;J0?s|u}V5# zM3I(^D%#fMepQjJXWB88=-$LEdGW_7`79%+P?<6nYg}zrs!D1?WL7+udqZAWMh_S# zQ)o_Bw=YBoJbN5%a-ip$e)gEwx`kt~RtmGg?7yuU!)OD}$t@{jyWn+GG{=sbx)wU| zVlggszEwCLBE5=6}#1}*9j4h-SK}K!OZMvud zXO?E+h>kdXr}~koi4+%8m&w%#o$%OZH7U3Hoi!E@+939Mc)M8j)x*lu)oTl>b^lj9 z5!0L`4okvLTa$GcwpTTlEpCj*tCg|M5S@xYtZr*}a&mDQb`3*2f7DN@>K;xP#q*`b zV*2vQRYRnn&DnUU>&U!sj7PE^C#FVLxwj$PK*u$Kj7H|WEyHp^k?x6XiI{ZP=t=+@W#3~@evF27uX zq7SE3PCX7UGcB3!c{1NTFXpJ?1fi;3TA)+`VoTb73=n(CDuq8(50m=il;Px0N(xIK zo_TSii8DGv8Ie7sR1tM$lImmCRy1)&lv>dLHD@z)K}9S0Z1*xXHx6?13GHDmr|X@b z&){h6=eLIae&K(OHvLZIb0@MP+JE+-vFM6i6nMy@FHbFZ0DEc03uqSr}tm>exBO$=415rN0oG&Z-@iS-)V38-tu ziZY%{)lyt_-6CvS;ILXvJwMXd;rU(Os|A~L=3sV*7cRqVGG^hG!cONECULlZ94(OZ zqL~m(o_RM`!vfLG1t}3-9h>L&8^E|Noo?h?l4>5-*e6zwCf7C5`;^Isg=O=aoAI7n zE6r#d+LA5JV#|jP2#jA+)!1G~ArleMCf?wjnxq9U84|CKkE546v2Q2$>`dt>NmF}c zqtwT?FXhlfzhmw26FE*?H9LNWdfGLWT7?&09K4ZT94yz)Ns8ruk%L|lDJhnlD^z}Z z7f`KG4}U4lkT78S{8j~9hlnNKsxVDR0A`Hh$btXy^m?(q(M94;pt#AVctfy>%DQJ0 z9*;M6oBW-SOjm%nE~JGx^O_P1;X*&r(qr$esfpXIY|oZB^m;AF*>+>DS>louwyau6 zXjx)7kGfl54M4|>6(0Qp%(g9`pikDTmMBbcIpI@~RnTc!KW#eIs6K;|si6Z@<~qr6 zR2Y{v`pLZ)BrExo%g<2j$1bbVo1+nvD(Lu)F$eh!-dR#RtCVu)`UroHCpCrKe6Sk7H9y?7iZN zt)n4DWf@ivs`s%({p)G@1kCgBs8@Cx9$|)&aa?Rd#&KGGdW$?@D(Ad3zlI+1Qx)pC zN$AuZ8Qic>Z?Fl6&f#%uQrp-eLccXx%Wkhz%ic1cZ?<~M0B=Lcm+GWKjKePC*L9!} zP!$`;oQCzhy7d#kU@)f^ffqLTaod~|6c<(F)EOT7TN-M&+JzJs*W$EK4bC>=ac5g* z66Vfqq!)3 z8DwOca||n^fcd274NT@Uh`wz`79J3T!@#7A@J4WQVRLKz{HUhPF(Pwo#K^F<#;f~D z#B1PDWSSmDbPsPHrv7Bc3^PYoxjy<7I=ziHBKq&vI(hJk<`GgdAx&UMyLWPKOE?}g*k&D^hxv+K^W5`@Dmgjfb!lDw$3ss$%J zp>vn6hs}UIXJDB+NJJ}f@@F(cJsTaw6ECla&fjgbX`YPQi5$7x=3MaW4i)r^mUw-{ zKSjIkwj6A_(8x^l7eKakg$21)@DKFiXXeUiJ0rdX?;A`KFPLIjxQI@Bi+3OJlLp2~ z{B2t=RRbb5aPwVH@uOv1U#G>%B6^oV92b`j5}9lpJ596H8PnlNFdh z!!JbX=Y-;7JiXvY=V*cx2K>+5eDJEL zwhHlkA^2(PT5NJv(epn&lTclc_n$)Kuh?N>pm=<31HB4J3k6AW`U($f@@Wt$Fgej_ zu+>qwsJZpxt!Fne5??=EBEKTMdHr#u!dz?u-Yu`i@Ap^L)Zo{Ieew7eXJa~rCpkVe zrca^K!&&uA(bLJ&$%9pm&5Q6BtN1|!=xTV~;AEPii0h<$Lbyu^7&_Q#?UK z>bEm9*Gqh&`1$_ki{ z#YC&-|Bt+Hfv=)E{=X!ks3=j=G%Bd?2ue)5(xnG|O%L1YEj(&Xe$7FgH zkL{2vBF}@TZazt!jwx!K=)b6f0yIo6-o#y9_IsKgf9h_j+IS{lJ7o7r-P-&S;5TQTXi_x$=U&_Ej2Fvo7rt4?1Ei5y${Ta&YXnh8c)+0wHQwt)_5&IkVF;M4>hogr0^)BXpCk1Ugk)_^h zd%pyJM|ZM)c*K;asAaD0eW!K`En;6$Q8$GzfY86l6P<7q`UlK_BHfoyIM!vN`Ga-6Iu|3D~ zUMfqkedQLn16<7DV+Z6=I&NS$jNc(Muo$v;D zsuQhW4(C_H`)~i%N@wSVpWc=+MBY5U6CxMr&UdZA_-7qErWvR2X?zFbpJ@4um~Bvv zUJUxC$N1oh*AAUeq?T28;H1Sb$emS_c-4TXtJF*S-v?@KYO?)1f>u7El3H)y5u;@W z%`Ah3YE zEqd(Ie`S^0Z?>u7CI`}k%yjLU9}=W_QJPYqmEHclvYYx^DD)#RHTJ&a(WcdrWZ*Oi z%tscDwtrEyGBb;w3G7sV>@<2;iBD=qL{E&{dn|XQ2@wr_sRqVQXpcS3X6X_Ff}knNOQ z+dCq53b}XRU+T#Ze!a*}D0%Jn!=2$qU%JlB&uf&?8zJZ=hu( z`xZSeVP5i6Q%~O=oL*5|N8jq=3hq587kOLRfHFF@pHNM2yWwVTX$nH`Cgf)@{IuZ9 z!Az2Tj8gj?8>b7o@+CG~3Hh4b{u1$1*SjT7`Ti&A=ej~_Us52;S7HUy(~O1oqiM|q`}QH}SdTdlZ}%J1b+ zYKc;f4a%s( zD}OKGoG*(n75rGjZUQ@x3C{V-0z1!y?AZ9c2=X()&YOVW0r)1sv%$UzJaf{2j$0>@ z+noX0EWVH6odst<+tabl*I|HTzD@-ETJYxrz@G>FJA(5L<2DK8-v#;W0RK1O3jjyn z=K=o%$iEAC2RgR-+6?&DAm5&yqmAP*3-AL0$9i>~;B1cL+?{lI>ksm`gPkJ4cLRSe z0372y32-d;se&^vm#NLy6@YgH{06Y|J@Driz*htQ9N-v-)quYY@*4zae>e`d-EIc? zJ;0x@0LM7&&4H(lcNm8*g0p?h?_q#revbh=nBP+Ye+&E{0r>9$9|!msfL{jqOMrhD zaPk5S;VHA+i0yb0EJb#O)Qp=L7HifFtiGfTMh(1Ci0j$td3yaP%`5@Oi*{ zGT>-uIN&Hh8E}mMbigtGHv^9GzaMan|8sz&Kd%6ead;i@QpnelyP5Eqev->&koPk& z(18yYoa2e(*Eo>pc2Pqdyp@4Gj$hM2o_Tv3=|tiNknaTbp#kLCS=$fX1~}Te2k;Le zzdr^0I8H4Ed5ptjAdlnJi-7+L?EePvy}{2-V4vf2qr~T*Adm4mXm>9l9Or$&&XIus z26zVuPNJq?vi1u>9_^0?d5l{L$Zr7q^8x2E)W-j3fad`I65u!kL+vH!W#f&UEfeZkHX zfMb4N1w4@7J-vKzyWlyYt%nB+PNswT1^GaJ0T1LC@IZb659HT@{|xXzegO~U7jVq) zM}mj*mDnp42lOY$fp-HO{TT%KAy6(O0O!8k#`$`|*&l94<2*MKcR28Szz&WV%R!#& zCg*{-W{}7J>h~beyu*!jBJmN(<9P9RkjL?2E8u7+OBx903)|zKf^&Vt@nT<)$2c4W z@;F}PhUBjn|NA=dL0|{tb^*xq;ZG%QB_NM+s{?uVvr>3(1bK|xe2~Yu-32(>`3c|{ zw+F#K#%&qMvmG0UwcNcu0WM!0*G>Q& z`|VQ!$NZirIM*MhvVL9&^62MOkjHq=0D1KDe!$Vs#{ow_R|1ZHPTwb$Uq0ux?YaqY zJP&#fa6Iq+E#T{*e^@WLjl&u#uTMgF7Z#xH^ANsNDG>2FW6IXF0XHc|Azve z3-~dBV?Wu?fe#X#c@GCWX9AuF_<3Ll&%b7ZJeRNSC+C7Z&NprY9LI(GLw0O?c^Kr; z&QpM+oi_o;`tTv(DF1iBIrg@md@IK*7moiC5QifGUkUQP07v_00gnEZ0*>+(fTKV4 zfFth>fTR2Zz;WKb2=MNZua^MF{Qd@TxN8Td=$9jH} z10M!Bp0}P4IQn@p;5a||so)f{L<_|2=OAAU_2Eg7=XSBs%Vy#QkpCL&yaMt#9=!!P z+Id&-W63VY;jdsH$D_?)=kLI~1?18HuRxx8SBU?6?B^YDyFmYQ1n2mm{|5t(cDf55 z_P;0CNB{eP9iEWcc6u_%qyI^eXWn(}7j4BLkN#f(^5}ml;ArPE!NdMf1N-RzT)?qj zo$I+})@?>Y{kahEF@Vo;;Lien0mvT%_=SL<2>3;Sp9=Um!21f$<;&x~jsIYf{|?Ca z2Yfu>BLT-abOpQ&-0-{rS#W>nO6YStTbA;ewJ7YlpO0bW9UIln> zkiQ!6Lcp&99OE_<@UuW3>)~X;XMz0nfX@cJNpQ{=m-!(1{X^Mvoacc2LxA%f*4F1I z0LOmy1qc3$;LJN0?7RgyU#qhA-vc{1kNPj*jUaz49rMQiqd%uPaP9+nV|g6!E(RRO zJ8ql2u{^d%TW=Z1ayf;CX=9wPwb^_X8PvmX1^j%#u^h_*zYXN;1h?f_DZj4+`P)JM zX27u=e*ief?S8=T06RYyJY0@X0*>W~^#RNAb+C`|`4I3sf%jj4qkKn_;Vm5J69LD3 z4F??aH5zcN4}6Yh?PGo5zSrVdAF%ymdq*7oNBnZKY3m8rAH;W5{aNZ|C-Hx={$PBt z{`>&qiS-BNvHl>wv+56)?+?L$?B}t*b(3=A`hO3|W4&4kcqZ~c0eQ4@zXN~JfiH33 z4?FN*IPk|D_~Q=zDZmFne3k-^aefl;u^?X$_+@~v0DLy!PXm5C;Ew?QW5BUL=?VCC zAaCa_T)xi&j^*+zzPzR06tt48OQnX6u@2ee=*oW-bH|8oPP^A&I4Zt9P^9g@8#eR-amu&;dfxi&bv5Y zI36toJ2)P_?7-gy9P7{9fMa~Ho?w3Me3i#>K3}tb90zvZ0ROSPFh1Cy;CdtSB7Qd5 ze;e%cJz%_XeAWV9VNef8JJ$k^`8^HrKZ2c!fWHIyRe+-%%opCDGZ5t82RkT_{jiNQ z=j%O?$N2mi@IGRn%Vi_so#gkGvS&M359a}n^>6{;Sg)1<{xR@A5BLVaHvo=yJ_Q`> z;TFI#o*0MCV4v3oc;o#34f1Q_!1-+f`IA_fwy^vV4>tAZpCCUT@Q(nm1RU2JrwPvX zw}3x4g8b)T2hW?(&ix>d@p%gHe}SEqfTR3cz%ict3m*3KD3JdT*vIowpO~l5;b-6Bl&IZSo|M?+kV*M{|U)+`Qo_Ho&{;+d>zSuWa|hxjxQJotUnkBSAO>+ z`*yzV%CF5A`+2lO{usb+R2`F#dDd+bDkjHhre86#jTLAdg4u7ye z=?(IB{f&A10*>>Xet?ey`(q&v7`Of){{xWk0r*b=$M%cu9piH}$PWNJ0|7q?aIA-e z0Pha+<={Wcp91oTp9VPEdB9=kbcg&IfMfh8IqVDpdGzNj!0oueH9|?Y52srwK z>t-0AYd{|3gXd+K-zPwR6!5MF9C`l=IL4s`aEyZ;?>KH4hn^rm8hB3zd<@{&51$YC zcR-%+QMdj4EC-J3gy`pOAdi0Hc!cFu5AtJyw-IoR+g*TTc|8I+mY1u3ZUlKOude~e z@;wmhA=dxn0Y~{EfL{pt!gXVmuLpU|FRz927H%&*$F?}e|3Sbp{&?PTG5B+WXU5nc z2Y5c@D#u45bwcsa;pzl7KKj|2IYbZq0$A8;(MlL5!_vhz}+Oz<-x*3OfXuP~nH zz;WE140Z-Ud@cpN2=L1QzX#LO0{k$LuLT_I8;;|HKz|7aOABA zycft{59NaR6(EoEt{H&ieDeEX2hW@C0(>y=qCE08f&8HkdFP42W1LYQ=hb(BJkH-RKDh38C&-VNcyPJg1vvVH_Z6T&cY{2Z;|~DG z`1}xXY`^yaJ{tV_5#Z?Oj{&~|IHepNsLvyf|)71{}xDOxn>B z@E_Y3&cm_(JOuIsj5nS?uKKnVG&(I&+U*UNc*7GTl-xXk|4sfg|GXckT@qNIt-Yy3GS+M^s;7#!F)Xi^5{S2D+%`Tx(3cmv7fvQq$qE=WgqFlwZ5$$N}T40k`GF_#1%dg8Z9++xo`xZvk%G zFXL+fM}K|~IQsJkz|kMX(Vs&>9{qV6aO7PJIP&uK1-l{de*s6{ZGdOO`$ynKJD9Ib z>@)x``ac(N^#4x|-gSUueBJ{b?Y|E=+FuVi=F4TjBgmuu-2q4Ye*rub`*|Rb_WAh; zyP^FJfTR7t0*>+d5OB0#<%oYZ;F;L}2<)T0tDam3^7)cMrbKyx%`)gllDB?izCH#! zHl6LDKbhG1#9;^PeTsxmS?6d%m{``Y*%ZG9P%pvb8mw$r1 zwa4Xx?G$-kcD6X|d=7XfcK!wO=+D0a&&1AFkViY%zA~}%#dfmuUx%G-fM?>*mmrV% z`U>#<#Sla9(jPmIwd-#@Z^_C|o!8j@igE6T?fH)Dd>rk+S4TsOe;yYV28{#OEy=gTty$MfZRfaClV&r>kJxK4E`l%tI^xt`b) z@;eypp9k_7|Ghx|2$1gtIQoO<-6C$rM_0eSH`xhqt}n2Mf}Eyc{#Wn;i3QrW`ZAyBzawksLE_$1;YR`44T3 z?_rL-KkMa~@jd0(?8Ilr_X0c@@Vx;q1biRB#{+KHUO0Is;I{8&d=cRLG9X(s;8-N< z0k?grQDMhvkj=htiskLK4^Fxo>C1p@g8;YJN;qj8;I@xt{A$4MSi|^2 zzy~lO+X}$#y+E9_4)Bw#FzvSielp;koQ&@~8V>SxAU^`| z+X1(0Wt{vN;OBz;8o-MI-van~fOnBjpZy;RcwfLr0X`aVJNMw^O8_4O@>c_XKHv)h zzX0$RfR6?I*MQqKVNTu%xLvzryrT?SoUe-+kgW&c<19$~BEVV4Zc_j+vmou~0?zX9 zOWG}fPXhU6fV2F2(te%-oaJrVtOL9P>}&)4Qoy^(V9d7p|4NC=k$|)P%SC4h;4HsJ z?2Z7O)w%Y-3v>@#t1AHFf&jQZ&$BF%QfX@f{ZGhhlcsH4p za~!@8IKHo@3Gi_se+%GO1AZ&u3jx0k@D+gH4){92?*M!o;CBMvEyw%8{@(@oAix&@ zJ`V7^0lymX9{|1(@E-!c0`P@^uLt}dz!Up=KiJP70iFx^j{z?Pd=cQ|0sjf$GXcLB z@I`>%2Y55!w$J8dd~eB5LB7*|-VgTwe!%VfLl}Pm@Zli81n^409|U|J;12=56!4z` z{uHTp0OxizTiQ`R;E#ZOG2qJpuL1lQfHwjDOTd=_{wUz9 z0e=ke7Qi0|Jg1BIgY)$S;Q4?*33xH!%K@(e{3*bj0Dl_rWq>~e_-epc0Nw)lvw;5x zaE`ydHrC|;Pl)sN9LNs<{CU8~0^SVx48VT{_yWLR0DL*%F9N<6@RfjX1^m~5w>!}L z!Txi;=1INk4){wTKLqfX0WSl572vZ0e+BTxfWHd(O2B^u_y)jV1HApWydUiUZvpQP z`0IcV0sMD>j{uzGVApr10KOXJ=K}r);7b616Yy1lzXkY4z}Eo&55U=<#ZoRgT|FVr z@9#lAAMif_UJUr#fY$)N7Vsv({|NXpz~2FUHQ;{&yan)efae_K{b2v!1w0?{_W&;j z+@9-jat+|?LB0v_KLfrD@V@}Q8t@MQZvlJ*;5i3-KiL1j0-g`}hkzFY{t@680?y_8 zsFd&3fNuo(g@7~nr7|wA0DLpZuLJyVfNul*?|^qZ#QVXvKLvac;4OfU1N~0RJ5DZGis^@NV6_AMF3X0UreTR=~#r{vW`v2K)=a7XtoYz*hji z4e)h``rbWoa+^+D~1gS6OLYX`! zZRo^g?@Ia*%dm-~dXtF&OH}m4iPckUN^8rL^i?5}pPE*ozxVM*mQO3&cVczTmC53X zB+G`Yz0jaXXCsvl#O{ys|nn_bwei3q;$<&gkPYzL|GvV?+MAgUCsS^2w zA4RDk-+s=o`Z6ng*7^2hfoa6C*4huag$RNX@r1k&x0!F#w&lY|A(O*Knyh(7`#vnn#j9Y*$@E9}A}zIjV07^)TE&OrAKgqxigaZWokkT zO;op_fGY^|Px3xE8R?x=+O|Y3nAHKCRr=g(=2_j2oERJ1M%rXvZ!KtEFSa(3Maqi9 zm!2#0CYy{f^xfVJf$H9$>i|<^T-{^jMQ4(+=p6VGT6mZ?HcRY+d?YYv1OHcp;M0@ zm~s$#ro$C|f7(+GG^kN^{Atb^GYSf5Mr0-=G>n!HEtXc@+k7Zk25dqfRd&sBdNYv}r?0+r*xr zWI-S6Q3;2C=%_PGhEFJGD$6aV0jhKLQ5(p4INuuT~#-&mYZY6 zw33=?n!c9T4jo;R>^Hr%vc8;CPNalsbUHnB)Zh}H;(95`3CX_v)m-`*>0rl@KWrEF zH&8bMj+Rmnl<_c=OpY!IouqkViC0QWA)1)pmo3U8RZiTsNhvx>TNXHH*M7?oEQCm#(S}gVKgDWXUB~vPB5jX1fs5+XaD@&1{w!3Q_ zT{1eqWOM<|QH%Nf;oNB79w)Q1CO$Q_Ty2A1F}bR`w!Eais(xB|+0e5`4y&L}X!?+v zb4SxyV(U%jeIB)ab^Pb$it^g3(n?-WFRimnawXMt_ETG5HMDZ7nTh$Qju}RurW+Kd zP<4u5h-dV6&T)E|&?2r`CZ^#ivS?x&l%KbP6DLlsDVbbbP8qB%DZjkFv~uXw%4BlF z_VbcYz-iK{`9g)%*I$g8SY2OLH?;LRL$tC|b&P4l8>SR^|?=0ovuxs$FXW&Jd>75cu*F1yz?%`e(@7?2tP6GL!9KP>osiM$+0e787i>%M zm?g~QsDULzYIuZ;&b0jA9GP^Fm1e^oGwLTt8mbb0X(#t^-$M{N|(&bXrZ{2 z8ym07a5L;@uGiO9`}ZkOo(uYwRq*9NZj~iw$%Y)Df1%0{zv0W>VC8O$k=TEAxy`r?XtR&@;cJZ9*M-ADa!JDqAn8o6;qQ6M~JS=M7oY$Zj#7Zm{2~s!mMT5CK>Eusk5YBXENRNWN+%Kh+HwR2<0?n zp@2G7It%7LZmRTud^glcy7%M6aR1txDxHH)w~CSZ02RSEu$l^UDI!#+E85`C*YIqU zP4dZhbb1lE2chk=7&D1ePkXCIt6L1MEyl}lB=NqSods~2xB8H7|@lz zs`|=G|2iPg=q41y${6`Z8vc}y<}>A!t81@peg1i3M4m5o@B~!6AggqP>i;yErHMp; zTKF!jo?22maU$JDkaE)8v}yB8RI#UsJmoAar&(^bnH_?uc?QqKtDkF!J$rC01-W@s9 zM^ZyH)iT&Cr4}zTU-K&99Msf%wSIH?acH)r?sjk<_E=^5OUjvSR#r}4XryMd}{oE6c^Q zLeRE3BAqP_Y-Rc3L_WVyj-=7aJ?Q6qqdu=h*v^0k{2jfz*oXU8x#d_c$4#oG6ZN_& zwBB$nCA46Kc{s@E!(bLI)v;_VV9sCz4tU7^2U{b|GH_9Y`_t zc9BUPFM;%?%dx48pfr1>XPs**OX;$1Tk4dY7_@#Fm9CJP#Y|p^E9H}c(9)z?n%NnC zMe81QQ1ocHogSA=uBVI2bm!g<^00qNGEL<8t^(?htV7;&fE2-zG&Y2zs7UTSzoVh0 z>J`n(&U3I2EhI))4%>d!g6g(*F|9ARw(<$p^d5rB8hY4ectt)xZ`PK!mUKUiwi6mp zzmlP@M-+F0H`K$leyJo$&x=RzyNxuhomU@AM(-f~SIt zJCXUp_750Mb%*m~D!ogFS5Lf*u2xl6OuRDLo2I{+F6QlsLD%h--t#&xh;09GWiX}< zu)`S*W2Z-FDZA7#L1oNN7Mte|L$hMnnd43gYGC$fT~4iTcxPVpwh&%dF%LfPfSF+W zvgZ@VGvI^}dX`XAZqo?Kr8O*iH_VP`fOH1g`rOSMAju>1rjm@RPMh+a9GJQ*lBOVO zhCx~e>Cej`>Uuns2K4jZ`(4^LWl;u`VZah9^Bqx6?vB!2jGbCKql6!~icAG}6)#hr zCA~^3bp@T;a{-+fc#XMw(oQ@>p~^JUwCO+<-&MjF=oYybkDL_qLpj@dj_!3skvHtP zW74LEkL|v{yWR6;B=16!ZS%@JYCAP|oUNJa5P8;-UPd+g{2kHG)Aq+Qw?>cH7w-bN ze@9>MKHigwwbc{qr`5sZt#;8u*DnY?_L)XH_?TrH;Q`dY`>#3kp6E-X!4Fqh4fB?n zH1d7z^MiCFZf$jKdg+p~>iP+FnMm9B&$(<;KNk1mtzM8jXK9OkvG4R7J!%)K)r@WnXz}|oLybXLwZ;(U&}3S%7;P{SgHaK;z0`|X!e&w_nl{ze3~wC`Rg4&F8n0I_ z1&*E|oClX&E0)zBBVt#TYQ?J3uS9GrGOb$-_dS}$uuLl!Pn=L&eOY-G-B@m4|HEBX z#HcRjwu}8<*chg17TVS)rdZmh&z{(sfq8tOAX41Q(t=Ae@;Xs>6?R%xs=IRIj^{zB z8aZu-;>ea_IApsp!mCU{Mbd}QDAPXu9#L+tv<=O{a0+#PDeeDQa5@B z&YpHkSgYUx#Z^ir$Z>iQaZ-+fyTU;a)aA)hh` zm?)HA9cBLpy+ps5zLC&ge%rlEzewadfj)od*Xr55OMkTJA^)ft`r{P+(J}PP6#X$V z^eaUl^M8H}{TYh>*cke=75$52=r<|)m&DLtsOXo(&|f0@SpE}Y=r2?Fzaq@mJG*z) zzZD99Sq%P_3jfzJ_*X0ZlVk9&RrD)j=&u)jtiSwSZyPtecg1hB=*wrD65M|zV(7Ch zZ^(an41N1uMXW!yG4#6#Kk845q2Eo>uZyAIUGy>k^)dAG75#QG^am;W*Tv8;68#*n z7)|+KA48w}I^Hn<-;bfsZIw6VZ;GMMWyKrv-x5QArlNmW41N0@FyvnlL!V`N!~EYJ zLw||rWBvbO4E<%IkN#g6Lw|*$pA|!Ym7<>=Lw}8;-#&)^dPToO4E@cbkMX}IhW-{s ze|!x6ZK99mw_6PTj@;kVhWfk5(C?z?cZ{K*tLX0$L%*k@zh?~n0gC=!G4zKh`aGuD zao6r$<8QH|zjqA%aiWj?$38LiD;56EG4yAMKF%L500TfPVxVc82Xi> zkNsD-82U3sAL}oV$+q9OdsqKISIPg^G4yX&{692?{u0H1o)cTY?cU}8GR1%Xro7d& zdzbzSMSo5V{Z)$o4`S%AQSyIf4E=SA{_)puKGJb(LXYV{t!j~s2KXiivH0t^v5asJ!0rj zQS^_ApZr0@@m;r~KK|En1MOBDU~G58-- z^!JFN->m3&ilP6SqW|p}`fEiW>rd|(`s)?`i(=?+R`mPF(BG=)4~U`PzC(2WdQuGi z97X@Q81=84=wtkQ#?bGs@ShgL|9nON_!#_y6#sk0&>y1cpAbWTxZ;0NjQo#P^v{Z+ zU#9p!J%)az!q00OQmy^HtN)&%=wBE^f3~8ZA0z%vO8$q(;9sEdkBFhaSkXT(hW;`| ze`E~(6^j0-82YOe{el?rU!&;vj-kI^^s)aL9mD^P3jg^r^tUMbV`JzicJumg^#76= z`W+Shi(}~LDEhpnm}&d%s_0)ALqAv1?-Qf^dno#SW9a9LKAyi^8pHoV3jbv>^oJqMwYB|89!@nKAUci$3Q6kr@8xEBa@};2)&u|1t)Dk&^#M zW9Szv`b9DPAFKF3G=_eeqW^3R|7#Te=VItzt>pjJ82Ymn{$It=Z&LVQjG@0k;a?d; zf3c!}c8u~{rs%JV!M{Su|0^-{S1SC^#L!=@=pPV6f1RSw_ta&&ez8%}|62_GEsFj- zG5k;L5uJa(8$-X7qW|X@`dtqy052{Qr!>ze?eMFNXdag?~#7{dEdI-_x9F{5LB6 z|B9jCqVVU%(BG!;^F583`rm%f==kxU82UM)kNw{lG4#7C{2#{9@2>FwH->&sh5w@% z`U4dHFJtHziaxHN4vW$LMl1TmW9Uy&^hd=YMa;i2pK0 z|E(DMD-``TG4xj{`W@+>x=h>e8byDP82al)AKUL>{D|-EN z?-=?WMIYB#{twTp z|1;5(4%uc{KXI7IgcNcGwz~p4V3FOz858|JR#5g~vC$6wzM@~AM*mz&H}MM@u9@jM zZsWx9TQMSo=){l_U? zi{D&{UyekOx$hU?!Z z;ZIs(*@yY)l9vC2h5vXYqvKFE6RQc(;@_;)e|~-|%>TKA zzexDQ^*_vS*F?hkZ&CR9`K>Vj0n|Tf`M*N=Wf<|Jz_PgUb9!3-b9u5vn~gK~-~9Yk zn7`b?f2Z&tfMj$W&i_wHpKWG`5|)ZS`-WTi_v;S*WukBWwKl@Pv&f(pKdW!w!(;Ws z@%z#dzX1}zwW7%J%TwZaw1dABPYh{0$J_aTLt#qfkv_*HTz_(Ad7c)DCiC<2J2wBe zT)*q!zexDQ^(V|<@8BOR{FaCL`T3nN|BoE}GlZYVH{3!$6L&lKYlPpvM}ql#DEz+{ z{&4^ISDCnVLvlI}^B>wluRra2c#2XDeJf%8uB1;cM9QxtKkP>v#*d#r2*;1_b7#r$ z{NpI$=XcKF7W$bO<>1d1{;i_G@jIT5!~D&{ACBK$GVq1lf0%#ZZo2kr@m8RlOp{Neg@-Ekg&y86?L3~KSaUG$Gk zQ+}lm{ij8LYDk}&L0}t4`da?S^2G+)aQ@EsFNX7fhl9TdpV-rOgtznmhWYtAy~aOR z__6-;{cmCZzc~1Z3xB%#_qz`MMG8OPKNjZC*+VbC$_(?r7wK#HU#{>MD*QJ&_?t4! z{|yfQ)e8UV3jaF}{$;}7%P)EFAYA?j&^jZTjr3pdWvD;Kq2Ea+&gsg(nDn*yZ&dQn z_dkWp|3L?T&kXr_om}Hje2=3N96yT`{(m_5hiAyY*}>mc;ph8T!ujvLmtKCA8S)=b z`da?;6@Ff;2=h;K@XyPTzskX1r110glQ4flCq4g5Gvx0{`da?SEBwU@|Jx4!*D~aP z)4@MO;UB5+U%I!R|IHclmy^Dh|0achw8HJP(>yl=>6yf3`aKmk9q7QRVsL z`3nDG`*`^ekN=MgKba3~WFoK?i+*_i_JZgq1Jcp+&tasm#jm*0W5V(KLdE}U9Q+;S z#D78>{uvJbnZn;B`W(ND75<+He>i@X!f&s?S~obaxGi+>=gjl+kMoC16#h3H`JXBL zygrXxxc)@Xu{ORUDZ#npL z75+;V{w)sv1;Rg9;%9f^_I`daxf5dI?3 zy`53bK!9PS>fP+PxuSd@IUF`->UHQ z`+LLu{rA($?=ZP=o38y7kiJ%aIo~HT+OYlb`+LLuOC9{D3;(fc^3T`THU1t7{}l@V z?sS2cJq?flmBOE{{brHA#$TxL^ZT#D`TvfCf1dDvl_vieI{3#5|60-K_H&iO|C#WI z`~UCt^%QA%2y7fH-0q?Yf)>9Yi2eW+rsHt?yOs2{_~kcwO!=bE{$H#3|GI7MQgBAKcF){wNLqv81o%ze)I8Apd+xAY6au34gf!+R24S%3fe& zUvc}w;s1f6KM;lKI9z_8JN%z{i^pW+&*jHU!eRgOsDoz7aQiD3{u9#hA4>XK{8kA+ z)*oI{4D%-){4<3=T>r!QuNVF7ke^MWZ~1LWTHj|0~aopF7SgZq1e-K{_5Q{5F1Ee|Sg> z^RE;BaQ^R=j_3H0-LRi;TmDeOT!o*TWSBquTYCLnE&S=~?^h1~{0V8e zWInKkvYD9V&_7W0(~WfbE0o|;rQ)M`da>rgntR}->vYU=io0q$x{sXKVGh^H;KeG z4*g=$KPn|^j>7&w?a-et`WJ`v!~Bms^4}u)$M$=VlK1*-N zz1{P4yy$cJ|5)L_)4@OXWKXeYh(DbFTO9l|g`dJ>Hs=3{!vBVYf41D|Vg7%r@K18^PZ$0|V|5%0p z0fqlz2mceoe_V>%9EJHGbnw>*Ki2;T75*%`0hl8d?tlIw{OS7NFCF}gl>Glp;Xlp6 zpCt=7>GFRP>1*Y`T*?2>75#__6%>Sbb|I|bE{J$*3bb1}wyj-QAcOClg zh<>{GttEXeeoadJo>2ThfhM@@Q@H(nA^eA@Ts24G_)T@_cRSTnoS8;{3h8V9FHz$E zl;Z!R4*rG0e`ScD^NQQU4*nK}{~3k<3kUxJr+F-V&kk;(pNY>M`~!HhMO&^Y@c8#E z9d{ICc3dc<3c@1c@;klI6WmYqy1**HD>rU+1pen0{tq1dqX&B|KS44& z7IQxOo`ZipPxffT@t4nq!uh`}SI__FgN=IP$q-@aXJQiRYx(cUFKef5rYLayU!>zO z|7WDnBH{QiJ%hCq30a2ne$Zbr=l?$9a9#g>(eLL=dIw?s!$@EAf9?-GNgO|4A}H+t z<)qJ&VgI`f@%WOS8Q+U=`>!N@jeoiDWBgW;tuX%v(r1b=|3z})uz(X`3-iBE`WpWL zo-EUb`G1w5Fn`}Xoqyh$9_dtX=l>1!pFsK={}kc3?Ud`!YYKmZgZ~TRr{)pZ!u+!x z{4*8)*A@O>IrtAg%cBjSKZW@ZI6{x#v7&!n!29U>R}SfG@mnDNj~9K8-y4emWe)y_ zgg;&UN*w%KmH54-@PFvwe>KDS4ePGQ@0|?wKX&MUBKnu6iT?)D*W#b^Bg!mo4nWHfO zCI|m`CI25Q{3DOi<3CUM)Aj!&NMDQp426G_!hes0e`$vN3mp7S3jf~}{tq1dzY+d) z=byul)#LZB=%*{cGf7{I-x8(%v}pc2_z#ta|7e=}^PYo$t?(}qeV#vjrtnXu1sZ}Q z^gk4Ry1gl|h4ugD(BC5Zv^*8q!ul7`0;}f#KEpk=f`E2({&lZI zzfknU{NeHY&kp^IL_gj9u^(Mv()_sUl7z$>{A(%0g*O5%s( zCx8DaT>omQfolA<4*$da2lv+X=Zb#1_+R1BUyz~xA07HjME`U@a^6AM|23qq#c!(; zKmPtxIDS{q0*e;EPlTVAM*~}!zn1hh{vLd>i8k9$@c6Np!vCy;zvDR`EmhCJ7Uo~> z;4c(@tUr4z{MmG$j+Xxc!k_N^>njI;jgtS)3jf&-{_}-@|3L1eNM9?zxr+b$DgN(E3v62a77G9ADJpYBCIVY0(%1MG34f7DbN%U}@UL_5zbE`B z1=ynTd)vXkQK>%%D*X5L*Yn@?T#xv&H2gmzeJ%f8@AXOw^WRnBzxYI*f41=Nmxh0d zL;p_EPuG9nNBWxo>=CD%znn?>8h?|*pR4eH;o$Er{OQ{N=MMfQ3V)u${~$FmE&pZ0Kf|lWekqWN zz_yt5wfr{=|1#0%_TOFMpF$UCHU4$yc{J(z&*UIozeV(^dk<`3{|iZ9^S@@X=Q!5? zqZR)f9sJ!#dbH`rpBo+ga~1w$6#m1gfot(QUHH?T{~tv9TK*R){KqN$H#_(z2tO?k z2exqh8yx)075?KD{*zAC^M9l8Q*vMn^Y=9sC;={sM*n z+SBy>Z_Kd#uOxjf{|Ua?hBmDKeH8vZ3w8e8M;Z0RU~lLD^{o0o6CDb5{;tB0^S^!y z|4P!=>VJ{&Q}zNInFwsp7wY^)O8!q&_{%AS8vk73&kL|c=P%<)UyJ{Eg@2&J-|=*v z{~_TIk6&aWuw|3J#y>;hKUv|wz`?&p_|x@2BOUxr3jZkz|8oxhEgAAZ<=|hU@bmXi z!{=Ya&(P!FWwaOO&jQhomj79#uf@Mv_;a~((Z=KFV1@s42mfwkJiR<`=l>-Wf$gp# zy8k^g)W4PVHUHP&?>UbB#}LK;Z_{;dt^J%W{QCvGjmGa`hyFOx@0><|$eB8SWrq6i zJM^y-{azt{DNY}KhxE1hZB^noREgibvvmI-68?1OPdAai#-GDCJJN>bH%#I0OD8y5 z`E3yX-hNKKgK+*&AbpL$hr&NX;s3zFf8hBZU%38+`L7(R``<(K_Ye6`E(Ess9r}Yr zKVAR(4(V(8FI4h>o|6CSvvvO`2|rD*0$Vu$my*85KUVm0{2it6?@sIVTKO*){=)+7 z(e|4~`WpXSCI4d-{z?b`3&L;fuXQ6_e*4opt>*tbqF-edWgph(>kOLzi^Tu&qR0I= ze}6VSemv^nFS@`}OjmzL(mJ2!|3#u7F8{FqBS>HKKe5ECDK>uW|HX>`|8?*$5dL)a z|6dONt_uGp3jZWpC(`o&g7E)F;%|51{Fjoxmj8U=Ukl||qVWIA!GH5uz5F8lw9di) zhu=TANc0C-$7OHpkA=sPzUF^NzFC~MCK2TFo1pmrPY3^6;kWHy%=q=!{{Fjze}VAN z0RA$CzfZBA|Be@Wis|@!k-nDyoQJ&pBmX3Yztq7$AVdCf4*t2qPs5YhIQ~-<{+k{A zQ-r^V=-XYm{2LtntA&5OC^A2PKiTSc6};KO-;^Q$GY!f)%TEO@dhec>B5=E~6(-r1*|8tm6NbivJzxJePAC_CNPx&%yBc zn=5|XU7_fQ{Vx{%bn!o#^fmt%DgIxr_+R1hzsA9zV;z_Mtq%X^I`qT!XTHP#jf(%* zDgHn0@PCo;e=Fo~*#Eyc{9m4-|L;2d&wn^t|8G$IZ%6ACTK!oq{QHFb563T8^uzUM zz37MY8`eLB^tJjkL;TMder~^W6#vIL{7;PY6pst}pBwtUz~O(s=%=gyw>kV@qQrl$ z;{UH5{uc{>w~)W#cz)*aza~Tf|K{+&Me)B;@&8ad&)4ctlkgv$#{VMG57(b%8Tx+) z>1*|806(lp8}|PEnW6vJJNzH3_|M;O5BvWchyRO&zpo#8?;tny zJBQA*x%|TS->nh-<3sY~LSWmA^tJde694l>n*0BI6#q|h@MnF;Q#>KS7F~bp=ipzh z@bmZA!|^L~@b?z}bonoF@F)0TU)nJLKT-Ib9Q@-m%zvYUKVRX$PvKwT;BU$>|4%yj z$1D6lRrohJ_@B!#|L;5an-qTj)=0SgJB`)r|KBsr|L&x()&FLN|3QVnuYpUI@JmHz@I|G!Z9zjE+z6aHJ%@c+lbzh3y4h(7nfk1G64 zbe^l_|K{ z{9Q$w^Z%s6zskYCU#X`UKL7S|m2%-l2Y=!*PZIf`QuzDRJX6d6AmQIHMP-h{{6BT* zpCkH5g!IGlTSWR={JJXsuTcCyfaVG8Q+WP1L-@nSbF_-*`sK6@bh$qxUQWa$3{hyUXh|9_?U|A52)X5kO_|G6RmKO%iT$IlMoEutTe zxBYGRf3g0D^qZ9OU#a-NRs0W^|JF48mhPXHpKRl{MB#r);qOD^bURWE^Cu>F)@(kl z?eOnjq_5S#W`%#1!q4+GjlW}t{1-d;*DCz4D*W?=-?kH*&m7^W$3p`f`^uZ$-y!-Q zn)-X9=%*0x$m&`Ar=-6-{UFx@+W^te4WOy{mxZ4d{;>X7(cjw5N_zWn`7I}XQ+`3Q zM2p04?6JxI!mhbK0*hBjF?Q5_B{Rj5; zknww7mmGd(R=bqNc8OE{dV!pCzfAoqG>3(WvF$D}n%|}0Y~d>Uf3+N6Bl~M<&tc^B zne_j9`hNrcpGE%}n?wI^l;fLdKUa<$X#YJqZlwJ@Ii64Zo8|cXv~QySx5#gvC*3B; zx6}R(Ilfc&chP=<9N$g*AJG3F%I}4=zekRLM0+kW_HPmW|A`#mOZ)recropND#!QB z{sG!Ak>dwx|BxL2jP^_A_~){JSoV+5ewiHqg7&|Z<40-#m>fS&`zPf1N!l-$ZP}`xSEhEbX6@<7V3bN{(Nk{flzElJ>urmT zuhaf_a=e=MZ^-eRw0}#E*U0|&wEu$~zfJqKa{NcxzeD>!$?-bczbnV@(f)loUQhc! z%kf`i|AFi`(EhJ-{GseWlKn>6e=Pe?Xupa6Z>Il$6YTG_|5T1!X#Wp6{*3njl;bV5 z|6Gp$Mf-ot@mAXZM~=Uc{eNk{O^&~m{a3R8TJ{`JZa5s*Ec%lz$L(p~L5_Em{qD5y zD93xyeor~xOZJ^;zqcIkBm2&@&ynMOX}_Nw?=Sl_ zENUFlVvIJtjs{vxjpW1nvZBWJ{LY3%QA2WTK{M%*Lu1y5oGB|h&XcO^U>)2T zuovtizp-%V+gLx_n=;3{`{h^qpBGDVv6H(isQ0y9Oow~mSdJ- z9OsYW@RD?@oLNfTYGNWK&dUS7ZtrsYKkfghqU$#=F;(~3v0s1vby36P#k9kc*vK_{ z4x>dU&taMRJ(p8sOnm%jR%rYrm`C`R=S(44 z^K&NsEt;QP)_4a)MUC?f8#KN7b80BTPxd@bwaoccNjwp#7!5D_nDhw5U>%+Pr@GyZ zE1M3RW&CK@Xm%%izRs&6I+IJPfE%esbusPRZ@HIjjnpXH8x=JM8$eOd#^mO9zv7x{ z$@w^-pKp7TqJ}Z6iyB6(#rT^Zg*uwXZi;{LZhhmJEmmsGRx2@P zo7dgio^$Y+!J|h}7v6(1y_T9iWtbXu!-!Qyjh9dkldFd`j%Oy?PvL%;YTp=2qui$| z#Nhd(J5b$Au5EZ@NW))>8s3A@t}U9ivd6`P#|^&Z62G_h7{?Ri5@KA`FlHe}*wpak zB5Pw{a$)CtxUx=vK8Gr%7iO+a$>*&|(fl#b)9>b@`FnE(2G0!I@KRC3`<@>3PC)}5 zJjEA^=F3q^r!l#tam+%>I=Pgp=*$FxuLfr^t*(-moS`NRCNqdd>0rm0Zh%tufkf zHH=sgs^^W#g(oK$T(>VZSKsA<$pzQ$ZpN=o9n3JdGkdc!i^w(VcT-a~@|1=Va=abY zl;jd`r0}2x7Rqm;q;I6h<1-2B>b!w%EB6F1P+bl7iMcd%q(*o;(J;d~=BTAHF~689 zaI&Q#hg}bj@EPj!Oj*@0CjRBx9GU0Gro%}2g8fGW2bdJqRO4o9Oz}@kXu6E^^YNCu zVa!sjduC!n^a??E)}GN69XT_Imu)>tup6$~+)z(-CvaLe>zd8&I?v(tj_a@4$P>@b zb4;ga$6wnlQzJ42P3d171+zVJ@FxY{8r}(J)RIk2IiKU~KhKl+jlcft>#r~2MJ(C4 zvohz{(khA?3p;jxA~ERL`hB=k^UtDL&FwaIw7*E%*O|3B$F>tMxtPUTjMBgt>Uvon zW3cWhFU`n!hEvsaPIG;r|4R7|1TCovo-7G$B$ISXp4@6XJ$9M^uZ%YBjlXCGAnLgc z&Zc$ekTkVx!K%F1)6RaQ(a?-kOjEv=eNptnsZomMfiWLjNq zMb+e!PAVBuGO@afe$`K`BkPrwxmDG5xrQ>DSN48Zb4TlNx*R&w+irtfdAON!5%FTH zA4pSXvzn=9NlPPvmkV=QBuzD^N&)pz7IYdT(=Up{D=&Wib-QSUXnl#;>AzG3Z^!xN zwWe7wQ0)B1P2q931CrJyWmMtX)A zlbVG{UUN*9sXyz;Hv&aH8&)5)D$t>kFW$_gl~#(rupMvpVN6To$R3R&Hrvd&>t>5r zwZ(b8W|LhCo^dmHCU5<-GoP)V85|L8E@^JWa~nmX^)l5w=WMptD|@Y0tsN<~Hndgi zX=eN_)<;tvjSf~v>T*(bL9xuiQhF5NHm$Jp)DHh>m$DPm2fB;x)^;84 z%u2k}u92n%WM!W|2h+(&FZ#8(9nWmO{^61B4jwl#K@uHq%xd>3gLh}`d0$rI@hm#z zxrEui{^6nRa?bDYdAsZ%W$jKkCq5~u*VuIGXItrOl~SX+*TYmDS&23aPqMn?sFzAS zgB8hdHnjFca|YANg+?9Q4>a%$nkrnV@FMkxg&Gq@bDHZq8wEOUrM5viVy|G=#c0aH zt9;y&E&yyoJE_3vP)J`{wP`c z$p&89Tu#f8W)(zMy=Gn0oTxj163B$@Pic{_-D)}=<*GtcwDlBr`p?UIY|TG|-*gy< zmd}?1ED!-aE41e<90I>RrOyNT#T_5bWgFh6Sb8Vml#_#WV=$@&t~qg6bf#U)q2oLok0 zCSP}cf*WjNcC)wSemsd#mXd25lgk>CkI}ESjfn;-GCs&@Og?7LxYst&;qp!0M0mXs zUeP#a1p(_@I{zxCVRh52t?kSrPUqQtwVo1)J>iYG6ioWn@bcGhnuA%*orrPc%gJVk zLmMf%g{ntGawRFyxpM=>mJi5_mByhKc4(Dxh=sQr;ny0+yhdVMLk`t_%di?}x_V8- za|YX%KO5vo^W}Myh42*EFFilx7E#)!T`uR`Q!^dgvGu0v)p$N1@jDZ$M}gMM4Uemt zSE3X^{ysn=RHBC)IupQkrXhK8TW{mGiI(`7g@Z-{8yd%KAYf}tyPT$`CS{7j6?A@T zP-R)uC#Kv?jYJ%U0aWp*J(`vKRgwOIE1TEmY0-&SrB)Z6oLohhTR11F<*3g7`LW+Y zaMnrL4-VykdI9U9bu_#Fm!Jp`kk=~+S$^r75k*-Hx4kN!@U z!?`;OD1{pN$(#CmU6XY*B0ywkAyNrHFG=>gb@ERn5qi?1){e0BDe@*fFyTW~)DUWl(om#tt#ZB`L-4eNCSi zIFBaVsZ?cbrm#oOoh_}m0$NN)mlNMI>PVMFYus|%p68EwfNJu~SQofIpFbu7*#L3B zGv9PwQchjz=L0r=e0|0A`Y%17OSMjl_GQAB4R82!QNug_;K5@cS1OtU6JziM)(k09 zAjUiII8?pP*>slFATJA|kXj}t`%9SFbhE~lR%_g>mBnT;*+$Z@b6&Ag@rfHSa{4md z1*Fm)CR(2J#&YW^wZlkV$S zgS3-WRgL!B4I@?)SE`Ztm6afBFO)KWEEnTiYu+?UqqM%2nOCYw(D+i=(R5RkrIaV! zG6HSE`>jXUi)6U73zk)|-J7|Elm%V3D{9E{B1$vdhT@JCMj#4l@+3G?bf^)DYP6Lz z8D-m)o;l=OsS=o9M@fWcxT&cvRd^|=)R4fXWA3e?97V>?twqauzCl|yL>=xH^5$Ww zx?MDo7F_OX?)*eE)kJT)bg*w@cTSz|%`l~NpxN86)_1VgLJbi1bfGAd>qeW$s}|^^ z0wt4UB5S)=so(ynkP~PPQsX$r|G#Xb>Iw#yjH;n!&ibml^0Jb$^2+kM^4g)r!v@w& zE~zb_R$p0HeCG5~y-Sj#N{3EQ4nJpLNy+4@`VzXKx1e{)@al<|mDE(zvg(z|-pQmp zYUlK=xqQZqe&3y5QGP`$Vi5!6--);;Tfzp0P9(Ts;*`?blDgW`in?h-C$`2NF$w?~ z>W}#+uJWO6%_Q0N@>x(|7L`lNYip}(Tg|S>_bsiRTtBtEs?MrF-{RF^zf+}-h&xpr zPq2-6(vZ%w;g$65Y(1AUZX0p1M@@MXSaJ3;&{)`&v_kW;S(^)~#RjIq-aUXki6?WZ z!Et`_eQ5M%wlIIh`!vq1$Js2LWO_+rz-ZgvJ$jd0D}9KRL~345^YVjDi3A+qUQE=oGngwk$t=Gj!d+h zk<;#wPP=z(q5-uV;rySsKKv)SPtJ{5XY9S(r6fQ()+(dr&AM(#bZ2WWS zM|VbO>r4N+%zPV{rF?7_jzUboB9*>g(vQXT(p0*=aCju9dqrr7$WIhPJaHNjLIZ^IHqTv;rl;Z(htYE%&)D(YrNq5;FBIz#sWs*J+?boF2&zAH&O!u0Jse_9p{aj4XI@6EeN=bLc ze}kkK2lUVK_1kmjNSjN)yQI7Hhe-MWHe%~{bt->ll72F#*QU~EOL`5aXHE9~Tbzb} zWg7hrY4qFg#>9!lVf@GXKgRPfm!R&F&d*r*=|!`$vkTh!J{E~gA&K}h(8i}o`glyw z@){Yp;klCD6iC0x*zZo*5=pPa^r7>!=e3{JA!~x?E6a_Qyz+A@rr2$M&YG7!t9|xC z>@o9g6??8eqwDTWh&1=H)i zax>*G>8?IxiKLG}{j4Fz0PC-kbaTIojbnMr{>C)+JMO`T6N%ILkJV4k%4QeYeh*16 z#B_-tm-lLk?~8OCC~vZn^|=|+Hkc}&vx!}Osk z{WX%#&tCZ)**#2SW&JIZ?uu2HJ=rilf5v}oEW~~;L475?4AVKEFn1a>OX>eV8HX z{m@3Gmj{k#uK38$aE0TUePXKLX%;&LXlF_)7V9OQt}>_ca$YJuu@@)MGiLn9<`wE? zuB7je>E6`Cj7^1-?waF{m-Ky5Kbhj6Dd{f%7D@V{s6RTT-z@1`KgMyKBKhZM-2!p+ z`ooiK|Ix7%6S(KPJtW=LK8qxMFdMOPlscVDP>c9+8XX7xn4ZeZJh9=L2P~CzSG{~q z(x(uI?*rFMnDe)!;mFyWmFZF#|FQY-rW&Ta^V6gkOS-FV)kykDX#et544NdpH>Ovl z(w9lP76Wcqt0i4KXUnDZ7D@jO+UFP*r#QNp$|~O(b@mfjO=5(yTHBEZg95$?v0jxhDP5RhY(sN0F zhNK@v$9@?}9c0M0agnx9{NrmaJv%X7gK4efN(cU32X1CLk+kfDy}Kxwl%2RX2*|JO z#7qZ%g9D!(!Fd>Lmq_8Jz7Uo#xc$v>;q4sy&+;<;q+@TZ6kMj0KHem_OkaF_ncy;Q z^7?Gg6vcCn90hmTiJO9eFW=z68y)z32mXBrev1P)ttXO}owz-MF_4|O(}CX=!B-N( zahBo4Ur%Gf?8My>c@H;hJdw2Q#KH*X$^XcKFLL1bI`G8~{C)@ifCGQff&a{b|J;E; z?7$y!;J(j9r%+D{3!?ij01nxfj{rSn;rNI4xDRObjwb>6a@*%_E+J8$=Qil zgMj?XHg5%qCS@mHkAj3`CssS~Hy!vI2hI<|M7Qk3+fk5^?8F}(_&W}KodbW*fvwwLIZo#3~>M7Qh&zX>L~WheG>;O5qb zh(dOP-xw3!vJ?CUndp|C;J3*{x9kMJSthvsjefR+`BJVVd+&C+GGTw){Rpza@`WO2 z@iM}*Xg+r6K3;;Ei;GNlg5MAm-LlOaV>F!K9uwWN&D&%&oZl=H-Lew{95}ymCc0%O z>=mA1T6TipL=)Yz6NL_(-%=CZvJ+-SHIQ&SNpjo<%l!NxNqxasu(P_9$~uGFSzQX} z?=5?8cS~V>#NRPYy$Owvy^Y`Rnn>_$Gq`=>Ym|}4A%vB(*!QkHtVEkjD!MjHAmkn;Co=Set z;C$v2+_FuPnAMp;LU)577Qpz&B!hoDg5PHF+z7tH;N2tm8wNizf*)k6!qE|Yq``Yc z@E;rems#@XGQQ?1}}=>n+<+;1fO7< z)`$pxkHOE0;Mu0hjf&tW8GLjEpKS2*2tM23lOp&#gy$tv=gWOW;xmJ%&X=vlJ*nT% ziC9S__9Z+I&ZEt`DajpV@N0byTXH8E{4O7#Dn}C?_AfQ^Gky8vBR|KNKSGZBQ2(9>^Z8zaR~kGj|FFSt^6l6jEj8GODkKS7SZYw+*;cwaes$l$Ad+}i&) z;aWZENJBziB5J=I;fH7Oo7%k1G=DlAK)7b-90z`tvHz+y<6ZZmUq?9Pe_`Zr_2moY z=x`dM^5A^R;@>fNRQ`2?-|pKvR*t?+Ls}lJOIWRULuMQGWh+ze6AdwXYdDn+_sA{2Y!XYAN1w>%F(?J{I>@GnJ+(Fjy5>( z{~G+~zWm{G)QzSrd5MQ3_$dZ|#K OmN^g8T=Q%ylr<&9QZ2+f7F-nFGqXPR4FeJ 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 << '\t'; + std::cout << '\n'; + } +``` + +Result sets are immutable, so all iterators on results and rows are actually +`const_iterator`s. There are also `const_reverse_iterator` types, which +iterate backwards from `rbegin()` to `rend()` exclusive. + +All these iterator types provide one extra bit of convenience that you won't +normally find in C++ iterators: referential transparency. You don't need to +dereference them to get to the row or field they refer to. That is, instead +of `row->end()` you can also choose to say `row.end()`. Similarly, you +may prefer `field.c_str()` over `field->c_str()`. + +This becomes really helpful with the array-indexing operator. With regular +C++ iterators you would need ugly expressions like `(*row)[0]` or +`row->operator[](0)`. With the iterator types defined by the result and +row classes you can simply say `row[0]`. + + +Streaming rows +-------------- + +There's another way to go through the rows coming out of a query. It's +usually easier and faster, but there are drawbacks. + +**One,** you start getting rows before all the data has come in from the +database. That speeds things up, but what happens if you lose your network +connection while transferring the data? Your application may already have +processed some of the data before finding out that the rest isn't coming. If +that is a problem for your application, streaming may not be the right choice. + +**Two,** streaming only works for some types of query. The `stream()` function +wraps your query in a PostgreSQL `COPY` command, and `COPY` only supports a few +commands: `SELECT`, `VALUES`, `or an `INSERT`, `UPDATE`, or `DELETE` with a +`RETURNING` clause. See the `COPY` documentation here: +https://www.postgresql.org/docs/current/sql-copy.html + +**Three,** when you convert a field to a "view" type (such as +`std::string_view` or `std::basic_string_view`), the view points to +underlying data which only stays valid until you iterate to the next row or +exit the loop. So if you want to use that data for longer than a single +iteration of the streaming loop, you'll have to store it somewhere yourself. + +Now for the good news. Streaming does make it very easy to query data and loop +over it: + +```cxx + for (auto [id, name, x, y] : + tx.stream( + "SELECT id, name, x, y FROM point")) + process(id + 1, "point-" + name, x * 10.0, y * 10.0); +``` + +The conversion to C++ types (here `int`, `std::string_view`, and two `float`s) +is built into the function. You never even see `row` objects, `field` objects, +iterators, or conversion methods. You just put in your query and you receive +your data. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/binary-data.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/binary-data.md new file mode 100644 index 0000000..20da8dc --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/binary-data.md @@ -0,0 +1,56 @@ +Binary data {#binary} +=========== + +The database has two ways of storing binary data: `BYTEA` is like a string, but +containing bytes rather than text characters. And _large objects_ are more +like a separate table containing binary objects. + +Generally you'll want to use `BYTEA` for reasonably-sized values, and large +objects for very large values. + +That's the database side. On the C++ side, in libpqxx, all binary data must be +either `std::basic_string` or `std::basic_string_view`; +or if you're building in C++20 or better, anything that's a block of +contiguous `std::byte` in memory. + +So for example, if you want to write a large object, you'd create a +`pqxx::blob` object. And you might use that to write data in the form of +`std::basic_string_view`. + +Your particular binary data may look different though. You may have it in a +`std::string`, or a `std::vector`, or a pointer to `char` +accompanied by a size (which could be signed or unsigned, and of any of a few +different widths). Sometimes that's your choice, or sometimes some other +library will dictate what form it takes. + +So long as it's _basically_ still a block of bytes though, you can use +`pqxx::binary_cast` to construct a `std::basic_string_view` from it. + +There are two forms of `binary_cast`. One takes a single argument that must +support `std::data()` and `std::size()`: + + std::string hi{"Hello binary world"}; + my_blob.write(pqxx::binary_cast(hi); + +The other takes a pointer and a size: + + char const greeting[] = "Hello binary world"; + char const *hi = greeting; + my_blob.write(pqxx::binary_cast(hi, sizeof(greeting))); + + +Caveats +------- + +There are some restrictions on `binary_cast` that you must be aware of. + +First, your data must of a type that gives us _bytes._ So: `char`, +`unsigned char`, `signed char`, `int8_t`, `uint8_t`, or of course `std::byte`. +You can't feed in a vector of `double`, or anything like that. + +Second, the data must be laid out as a contiguous block in memory. If there's +no `std::data()` implementation for your type, it's not suitable. + +Third, `binary_cast` only constructs something like a `std::string_view`. It +does not make a copy of your actual data. So, make sure that your data remains +alive and in the same place while you're using it. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/datatypes.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/datatypes.md new file mode 100644 index 0000000..bc14c8b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/datatypes.md @@ -0,0 +1,373 @@ +Supporting additional data types {#datatypes} +================================ + +Communication with the database mostly happens in a text format. When you +include an integer value in a query, you use `to_string` to convert it to that +text format. When you get a query result field "as a float," it converts from +the text format to a floating-point type. These conversions are everywhere in +libpqxx. + +The conversion sydstem supports many built-in types, but it is also extensible. +You can "teach" libpqxx (in the scope of your own application) to convert +additional types of values to and from PostgreSQL's string format. + +This is massively useful, but it's not for the faint of heart. You'll need to +specialise some templates. And, **the API for doing this can change with any +major libpqxx release.** + + +Converting types +---------------- + +In your application, a conversion is driven entirely by a C++ type you specify. +The value's SQL type has nothing to do with it, nor is there anything in the +string that would identify its type. + +So, if you've SELECTed a 64-bit integer from the database, and you try to +convert it to a C++ "short," one of two things will happen: either the number +is small enough to fit in your `short` (and it just works), or else it throws a +conversion exception. + +Or, your database table might have a text column, but a given field may contain +a string that _looks_ just like a number. You can convert that value to an +integer type just fine. Or to a floating-point type. All that matters to the +conversion is the actual value, and the type. + +In some cases the templates for these conversions can tell the type from the +arguments you pass them: + + auto x = to_string(99); + +In other cases you may need to instantiate template explicitly: + + auto y = from_string("99"); + + +Supporting a new type +--------------------- + +Let's say you have some other SQL type which you want to be able to store in, +or retrieve from, the database. What would it take to support that? + +Sometimes you do not need _complete_ support. You might need a conversion _to_ +a string but not _from_ a string, for example. The conversion is defined at +compile time, so don't be too afraid to be incomplete. If you leave out one of +these steps, it's not going to crash at run time or mess up your data. The +worst that can happen is that your code won't build. + +So what do you need for a complete conversion? + +First off, of course, you need a C++ type. It may be your own, but it +doesn't have to be. It could be a type from a third-party library, or even one +from the standard library that libpqxx does not yet support. + +You also specialise the `pqxx::type_name` variable to specify the type's name. +This is important for all code which mentions your type in human-readable text, +such as error messages. + +Then, does your type have a built-in null value? You specialise the +`pqxx::nullness` template to specify the details. + +Finally, you specialise the `pqxx::string_traits` template. This is where you +define the actual conversions. + +Let's go through these steps one by one. + + +Your type +--------- + +You'll need a type for which the conversions are not yet defined, because the +C++ type is what determines the right conversion. One type, one set of +conversions. + +The type doesn't have to be one that you create. The conversion logic was +designed such that you can build it around any type. So you can just as +easily build a conversion for a type that's defined somewhere else. There's +no need to include any special methods or other members inside it. That's also +how libpqxx can support converting built-in types like `int`. + +By the way, if the type is an enum, you don't need to do any of this. Just +invoke the preprocessor macro `PQXX_DECLARE_ENUM_CONVERSION`, from the global +namespace near the top of your translation unit, and pass the type as an +argument. + +The library also provides specialisations for `std::optional`, +`std::shared_ptr`, and `std::unique_ptr`. If you have conversions for +`T`, you'll also have conversions for those. + + +Specialise `type_name` +---------------------- + +When errors happen during conversion, libpqxx will compose error messages for +the user. Sometimes these will include the name of the type that's being +converted. + +To tell libpqxx the name of each type, there's a template variable called +`pqxx::type_name`. For any given type `T`, it should have a specialisation +that provides that `T`'s human-readable name: + + namespace pqxx + { + template<> std::string const type_name{"T"}; + } + +(Yes, this means that you need to define something inside the pqxx namespace. +Future versions of libpqxx may move this into a separate namespace.) + +Define this early on in your translation unit, before any code that might cause +libpqxx to need the name. That way, the libpqxx code which needs to know the +type's name can see your definition. + + +Specialise `nullness` +--------------------- + +A struct template `pqxx::nullness` defines whether your type has a natural +"null value" built in. If so, it also provides member functions for producing +and recognising null values. + +The simplest scenario is also the most common: most types don't have a null +value built in. In that case, derive your nullness traits from +`pqxx::no_null`: + + namespace pqxx + { + template<> struct nullness : pqxx::no_null {}; + } + +(Here again you're defining this in the pqxx namespace.) + +If your type does have a natural null value, the definition gets a little more +complex: + + namespace pqxx + { + template<> struct nullness + { + static constexpr bool has_null{true}; + static constexpr bool always_null{false}; + + static bool is_null(T const &value) + { + // Return whether "value" is null. + return ...; + } + + [[nodiscard]] static T null() + { + // Return a null value. + return ...; + } + }; + } + +You may be wondering why there's a function to produce a null value, but also a +function to check whether a value is null. Why not just compare the value to +the result of `null()`? Because two null values may not be equal. `T` may +have several different null values. Or it may override the comparison +operator, similar to SQL where NULL is not equal to NULL. + +As a third case, your type may be one that _always_ represents a null value. +This is the case for `std::nullptr_t` and `std::nullopt_t`. In that case, you +set `nullness::always_null` to `true` (as well as `has_null` of course), +and you won't need to define any actual conversions. + + +Specialise `string_traits` +------------------------- + +This part is more work. (You can skip it for types that are _always_ null, +but those will be rare.) Specialise the `pqxx::string_traits` template: + + namespace pqxx + { + template<> struct string_traits + { + static T from_string(std::string_view text); + static zview to_buf(char *begin, char *end, T const &value); + static char *into_buf(char *begin, char *end, T const &value); + static std::size_t size_buffer(T const &value) noexcept; + }; + } + +You'll also need to write those member functions, or as many of them as needed +to get your code to build. + + +### `from_string` + +We start off simple: `from_string` parses a string as a value of `T`, and +returns that value. + +The string may not be zero-terminated; it's just the `string_view` from +beginning to end (exclusive). In your tests, cover cases where the string +does not end in a zero byte. + +It's perfectly possible that the string isn't actually a `T` value. Mistakes +happen. In that case, throw a `pqxx::conversion_error`. + +(Of course it's also possible that you run into some other error, so it's fine +to throw different exceptions as well. But when it's definitely "this is not +the right format for a `T`," throw `conversion_error`.) + + +### `to_buf` + +In this function, you convert a value of `T` into a string that the postgres +server will understand. + +The caller will provide you with a buffer where you can write the string, if +you need it: from `begin` to `end` exclusive. It's a half-open interval, so +don't access `*end`. + +If the buffer is insufficient for you to do the conversion, throw a +`pqxx::conversion_overrun`. It doesn't have to be exact: you can be a little +pessimistic and demand a bit more space than you need. Just be sure to throw +the exception if there's any risk of overrunning the buffer. + +You don't _have_ to use the buffer for this function though. For example, +`pqxx::string_traits::to_buf` returns a compile-time constant string and +ignores the buffer. + +Even if you do use the buffer, your string does not _have_ to start at the +beginning of the buffer. For example, the integer conversions start by writing +the _least_ significant digit to the _end_ of the buffer, and then writes the +more significant digits before it. It was just more convenient. + +Return a `pqxx::zview`. This is basically a `std::string_view`, but with one +difference: a `zview` guarantees that there will be a valid zero byte right +after the `string_view`. The zero byte is not counted as part of its size, but +it will be there. + +Expressed in code, this rule must hold: + + void invariant(zview z) + { + assert(z[std::size(z)] == 0); + } + +Make sure you write your trailing zero _before_ the `end`. If the trailing +zero doesn't fit in the buffer, then there's just not enough room to perform +the conversion. + +Beware of locales when converting. If you use standard library features like +`sprintf`, they may obey whatever locale is currently set on the system. That +means that a simple integer like 1000000 may come out as "1000000" on your +system, but as "1,000,000" on mine, or as "1.000.000" for somebody else, and on +an Indian system it may be "1,00,000". Values coming from or going to the +database should be in non-localised formats. You can use libpqxx functions for +those conversions: `pqxx::from_string`, `pqxx::to_string`, `pqxx::to_buf`. + + +### `into_buf` + +This is a stricter version of `to_buf`. All the same requirements apply, but +in addition you must write your string into the buffer provided, starting +_exactly_ at `begin`. + +That's why this function returns just a simple pointer: the address right +behind the trailing zero. If the caller wants to use the string, they can +find it at `begin`. If they want to write a different value into the rest of +the buffer, they can start at the location you returned. + + +### `size_buffer` + +Here you estimate how much buffer space you need for converting a `T` to a +string. Be precise if you can, but pessimistic if you must. It's usually +better to waste a few unnecessary bytes than to spend a lot of time computing +the exact buffer space you need. And failing the conversion because you +under-budgeted the buffer is worst of all. + +Include the trailing zero in the buffer size. If your `to_buf` takes more +space than just what's needed to store the result, include that too. + +Make `size_buffer` a `constexpr` function if you can. It can allow the caller +to allocate the buffer on the stack, with a size known at compile time. + + +Optional: Specialise `is_unquoted_safe` +--------------------------------------- + +When converting arrays or composite values to strings, libpqxx may need to +quote values and escape any special characters. This takes time. + +Some types though, such as integral or floating-point types, can never have +any special characters such as quotes, commas, or backslashes in their string +representations. In such cases, there's no need to quote or escape such values +in arrays or composite types. + +If your type is like that, you can tell libpqxx about this by defining: + + namespace pqxx + { + template<> inline constexpr bool is_unquoted_safe{true}; + } + +The code that converts this type of field to strings in an array or a composite +type can then use a simpler, more efficient variant of the code. It's always +safe to leave this out; it's _just_ an optimisation for when you're completely +sure that it's safe. + +Do not do this if a string representation of your type may contain a comma; +semicolon; parenthesis; brace; quote; backslash; newline; or any other +character that might need escaping. + + +Optional: Specialise `param_format` +----------------------------------- + +This one you don't generally need to worry about. Read on if you're writing a +type which represents raw binary data, or if you're writing a template where +_some specialisations_ may contain raw binary data. + +When you call parameterised statements, or prepared statements with parameters, +libpqxx needs to your parameters on to libpq, the underlying C-level PostgreSQL +client library. + +There are two formats for doing that: _text_ and _binary._ In the first, we +represent all values as strings, and the server then converts them into its own +internal binary representation. That's what the string conversions are all +about, and it's what we do for almost all types of parameters. + +But we do it differently when the parameter is a contiguous series of raw bytes +and the corresponding SQL type is `BYTEA`. There is a text format for those, +but we bypass it for efficiency. The server can use the binary data in the +exact same form, without any conversion or extra processing. The binary data +is also twice as compact during transport. + +(People sometimes ask why we can't just treat all types as binary. However the +general case isn't so clear-cut. The binary formats are not documented, there +are no guarantees that they will be platform-independent or that they will +remain stable, and there's no really solid way to detect when we might get the +format wrong. But also, the conversions aren't necessarily as straightforward +and efficient as they sound. So, for the general case, libpqxx sticks with the +text formats. Raw binary data alone stands out as a clear win.) + +Long story short, the machinery for passing parameters needs to know: is this +parameter a binary string, or not? In the normal case it can assume "no," and +that's what it does. The text format is always a safe choice; we just try to +use the binary format where it's faster. + +The `param_format` function template is what makes the decision. We specialise +it for types which may be binary strings, and use the default for all other +types. + +"Types which _may_ be binary"? You might think we know whether a type is a +binary type or not. But there are some complications with generic types. + +Templates like `std::shared_ptr`, `std::optional`, and so on act like +"wrappers" for another type. A `std::optional` is binary if `T` is binary. +Otherwise, it's not. If you're building support for a template of this nature, +you'll probably want to implement `param_format` for it. + +The decision to use binary format is made based on a given object, not +necessarily based on the type in general. Look at `std::variant`. If you have +a `std::variant` type which can hold an `int` or a binary string, is that a +binary parameter? We can't decide without knowing the individual object. + +Containers are another hard case. Should we pass `std::vector` in binary? +Even when `T` is a binary type, we don't currently have any way to pass an +array in binary format, so we always pass it as text. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/escaping.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/escaping.md new file mode 100644 index 0000000..2ad9fe3 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/escaping.md @@ -0,0 +1,74 @@ +String escaping {#escaping} +=============== + +Writing queries as strings is easy. But sometimes you need a variable in +there: `"SELECT id FROM user WHERE name = '" + name + "'"`. + +This is dangerous. See the bug? If `name` can contain quotes, you may have +an SQL injection vulnerability there, where users can enter nasty stuff like +"`.'; DROP TABLE user`". Or if you're lucky, it's just a nasty bug that you +discover when `name` happens to be "d'Arcy". + +So, you'll need to _escape_ the `name` before you insert it. This is where +quotes and other problematic characters are marked as "this is just a character +in the string, not the end of the string." There are +[several functions](@ref escaping-functions) in libpqxx to do this for you. + + +SQL injection +------------- + +To understand what SQL injection vulnerabilities are and why they should be +prevented, imagine you use the following SQL statement somewhere in your +program: + + TX.exec( + "SELECT number,amount " + "FROM accounts " + "WHERE allowed_to_see('" + userid + "','" + password + "')"); + +This shows a logged-in user important information on all accounts he is +authorized to view. The userid and password strings are variables entered +by the user himself. + +Now, if the user is actually an attacker who knows (or can guess) the +general shape of this SQL statement, imagine he enters the following +password: + + x') OR ('x' = 'x + +Does that make sense to you? Probably not. But if this is inserted into +the SQL string by the C++ code above, the query becomes: + + SELECT number,amount + FROM accounts + WHERE allowed_to_see('user','x') OR ('x' = 'x') + +Is this what you wanted to happen? Probably not! The neat `allowed_to_see()` +clause is completely circumvented by the "`OR ('x' = 'x')`" clause, which is +always `true`. Therefore, the attacker will get to see all accounts in the +database! + + +Using the esc functions +----------------------- + +Here's how you can fix the problem in the example above: + + TX.exec( + "SELECT number,amount " + "FROM accounts " + "WHERE allowed_to_see('" + TX.esc(userid) + "', " + "'" + TX.esc(password) + "')"); + +Now, the quotes embedded in the attacker's string will be neatly escaped so +they can't "break out" of the quoted SQL string they were meant to go into: + + SELECT number,amount + FROM accounts + WHERE allowed_to_see('user', 'x'') OR (''x'' = ''x') + +If you look carefully, you'll see that thanks to the added escape characters +(a single-quote is escaped in SQL by doubling it) all we get is a very +strange-looking password string--but not a change in the SQL statement. + diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/getting-started.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/getting-started.md new file mode 100644 index 0000000..1b87b88 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/getting-started.md @@ -0,0 +1,142 @@ +Getting started {#getting-started} +=============== + +The most basic three types in libpqxx are the _connection_, the _transaction_, +and the _result_. + +They fit together as follows: +* You connect to the database by creating a `pqxx::connection` object (see + @ref connections). + +* You create a transaction object (see @ref transactions) operating on that + connection. You'll usually want the `pqxx::work` variety. + + Once you're done you call the transaction's `commit` function to make its + work final. If you don't call this, the work will be rolled back when the + transaction object is destroyed. + +* Until then, use the transaction's `exec`, `query_value`, and `stream` + functions (and variants) to execute SQL statements. You pass the statements + themselves in as simple strings. (See @ref streams for more about data + streaming). + +* Most of the `exec` functions return a `pqxx::result` object, which acts + as a standard container of rows: `pqxx::row`. + + Each row in a result, in turn, acts as a container of fields: `pqxx::field`. + See @ref accessing-results for more about results, rows, and fields. + +* Each field's data is stored internally as a text string, in a format defined + by PostgreSQL. You can convert field or row values using their `as()` and + `to()` member functions. + +* After you've closed the transaction, the connection is free to run a next + transaction. + +Here's a very basic example. It connects to the default database (you'll +need to have one set up), queries it for a very simple result, converts it to +an `int`, and prints it out. It also contains some basic error handling. + + #include + #include + + int main() + { + try + { + // Connect to the database. In practice we may have to pass some + // arguments to say where the database server is, and so on. + // The constructor parses options exactly like libpq's + // PQconnectdb/PQconnect, see: + // https://www.postgresql.org/docs/10/static/libpq-connect.html + pqxx::connection c; + + // Start a transaction. In libpqxx, you always work in one. + pqxx::work w(c); + + // work::exec1() executes a query returning a single row of data. + // We'll just ask the database to return the number 1 to us. + pqxx::row r = w.exec1("SELECT 1"); + + // Commit your transaction. If an exception occurred before this + // point, execution will have left the block, and the transaction will + // have been destroyed along the way. In that case, the failed + // transaction would implicitly abort instead of getting to this point. + w.commit(); + + // Look at the first and only field in the row, parse it as an integer, + // and print it. + // + // "r[0]" returns the first field, which has an "as<...>()" member + // function template to convert its contents from their string format + // to a type of your choice. + std::cout << r[0].as() << std::endl; + } + catch (std::exception const &e) + { + std::cerr << e.what() << std::endl; + return 1; + } + } + +This prints the number 1. Notice that you can keep the result object around +after you've closed the transaction or even the connection. There are +situations where you can't do it, but generally it's fine. If you're +interested: you can install your own callbacks for receiving error messages +from the database, and in that case you'll have to keep the connection object +alive. But otherwise, it's nice to be able to "fire and forget" your +connection and deal with the data. + +You can also convert an entire row to a series of C++-side types in one go, +using the @c as member function on the row: + + pqxx::connection c; + pqxx::work w(c); + pqxx::row r = w.exec1("SELECT 1, 2, 'Hello'"); + auto [one, two, hello] = r.as(); + std::cout << (one + two) << ' ' << std::strlen(hello) << std::endl; + +Here's a slightly more complicated example. It takes an argument from the +command line and retrieves a string with that value. The interesting part is +that it uses the escaping-and-quoting function `quote` to embed this +string value in SQL safely. It also reads the result field's value as a +plain C-style string using its `c_str` function. + + #include + #include + #include + + int main(int argc, char *argv[]) + { + try + { + if (!argv[1]) throw std::runtime_error("Give me a string!"); + + pqxx::connection c; + pqxx::work w(c); + + // work::exec() returns a full result set, which can consist of any + // number of rows. + pqxx::result r = w.exec("SELECT " + w.quote(argv[1])); + + // End our transaction here. We can still use the result afterwards. + w.commit(); + + // Print the first field of the first row. Read it as a C string, + // just like std::string::c_str() does. + std::cout << r[0][0].c_str() << std::endl; + } + catch (std::exception const &e) + { + std::cerr << e.what() << std::endl; + return 1; + } + } + +You can find more about converting field values to native types, or +converting values to strings for use with libpqxx, under +@ref stringconversion. More about getting to the rows and fields of a +result is under @ref accessing-results. + +If you want to handle exceptions thrown by libpqxx in more detail, for +example to print the SQL contents of a query that failed, see @ref exception. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/mainpage.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/mainpage.md new file mode 100644 index 0000000..5d4b8f9 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/mainpage.md @@ -0,0 +1,28 @@ +libpqxx {#mainpage} +======= + +@version 7.7.3 +@author Jeroen T. Vermeulen +@see http://pqxx.org +@see https://github.com/jtv/libpqxx + +Welcome to libpqxx, the C++ API to the PostgreSQL database management system. + +Compiling this package requires PostgreSQL to be installed -- including the +C headers for client development. The library builds on top of PostgreSQL's +standard C API, libpq. The libpq headers are not needed to compile client +programs, however. + +For a quick introduction to installing and using libpqxx, see the README.md +file. The latest information can be found at http://pqxx.org/ + + +Some links that should help you find your bearings: +* @ref getting-started +* @ref thread-safety +* @ref connections +* @ref transactions +* @ref escaping +* @ref performance +* @ref transactor +* @ref datatypes diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/parameters.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/parameters.md new file mode 100644 index 0000000..7ac7920 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/parameters.md @@ -0,0 +1,90 @@ +Statement parameters {#parameters} +==================== + +When you execute a prepared statement (see @ref prepared), or a parameterised +statement (using functions like `pqxx::connection::exec_params`), you may write +special _placeholders_ in the query text. They look like `$1`, `$2`, and so +on. + +If you execute the query and pass parameter values, the call will respectively +substitute the first where it finds `$1`, the second where it finds `$2`, et +cetera. + +Doing this saves you work. If you don't use statement parameters, you'll need +to quote and escape your values (see `connection::quote()` and friends) as you +insert them into your query as literal values. + +Or if you forget to do that, you leave yourself open to horrible +[SQL injection attacks](https://xkcd.com/327/). Trust me, I was born in a town +whose name started with an apostrophe! + +Statement parameters save you this work. With these parameters you can pass +your values as-is, and they will go across the wire to the database in a safe +format. + +In some cases it may even be faster! When a parameter represents binary data +(as in the SQL `BYTEA` type), libpqxx will send it directly as binary, which is +a bit more efficient. If you insert the binary data directly in your query +text, your CPU will have some extra work to do, converting the data into a text +format, escaping it, and adding quotes. + + +Dynamic parameter lists +----------------------- + +In rare cases you may just not know how many parameters you'll pass into your +statement when you call it. + +For these situations, have a look at `params`. It lets you compose your +parameters list on the fly, even add whole ranges of parameters at a time. + +You can pass a `params` into your statement as a normal parameter. It will +fill in all the parameter values it contains into that position of the +statement's overall parameter list. + +So if you call your statement passing a regular parameter `a`, a +`params` containing just a parameter `b`, and another regular parameter `c`, +then your call will pass parameters `a`, `b`, and `c`. Or if the params object +is empty, it will pass just `a` and `c`. If the params object contains `x` and +`y`, your call will pass `a, x, y, c`. + +You can mix static and dynamic parameters freely. Don't go overboard though: +complexity is where bugs happen! + + +Generating placeholders +----------------------- + +If your code gets particularly complex, it may sometimes happen that it becomes +hard to track which parameter value belongs with which placeholder. Did you +intend to pass this numeric value as `$7`, or as `$8`? The answer may depend +on an `if` that happened earlier in a different function. + +(Generally if things get that complex, it's a good idea to look for simpler +solutions. But especially when performance matters, sometimes you can't avoid +complexity like that.) + +There's a little helper class called `placeholders`. You can use it as a +counter which produces those placeholder strings, `$1`, `$2`, `$3`, et cetera. +When you start generating a complex statement, you can create both a `params` +and a `placeholders`: + + pqxx::params values; + pqxx::placeholders name; + +Let's say you've got some complex code to generate the conditions for an SQL +"WHERE" clause. You'll generally want to do these things close together in +your, so that you don't accidentally update one part and forget another: + + if (extra_clause) + { + // Extend the query text, using the current placeholder. + query += " AND x = " + name.get(); + // Add the parameter value. + values.append(my_x); + // Move on to the next placeholder value. + name.next(); + } + +Depending on the starting value of `name`, this might add to `query` a fragment +like "` AND x = $3`" or "` AND x = $5`". diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/performance.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/performance.md new file mode 100644 index 0000000..6c40368 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/performance.md @@ -0,0 +1,24 @@ +Performance features {#performance} +==================== + +If your program's database interaction is not as efficient as it needs to be, +the first place to look is usually the SQL you're executing. But libpqxx +has a few specialized features to help you squeeze more performance out +of how you issue commands and retrieve data: + +* @ref streams. Use these as a faster way to transfer data between your + code and the database. +* `std::string_view` and `pqxx::zview`. In places where traditional C++ worked + with `std::string`, see whether `std::string_view` or `pqxx::zview` will + do. Of course that means that you'll have to look at the data's lifetime + more carefully, but it'll save the computer a lot of copying. +* @ref prepared. These can be executed many times without the server + parsing and planning them anew each time. They also save you having to + escape string parameters. +* `pqxx::pipeline` lets you send queries to the database in batches, and + continue other processing while they are executing. +* `pqxx::connecting` lets you start setting up a database connection, but + without blocking the thread. + +As always of course, don't risk the quality of your code for optimizations +that you don't need! diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/prepared-statement.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/prepared-statement.md new file mode 100644 index 0000000..5193866 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/prepared-statement.md @@ -0,0 +1,125 @@ +Prepared statements {#prepared} +=================== + +Prepared statements are SQL queries that you define once and then invoke +as many times as you like, typically with varying parameters. It's basically +a function that you can define ad hoc. + +If you have an SQL statement that you're going to execute many times in +quick succession, it may be more efficient to prepare it once and reuse it. +This saves the database backend the effort of parsing complex SQL and +figuring out an efficient execution plan. Another nice side effect is that +you don't need to worry about escaping parameters. Some corporate coding +standards require all SQL parameters to be passed in this way, to reduce the +risk of programmer mistakes leaving room for SQL injections. + + +Preparing a statement +--------------------- + +You create a prepared statement by preparing it on the connection (using the +`pqxx::connection::prepare` functions), passing an identifier and its SQL text. + +The identifier is the name by which the prepared statement will be known; it +should consist of ASCII letters, digits, and underscores only, and start with +an ASCII letter. The name is case-sensitive. + +```cxx + void prepare_my_statement(pqxx::connection &c) + { + c.prepare( + "my_statement", + "SELECT * FROM Employee WHERE name = 'Xavier'"); + } +``` + +Once you've done this, you'll be able to call `my_statement` from any +transaction you execute on the same connection. For this, use the +`pqxx::transaction_base::exec_prepared` functions. + +```cxx + pqxx::result execute_my_statement(pqxx::transaction_base &t) + { + return t.exec_prepared("my_statement"); + } +``` + + +Parameters +---------- + +Did I mention that prepared statements can have parameters? The query text +can contain `$1`, `$2` etc. as placeholders for parameter values that you +will provide when you invoke the prepared satement. + +See @ref parameters for more about this. And here's a simple example of +preparing a statement and invoking it with parameters: + +```cxx + void prepare_find(pqxx::connection &c) + { + // Prepare a statement called "find" that looks for employees with a + // given name (parameter 1) whose salary exceeds a given number + // (parameter 2). + c.prepare( + "find", + "SELECT * FROM Employee WHERE name = $1 AND salary > $2"); + } +``` + +This example looks up the prepared statement "find," passes `name` and +`min_salary` as parameters, and invokes the statement with those values: + +```cxx + pqxx::result execute_find( + pqxx::transaction_base &t, std::string name, int min_salary) + { + return t.exec_prepared("find", name, min_salary); + } +``` + + +A special prepared statement +---------------------------- + +There is one special case: the _nameless_ prepared statement. You may prepare +a statement without a name, i.e. whose name is an empty string. The unnamed +statement can be redefined at any time, without un-preparing it first. + + +Performance note +---------------- + +Don't assume that using prepared statements will speed up your application. +There are cases where prepared statements are actually slower than plain SQL. + +The reason is that the backend can often produce a better execution plan when +it knows the statement's actual parameter values. + +For example, say you've got a web application and you're querying for users +with status "inactive" who have email addresses in a given domain name X. If +X is a very popular provider, the best way for the database engine to plan the +query may be to list the inactive users first and then filter for the email +addresses you're looking for. But in other cases, it may be much faster to +find matching email addresses first and then see which of their owners are +"inactive." A prepared statement must be planned to fit either case, but a +direct query will be optimised based on table statistics, partial indexes, etc. + + +Zero bytes +---------- + +@warning Beware of "nul" bytes! + +Any string you pass as a parameter will end at the _first char with value +zero._ If you pass a string that contains a zero byte, the last byte in the +value will be the one just before the zero. + +So, if you need a zero byte in a string, consider that it's really a _binary +string,_ which is not the same thing as a text string. SQL represents binary +data as the `BYTEA` type, or in binary large objects ("blobs"). + +In libpqxx, you represent binary data as a range of `std::byte`. They must be +contiguous in memory, so that libpqxx can pass pointers to the underlying C +library. So you might use `std::basic_string`, or +`std::basic_string_view`, or `std::vector`. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/streams.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/streams.md new file mode 100644 index 0000000..3df4d61 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/streams.md @@ -0,0 +1,107 @@ +Streams {#streams} +======= + +Most of the time it's fine to retrieve data from the database using `SELECT` +queries, and store data using `INSERT`. But for those cases where efficiency +matters, there are two classes to help you do this better: `stream_from` and +`stream_to`. They're less flexible than SQL queries, and there's the risk of +losing your connection while you're in mid-stream, but you get some speed and +memory efficiencies in return. + +Both stream classes do data conversion for you: `stream_from` receives values +from the database in PostgreSQL's text format, and converts them to the C++ +types you specify. Likewise, `stream_to` converts C++ values you provide to +PostgreSQL's text format for transfer. (On its end, the database of course +converts values to and from their SQL types.) + + +Null values +----------- + +So how do you deal with nulls? It depends on the C++ type you're using. Some +types may have a built-in null value. For instance, if you have a +`char const *` value and you convert it to an SQL string, then converting a +`nullptr` will produce a NULL SQL value. + +But what do you do about C++ types which don't have a built-in null value, such +as `int`? The trick is to wrap it in `std::optional`. The difference between +`int` and `std::optional` is that the former always has an `int` value, +and the latter doesn't have to. + +Actually it's not just `std::optional`. You can do the same thing with +`std::unique_ptr` or `std::shared_ptr`. A smart pointer is less efficient than +`std::optional` in most situations because they allocate their value on the +heap, but sometimes that's what you want in order to save moving or copying +large values around. + +This part is not generic though. It won't work with just any smart-pointer +type, just the ones which are explicitly supported: `shared_ptr` and +`unique_ptr`. If you really need to, you can build support for additional +wrappers and smart pointers by copying the implementation patterns from the +existing smart-pointer support. + + +stream\_from +------------ + +Use `stream_from` to read data directly from the database. It's faster than +the transaction's `exec` functions if the result contains enough rows. But +also, you won't need to keep your full result set in memory. That can really +matter with larger data sets. + +And, you can start processing your data right after the first row of data comes +in from the server. With `exec()` you need to wait to receive all data, and +then you begin processing. With `stream_from` you can be processing data on +the client side while the server is still sending you the rest. + +You don't actually need to create a `stream_from` object yourself, though you +can. Two shorthand functions, @ref pqxx::transaction_base::stream +and @ref pqxx::transaction_base::for_each, can create the streams for you with +a minimum of overhead. + +Not all kinds of queries will work in a stream. Internally the streams make +use of PostgreSQL's `COPY` command, so see the PostgreSQL documentation for +`COPY` for the exact limitations. Basic `SELECT` and `UPDATE ... RETURNING` +queries should just work. + +As you read a row, the stream converts its fields to a tuple type containing +the value types you ask for: + + auto stream pqxx::stream_from::query( + tx, "SELECT name, points FROM score"); + std::tuple row; + while (stream >> row) + process(row); + stream.complete(); + +As the stream reads each row, it converts that row's data into your tuple, +goes through your loop body, and then promptly forgets that row's data. This +means you can easily process more data than will fit in memory. + + +stream\_to +---------- + +Use `stream_to` to write data directly to a database table. This saves you +having to perform an `INSERT` for every row, and so it can be significantly +faster if you want to insert more than just one or two rows at a time. + +As with `stream_from`, you can specify the table and the columns, and not much +else. You insert tuple-like objects of your choice: + + pqxx::stream_to stream{ + tx, + "score", + std::vector{"name", "points"}}; + for (auto const &entry: scores) + stream << entry; + stream.complete(); + +Each row is processed as you provide it, and not retained in memory after that. + +The call to `complete()` is more important here than it is for `stream_from`. +It's a lot like a "commit" or "abort" at the end of a transaction. If you omit +it, it will be done automatically during the stream's destructor. But since +destructors can't throw exceptions, any failures at that stage won't be visible +in your code. So, always call `complete()` on a `stream_to` to close it off +properly! diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/thread-safety.md b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/thread-safety.md new file mode 100644 index 0000000..07c7f99 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/amd64/share/doc/libpqxx/thread-safety.md @@ -0,0 +1,29 @@ +Thread safety {#thread-safety} +============= + +This library does not contain any locking code to protect objects against +simultaneous modification in multi-threaded programs. Therefore it is up +to you, the user of the library, to ensure that your threaded client +programs perform no conflicting operations concurrently. + +Most of the time this isn't hard. Result sets are immutable, so you can +share them between threads without problem. The main rule is: + +@li Treat a connection, together with any and all objects related to it, as +a "world" of its own. You should generally make sure that the same "world" +is never accessed by another thread while you're doing anything non-const +in there. + +That means: don't issue a query on a transaction while you're also opening +a subtransaction, don't access a cursor while you may also be committing, +and so on. + +In particular, cursors are tricky. It's easy to perform a non-const +operation without noticing. So, if you're going to share cursors or +cursor-related objects between threads, lock very conservatively! + +Use `pqxx::describe_thread_safety` to find out at runtime what level of +thread safety is implemented in your build and version of libpqxx. It +returns a `pqxx::thread_safety_model` describing what you can and cannot rely +on. A command-line utility `tools/pqxxthreadsafety` prints out the same +information. diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array new file mode 100644 index 0000000..689f5b2 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array @@ -0,0 +1,6 @@ +/** Handling of SQL arrays. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/array.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array.hxx new file mode 100644 index 0000000..8440a24 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/array.hxx @@ -0,0 +1,103 @@ +/* Handling of SQL arrays. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ARRAY +#define PQXX_H_ARRAY + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx +{ +/// Low-level array parser. +/** Use this to read an array field retrieved from the database. + * + * This parser will only work reliably if your client encoding is UTF-8, ASCII, + * or a single-byte encoding which is a superset of ASCII (such as Latin-1). + * + * Also, the parser only supports array element types which use either a comma + * or a semicolon ("," or ";") as the separator between array elements. All + * built-in types use comma, except for one which uses semicolon, but some + * custom types may not work. + * + * The input is a C-style string containing the textual representation of an + * array, as returned by the database. The parser reads this representation + * on the fly. The string must remain in memory until parsing is done. + * + * Parse the array by making calls to @ref get_next until it returns a + * @ref juncture of "done". The @ref juncture tells you what the parser found + * in that step: did the array "nest" to a deeper level, or "un-nest" back up? + */ +class PQXX_LIBEXPORT array_parser +{ +public: + /// What's the latest thing found in the array? + enum class juncture + { + /// Starting a new row. + row_start, + /// Ending the current row. + row_end, + /// Found a NULL value. + null_value, + /// Found a string value. + string_value, + /// Parsing has completed. + done, + }; + + // TODO: constexpr noexcept. Breaks ABI. + /// Constructor. You don't need this; use @ref field::as_array instead. + /** The parser only remains valid while the data underlying the @ref result + * remains valid. Once all `result` objects referring to that data have been + * destroyed, the parser will no longer refer to valid memory. + */ + explicit array_parser( + std::string_view input, + internal::encoding_group = internal::encoding_group::MONOBYTE); + + /// Parse the next step in the array. + /** Returns what it found. If the juncture is @ref juncture::string_value, + * the string will contain the value. Otherwise, it will be empty. + * + * Call this until the @ref array_parser::juncture it returns is + * @ref juncture::done. + */ + std::pair get_next(); + +private: + std::string_view m_input; + internal::glyph_scanner_func *const m_scan; + + /// Current parsing position in the input. + std::string::size_type m_pos = 0u; + + std::string::size_type scan_single_quoted_string() const; + std::string parse_single_quoted_string(std::string::size_type end) const; + std::string::size_type scan_double_quoted_string() const; + std::string parse_double_quoted_string(std::string::size_type end) const; + std::string::size_type scan_unquoted_string() const; + std::string parse_unquoted_string(std::string::size_type end) const; + + std::string::size_type scan_glyph(std::string::size_type pos) const; + std::string::size_type + scan_glyph(std::string::size_type pos, std::string::size_type end) const; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring new file mode 100644 index 0000000..77551d9 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring @@ -0,0 +1,6 @@ +/** BYTEA (binary string) conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring.hxx new file mode 100644 index 0000000..47c82a0 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/binarystring.hxx @@ -0,0 +1,236 @@ +/* Deprecated representation for raw, binary data. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BINARYSTRING +#define PQXX_H_BINARYSTRING + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class binarystring; +template<> struct string_traits; + + +/// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type. +/** @ingroup escaping-functions + * @deprecated Use @c std::basic_string and + * @c std::basic_string_view for binary data. In C++20 or better, + * any @c contiguous_range of @c std::byte will do. + * + * This class represents a binary string as stored in a field of type @c bytea. + * + * Internally a binarystring is zero-terminated, but it may also contain null + * bytes, they're just like any other byte value. So don't assume that it's + * safe to treat the contents as a C-style string. + * + * The binarystring retains its value even if the result it was obtained from + * is destroyed, but it cannot be copied or assigned. + * + * \relatesalso transaction_base::quote_raw + * + * To include a @c binarystring value in an SQL query, escape and quote it + * using the transaction's @c quote_raw function. + * + * @warning This class is implemented as a reference-counting smart pointer. + * Copying, swapping, and destroying binarystring objects that refer to the + * same underlying data block is not thread-safe. If you wish to pass + * binarystrings around between threads, make sure that each of these + * operations is protected against concurrency with similar operations on the + * same object, or other objects pointing to the same data block. + */ +class PQXX_LIBEXPORT binarystring +{ +public: + using char_type = unsigned char; + using value_type = std::char_traits::char_type; + using size_type = std::size_t; + using difference_type = long; + using const_reference = value_type const &; + using const_pointer = value_type const *; + using const_iterator = const_pointer; + using const_reverse_iterator = std::reverse_iterator; + + [[deprecated("Use std::byte for binary data.")]] binarystring( + binarystring const &) = default; + + /// Read and unescape bytea field. + /** The field will be zero-terminated, even if the original bytea field + * isn't. + * @param F the field to read; must be a bytea field + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + field const &); + + /// Copy binary data from std::string_view on binary data. + /** This is inefficient in that it copies the data to a buffer allocated on + * the heap. + */ + [[deprecated("Use std::byte for binary data.")]] explicit binarystring( + std::string_view); + + /// Copy binary data of given length straight out of memory. + [[deprecated("Use std::byte for binary data.")]] binarystring( + void const *, std::size_t); + + /// Efficiently wrap a buffer of binary data in a @c binarystring. + [[deprecated("Use std::byte for binary data.")]] binarystring( + std::shared_ptr ptr, size_type size) : + m_buf{std::move(ptr)}, m_size{size} + {} + + /// Size of converted string in bytes. + [[nodiscard]] size_type size() const noexcept { return m_size; } + /// Size of converted string in bytes. + [[nodiscard]] size_type length() const noexcept { return size(); } + [[nodiscard]] bool empty() const noexcept { return size() == 0; } + + [[nodiscard]] const_iterator begin() const noexcept { return data(); } + [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); } + [[nodiscard]] const_iterator end() const noexcept { return data() + m_size; } + [[nodiscard]] const_iterator cend() const noexcept { return end(); } + + [[nodiscard]] const_reference front() const noexcept { return *begin(); } + [[nodiscard]] const_reference back() const noexcept + { + return *(data() + m_size - 1); + } + + [[nodiscard]] const_reverse_iterator rbegin() const + { + return const_reverse_iterator{end()}; + } + [[nodiscard]] const_reverse_iterator crbegin() const { return rbegin(); } + [[nodiscard]] const_reverse_iterator rend() const + { + return const_reverse_iterator{begin()}; + } + [[nodiscard]] const_reverse_iterator crend() const { return rend(); } + + /// Unescaped field contents. + [[nodiscard]] value_type const *data() const noexcept { return m_buf.get(); } + + [[nodiscard]] const_reference operator[](size_type i) const noexcept + { + return data()[i]; + } + + [[nodiscard]] PQXX_PURE bool operator==(binarystring const &) const noexcept; + [[nodiscard]] bool operator!=(binarystring const &rhs) const noexcept + { + return not operator==(rhs); + } + + binarystring &operator=(binarystring const &); + + /// Index contained string, checking for valid index. + const_reference at(size_type) const; + + /// Swap contents with other binarystring. + void swap(binarystring &); + + /// Raw character buffer (no terminating zero is added). + /** @warning No terminating zero is added! If the binary data did not end in + * a null character, you will not find one here. + */ + [[nodiscard]] char const *get() const noexcept + { + return reinterpret_cast(m_buf.get()); + } + + /// Read contents as a std::string_view. + [[nodiscard]] std::string_view view() const noexcept + { + return std::string_view(get(), size()); + } + + /// Read as regular C++ string (may include null characters). + /** This creates and returns a new string object. Don't call this + * repeatedly; retrieve your string once and keep it in a local variable. + * Also, do not expect to be able to compare the string's address to that of + * an earlier invocation. + */ + [[nodiscard]] std::string str() const; + + /// Access data as a pointer to @c std::byte. + [[nodiscard]] std::byte const *bytes() const + { + return reinterpret_cast(get()); + } + + /// Read data as a @c std::basic_string_view. + [[nodiscard]] std::basic_string_view bytes_view() const + { + return std::basic_string_view{bytes(), size()}; + } + +private: + std::shared_ptr m_buf; + size_type m_size{0}; +}; + + +template<> struct nullness : no_null +{}; + + +/// String conversion traits for @c binarystring. +/** Defines the conversions between a @c binarystring and its PostgreSQL + * textual format, for communication with the database. + * + * These conversions rely on the "hex" format which was introduced in + * PostgreSQL 9.0. Both your libpq and the server must be recent enough to + * speak this format. + */ +template<> struct string_traits +{ + static std::size_t size_buffer(binarystring const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, binarystring const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, binarystring const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + std::string_view text{value.view()}; + internal::esc_bin(binary_cast(text), begin); + return begin + budget; + } + + static binarystring from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::shared_ptr buf{ + new unsigned char[size], [](unsigned char const *x) { delete[] x; }}; + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.get())); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return binarystring{std::move(buf), size}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob new file mode 100644 index 0000000..3fd0afa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob @@ -0,0 +1,6 @@ +/** Binary Large Objects interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob.hxx new file mode 100644 index 0000000..6d77be7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/blob.hxx @@ -0,0 +1,351 @@ +/* Binary Large Objects interface. + * + * Read or write large objects, stored in their own storage on the server. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_BLOB +#define PQXX_H_BLOB + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#if defined(PQXX_HAVE_PATH) +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/** Binary large object. + * + * This is how you store data that may be too large for the `BYTEA` type. + * Access operations are similar to those for a file: you can read, write, + * query or set the current reading/writing position, and so on. + * + * These large objects live in their own storage on the server, indexed by an + * integer object identifier ("oid"). + * + * Two `blob` objects may refer to the same actual large object in the + * database at the same time. Each will have its own reading/writing position, + * but writes to the one will of course affect what the other sees. + */ +class PQXX_LIBEXPORT blob +{ +public: + /// Create a new, empty large object. + /** You may optionally specify an oid for the new blob. If you do, then + * the new object will have that oid -- or creation will fail if there + * already is an object with that oid. + */ + [[nodiscard]] static oid create(dbtransaction &, oid = 0); + + /// Delete a large object, or fail if it does not exist. + static void remove(dbtransaction &, oid); + + /// Open blob for reading. Any attempt to write to it will fail. + [[nodiscard]] static blob open_r(dbtransaction &, oid); + // Open blob for writing. Any attempt to read from it will fail. + [[nodiscard]] static blob open_w(dbtransaction &, oid); + // Open blob for reading and/or writing. + [[nodiscard]] static blob open_rw(dbtransaction &, oid); + + /// You can default-construct a blob, but it won't do anything useful. + /** Most operations on a default-constructed blob will throw @ref + * usage_error. + */ + blob() = default; + + /// You can move a blob, but not copy it. The original becomes unusable. + blob(blob &&); + /// You can move a blob, but not copy it. The original becomes unusable. + blob &operator=(blob &&); + + blob(blob const &) = delete; + blob &operator=(blob const &) = delete; + ~blob(); + + /// Maximum number of bytes that can be read or written at a time. + /** The underlying protocol only supports reads and writes up to 2 GB + * exclusive. + * + * If you need to read or write more data to or from a binary large object, + * you'll have to break it up into chunks. + */ + static constexpr std::size_t chunk_limit = 0x7fffffff; + + /// Read up to `size` bytes of the object into `buf`. + /** Uses a buffer that you provide, resizing it as needed. If it suits you, + * this lets you allocate the buffer once and then re-use it multiple times. + * + * Resizes `buf` as needed. + * + * @warning The underlying protocol only supports reads up to 2GB at a time. + * If you need to read more, try making repeated calls to @ref append_to_buf. + */ + std::size_t read(std::basic_string &buf, std::size_t size); + +#if defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::span read(std::span buf) + { + return buf.subspan(0, raw_read(std::data(buf), std::size(buf))); + } +#endif // PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Read up to `std::size(buf)` bytes from the object. + /** Retrieves bytes from the blob, at the current position, until `buf` is + * full or there are no more bytes to read, whichever comes first. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template std::span read(DATA &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#else // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + /// Read up to `std::size(buf)` bytes from the object. + /** @deprecated As libpqxx moves to C++20 as its baseline language version, + * this will take and return `std::span`. + * + * Retrieves bytes from the blob, at the current position, until `buf` is + * full (i.e. its current size is reached), or there are no more bytes to + * read, whichever comes first. + * + * This function will not change either the size or the capacity of `buf`, + * only its contents. + * + * Returns the filled portion of `buf`. This may be empty. + */ + template + std::basic_string_view read(std::vector &buf) + { + return {std::data(buf), raw_read(std::data(buf), std::size(buf))}; + } +#endif // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN + +#if defined(PQXX_HAVE_CONCEPTS) + /// Write `data` to large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#else + /// Write `data` large object, at the current position. + /** If the writing position is at the end of the object, this will append + * `data` to the object's contents and move the writing position so that + * it's still at the end. + * + * If the writing position was not at the end, writing will overwrite the + * prior data, but it will not remove data that follows the part where you + * wrote your new data. + * + * @warning This is a big difference from writing to a file. You can + * overwrite some data in a large object, but this does not truncate the + * data that was already there. For example, if the object contained binary + * data "abc", and you write "12" at the starting position, the object will + * contain "12c". + * + * @warning The underlying protocol only supports writes up to 2 GB at a + * time. If you need to write more, try making repeated calls to + * @ref append_from_buf. + */ + template void write(DATA const &data) + { + raw_write(std::data(data), std::size(data)); + } +#endif + + /// Resize large object to `size` bytes. + /** If the blob is more than `size` bytes long, this removes the end so as + * to make the blob the desired length. + * + * If the blob is less than `size` bytes long, it adds enough zero bytes to + * make it the desired length. + */ + void resize(std::int64_t size); + + /// Return the current reading/writing position in the large object. + [[nodiscard]] std::int64_t tell() const; + + /// Set the current reading/writing position to an absolute offset. + /** Returns the new file offset. */ + std::int64_t seek_abs(std::int64_t offset = 0); + /// Move the current reading/writing position forwards by an offset. + /** To move backwards, pass a negative offset. + * + * Returns the new file offset. + */ + std::int64_t seek_rel(std::int64_t offset = 0); + /// Set the current position to an offset relative to the end of the blob. + /** You'll probably want an offset of zero or less. + * + * Returns the new file offset. + */ + std::int64_t seek_end(std::int64_t offset = 0); + + /// Create a binary large object containing given `data`. + /** You may optionally specify an oid for the new object. If you do, and an + * object with that oid already exists, creation will fail. + */ + static oid from_buf( + dbtransaction &tx, std::basic_string_view data, oid id = 0); + + /// Append `data` to binary large object. + /** The underlying protocol only supports appending blocks up to 2 GB. + */ + static void append_from_buf( + dbtransaction &tx, std::basic_string_view data, oid id); + + /// Read client-side file and store it server-side as a binary large object. + [[nodiscard]] static oid from_file(dbtransaction &, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + [[nodiscard]] static oid + from_file(dbtransaction &tx, std::filesystem::path const &path) + { + return from_file(tx, path.c_str()); + } +#endif + + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + */ + static oid from_file(dbtransaction &, char const path[], oid); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Read client-side file and store it server-side as a binary large object. + /** In this version, you specify the binary large object's oid. If that oid + * is already in use, the operation will fail. + * + * This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static oid + from_file(dbtransaction &tx, std::filesystem::path const &path, oid id) + { + return from_file(tx, path.c_str(), id); + } +#endif + + /// Convenience function: Read up to `max_size` bytes from blob with `id`. + /** You could easily do this yourself using the @ref open_r and @ref read + * functions, but it can save you a bit of code to do it this way. + */ + static void to_buf( + dbtransaction &, oid, std::basic_string &, + std::size_t max_size); + + /// Read part of the binary large object with `id`, and append it to `buf`. + /** Use this to break up a large read from one binary large object into one + * massive buffer. Just keep calling this function until it returns zero. + * + * The `offset` is how far into the large object your desired chunk is, and + * `append_max` says how much to try and read in one go. + */ + static std::size_t append_to_buf( + dbtransaction &tx, oid id, std::int64_t offset, + std::basic_string &buf, std::size_t append_max); + + /// Write a binary large object's contents to a client-side file. + static void to_file(dbtransaction &, oid, char const path[]); + +#if defined(PQXX_HAVE_PATH) && !defined(_WIN32) + /// Write a binary large object's contents to a client-side file. + /** This overload is not available on Windows, where `std::filesystem::path` + * converts to a `wchar_t` string rather than a `char` string. + */ + static void + to_file(dbtransaction &tx, oid id, std::filesystem::path const &path) + { + to_file(tx, id, path.c_str()); + } +#endif + + /// Close this blob. + /** This does not delete the blob from the database; it only terminates your + * local object for accessing the blob. + * + * Resets the blob to a useless state similar to one that was + * default-constructed. + * + * The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + */ + void close(); + +private: + PQXX_PRIVATE blob(connection &conn, int fd) noexcept : + m_conn{&conn}, m_fd{fd} + {} + static PQXX_PRIVATE blob open_internal(dbtransaction &, oid, int); + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::connection *) noexcept; + static PQXX_PRIVATE pqxx::internal::pq::PGconn * + raw_conn(pqxx::dbtransaction const &) noexcept; + static PQXX_PRIVATE std::string errmsg(connection const *); + static PQXX_PRIVATE std::string errmsg(dbtransaction const &tx) + { + return errmsg(&tx.conn()); + } + PQXX_PRIVATE std::string errmsg() const { return errmsg(m_conn); } + PQXX_PRIVATE std::int64_t seek(std::int64_t offset, int whence); + std::size_t raw_read(std::byte buf[], std::size_t size); + void raw_write(std::byte const buf[], std::size_t size); + + connection *m_conn = nullptr; + int m_fd = -1; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite new file mode 100644 index 0000000..2bfa7ad --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite @@ -0,0 +1,6 @@ +/** Handling of SQL "composite types." + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite.hxx new file mode 100644 index 0000000..439b133 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/composite.hxx @@ -0,0 +1,149 @@ +#ifndef PQXX_H_COMPOSITE +#define PQXX_H_COMPOSITE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Parse a string representation of a value of a composite type. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own @ref string_traits + * for a composite type. + * + * This function interprets `text` as the string representation of a value of + * some composite type, and sets each of `fields` to the respective values of + * its fields. The field types must be copy-assignable. + * + * The number of fields must match the number of fields in the composite type, + * and there must not be any other text in the input. The function is meant to + * handle any value string that the backend can produce, but not necessarily + * every valid alternative spelling. + * + * Fields in composite types can be null. When this happens, the C++ type of + * the corresponding field reference must be of a type that can handle nulls. + * If you are working with a type that does not have an inherent null value, + * such as e.g. `int`, consider using `std::optional`. + */ +template +inline void parse_composite( + pqxx::internal::encoding_group enc, std::string_view text, T &...fields) +{ + static_assert(sizeof...(fields) > 0); + + auto const scan{pqxx::internal::get_glyph_scanner(enc)}; + auto const data{std::data(text)}; + auto const size{std::size(text)}; + if (size == 0) + throw conversion_error{"Cannot parse composite value from empty string."}; + + std::size_t here{0}, next{scan(data, size, here)}; + if (next != 1 or data[here] != '(') + throw conversion_error{ + internal::concat("Invalid composite value string: ", text)}; + + here = next; + + constexpr auto num_fields{sizeof...(fields)}; + std::size_t index{0}; + (pqxx::internal::parse_composite_field( + index, text, here, fields, scan, num_fields - 1), + ...); + if (here != std::size(text)) + throw conversion_error{internal::concat( + "Composite value did not end at the closing parenthesis: '", text, + "'.")}; + if (text[here - 1] != ')') + throw conversion_error{internal::concat( + "Composive value did not end in parenthesis: '", text, "'")}; +} + + +/// Parse a string representation of a value of a composite type. +/** @warning This version only works for UTF-8 and single-byte encodings. + * + * For proper encoding support, use the composite-type support in the + * `field` class. + */ +template +inline void parse_composite(std::string_view text, T &...fields) +{ + parse_composite(pqxx::internal::encoding_group::MONOBYTE, text, fields...); +} +} // namespace pqxx + + +namespace pqxx::internal +{ +constexpr char empty_composite_str[]{"()"}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Estimate the buffer size needed to represent a value of a composite type. +/** Returns a conservative estimate. + */ +template +[[nodiscard]] inline std::size_t +composite_size_buffer(T const &...fields) noexcept +{ + constexpr auto num{sizeof...(fields)}; + + // Size for a multi-field composite includes room for... + // + opening parenthesis + // + field budgets + // + separating comma per field + // - comma after final field + // + closing parenthesis + // + terminating zero + + if constexpr (num == 0) + return std::size(pqxx::internal::empty_composite_str); + else + return 1 + (pqxx::internal::size_composite_field_buffer(fields) + ...) + + num + 1; +} + + +/// Render a series of values as a single composite SQL value. +/** @warning This code is still experimental. Use with care. + * + * You may use this as a helper while implementing your own `string_traits` + * for a composite type. + */ +template +inline char *composite_into_buf(char *begin, char *end, T const &...fields) +{ + if (std::size_t(end - begin) < composite_size_buffer(fields...)) + throw conversion_error{ + "Buffer space may not be enough to represent composite value."}; + + constexpr auto num_fields{sizeof...(fields)}; + if constexpr (num_fields == 0) + { + constexpr char empty[]{"()"}; + std::memcpy(begin, empty, std::size(empty)); + return begin + std::size(empty); + } + + char *pos{begin}; + *pos++ = '('; + + (pqxx::internal::write_composite_field(pos, end, fields), ...); + + // If we've got multiple fields, "backspace" that last comma. + if constexpr (num_fields > 1) + --pos; + *pos++ = ')'; + *pos++ = '\0'; + return pos; +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/config-public-compiler.h b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/config-public-compiler.h new file mode 100644 index 0000000..3668a10 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/config-public-compiler.h @@ -0,0 +1,81 @@ +/* include/pqxx/config.h.in. Generated from configure.ac by autoheader. */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ +/* Define to 1 if you have the `pq' library (-lpq). */ +/* #undef HAVE_LIBPQ */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MEMORY_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDLIB_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRINGS_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRING_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STAT_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TYPES_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +/* #undef LT_OBJDIR */ +/* Name of package */ +/* #undef PACKAGE */ +/* Define to the address where bug reports for this package should be sent. */ +/* #undef PACKAGE_BUGREPORT */ +/* Define to the full name of this package. */ +/* #undef PACKAGE_NAME */ +/* Define to the full name and version of this package. */ +/* #undef PACKAGE_STRING */ +/* Define to the one symbol short name of this package. */ +/* #undef PACKAGE_TARNAME */ +/* Define to the home page for this package. */ +/* #undef PACKAGE_URL */ +/* Define to the version of this package. */ +/* #undef PACKAGE_VERSION */ +/* Define if supports floating-point conversion. */ +#define PQXX_HAVE_CHARCONV_FLOAT +/* Define if supports integer conversion. */ +#define PQXX_HAVE_CHARCONV_INT +/* Define if compiler has C++20 std::cmp_greater etc. */ +/* #undef PQXX_HAVE_CMP */ +/* Define if compiler supports Concepts and header. */ +/* #undef PQXX_HAVE_CONCEPTS */ +/* Define if compiler supports __cxa_demangle */ +#define PQXX_HAVE_CXA_DEMANGLE +/* Define if g++ supports pure attribute */ +#define PQXX_HAVE_GCC_PURE +/* Define if g++ supports visibility attribute. */ +#define PQXX_HAVE_GCC_VISIBILITY +/* Define if likely & unlikely work. */ +/* #undef PQXX_HAVE_LIKELY */ +/* Define if operator[] can take multiple arguments. */ +/* #undef PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT */ +/* Define if compiler has usable std::filesystem::path. */ +#define PQXX_HAVE_PATH +/* Define if poll() is available. */ +#define PQXX_HAVE_POLL +/* Define if libpq has PQencryptPasswordConn (since pg 10). */ +#define PQXX_HAVE_PQENCRYPTPASSWORDCONN +/* Define if libpq has pipeline mode (since pg 14). */ +#define PQXX_HAVE_PQ_PIPELINE +/* Define if std::this_thread::sleep_for works. */ +#define PQXX_HAVE_SLEEP_FOR +/* Define if compiler has std::span. */ +/* #undef PQXX_HAVE_SPAN */ +/* Define if strerror_r() is available. */ +#define PQXX_HAVE_STRERROR_R +/* Define if strerror_s() is available. */ +/* #undef PQXX_HAVE_STRERROR_S */ +/* Define if thread_local is fully supported. */ +#define PQXX_HAVE_THREAD_LOCAL +/* Define if std::chrono has year_month_day etc. */ +/* #undef PQXX_HAVE_YEAR_MONTH_DAY */ +/* Define to 1 if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ +/* Version number of package */ +/* #undef VERSION */ diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection new file mode 100644 index 0000000..82ff43a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection @@ -0,0 +1,8 @@ +/** pqxx::connection class. + * + * pqxx::connection encapsulates a connection to a database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection.hxx new file mode 100644 index 0000000..92454bb --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/connection.hxx @@ -0,0 +1,1261 @@ +/* Definition of the connection class. + * + * pqxx::connection encapsulates a connection to a database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CONNECTION +#define PQXX_H_CONNECTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Double-check in order to suppress an overzealous Visual C++ warning (#418). +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/params.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +/** + * @addtogroup connections + * + * Use of the libpqxx library starts here. + * + * Everything that can be done with a database through libpqxx must go through + * a @ref pqxx::connection object. It connects to a database when you create + * it, and it terminates that communication during destruction. + * + * Many things come together in this class. Handling of error and warning + * messages, for example, is defined by @ref pqxx::errorhandler objects in the + * context of a connection. Prepared statements are also defined here. + * + * When you connect to a database, you pass a connection string containing any + * parameters and options, such as the server address and the database name. + * + * These are identical to the ones in libpq, the C language binding upon which + * libpqxx itself is built: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * There are also environment variables you can set to provide defaults, again + * as defined by libpq: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * You can also create a database connection _asynchronously_ using an + * intermediate @ref pqxx::connecting object. + */ + +namespace pqxx::internal +{ +class sql_cursor; + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: T is a range of pairs of zero-terminated strings. +template +concept ZKey_ZValues = std::ranges::input_range and requires(T t) +{ + {std::cbegin(t)}; + { + std::get<0>(*std::cbegin(t)) + } -> ZString; + { + std::get<1>(*std::cbegin(t)) + } -> ZString; +} and std::tuple_size_v::value_type> +== 2; +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class connection_dbtransaction; +class connection_errorhandler; +class connection_largeobject; +class connection_notification_receiver; +class connection_pipeline; +class connection_sql_cursor; +class connection_stream_from; +class connection_stream_to; +class connection_transaction; +class const_connection_largeobject; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Representation of a PostgreSQL table path. +/** A "table path" consists of a table name, optionally prefixed by a schema + * name, which in turn is optionally prefixed by a database name. + * + * A minimal example of a table path would be `{mytable}`. But a table path + * may also take the forms `{myschema,mytable}` or + * `{mydb,myschema,mytable}`. + */ +using table_path = std::initializer_list; + + +/// Encrypt a password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] std::string + PQXX_LIBEXPORT + encrypt_password(char const user[], char const password[]); + +/// Encrypt password. @deprecated Use connection::encrypt_password instead. +[[nodiscard, + deprecated("Use connection::encrypt_password instead.")]] inline std::string +encrypt_password(zview user, zview password) +{ +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return encrypt_password(user.c_str(), password.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Error verbosity levels. +enum class error_verbosity : int +{ + // These values must match those in libpq's PGVerbosity enum. + terse = 0, + normal = 1, + verbose = 2 +}; + + +/// Connection to a database. +/** This is the first class to look at when you wish to work with a database + * through libpqxx. The connection opens during construction, and closes upon + * destruction. + * + * When creating a connection, you can pass a connection URI or a postgres + * connection string, to specify the database server's address, a login + * username, and so on. If you don't, the connection will try to obtain them + * from certain environment variables. If those are not set either, the + * default is to try and connect to the local system's port 5432. + * + * Find more about connection strings here: + * + * https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + * + * The variables are documented here: + * + * https://www.postgresql.org/docs/current/libpq-envars.html + * + * To query or manipulate the database once connected, use one of the + * transaction classes (see pqxx/transaction_base.hxx) and perhaps also the + * transactor framework (see pqxx/transactor.hxx). + * + * When a connection breaks, you will typically get a @ref broken_connection + * exception. This can happen at almost any point. + * + * @warning On Unix-like systems, including GNU and BSD systems, your program + * may receive the SIGPIPE signal when the connection to the backend breaks. By + * default this signal will abort your program. Use "signal(SIGPIPE, SIG_IGN)" + * if you want your program to continue running after a connection fails. + */ +class PQXX_LIBEXPORT connection +{ +public: + connection() : connection{""} {} + + /// Connect to a database, using `options` string. + explicit connection(char const options[]) + { + check_version(); + init(options); + } + + /// Connect to a database, using `options` string. + explicit connection(zview options) : connection{options.c_str()} + { + // (Delegates to other constructor which calls check_version for us.) + } + + /// Move constructor. + /** Moving a connection is not allowed if it has an open transaction, or has + * error handlers or notification receivers registered on it. In those + * situations, other objects may hold references to the old object which + * would become invalid and might produce hard-to-diagnose bugs. + */ + connection(connection &&rhs); + +#if defined(PQXX_HAVE_CONCEPTS) + /// Connect to a database, passing options as a range of key/value pairs. + /** @warning Experimental. Requires C++20 "concepts" support. Define + * `PQXX_HAVE_CONCEPTS` to enable it. + * + * There's no need to escape the parameter values. + * + * See the PostgreSQL libpq documentation for the full list of possible + * options: + * + * https://postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS + * + * The options can be anything that can be iterated as a series of pairs of + * zero-terminated strings: `std::pair`, or + * `std::tuple`, or + * `std::map`, and so on. + */ + template + inline connection(MAPPING const ¶ms); +#endif // PQXX_HAVE_CONCEPTS + + ~connection() + { + try + { + close(); + } + catch (std::exception const &) + {} + } + + /// Move assignment. + /** Neither connection can have an open transaction, registered error + * handlers, or registered notification receivers. + */ + connection &operator=(connection &&rhs); + + connection(connection const &) = delete; + connection &operator=(connection const &) = delete; + + /// Is this connection open at the moment? + /** @warning This function is **not** needed in most code. Resist the + * temptation to check it after opening a connection. The `connection` + * constructor will throw a @ref broken_connection exception if can't connect + * to the database. + */ + [[nodiscard]] bool PQXX_PURE is_open() const noexcept; + + /// Invoke notice processor function. The message should end in newline. + void process_notice(char const[]) noexcept; + /// Invoke notice processor function. Newline at end is recommended. + /** The zview variant, with a message ending in newline, is the most + * efficient way to call process_notice. + */ + void process_notice(zview) noexcept; + + /// Enable tracing to a given output stream, or nullptr to disable. + void trace(std::FILE *) noexcept; + + /** + * @name Connection properties + * + * These are probably not of great interest, since most are derived from + * information supplied by the client program itself, but they are included + * for completeness. + * + * The connection needs to be currently active for these to work. + */ + //@{ + /// Name of database we're connected to, if any. + [[nodiscard]] char const *dbname() const; + + /// Database user ID we're connected under, if any. + [[nodiscard]] char const *username() const; + + /// Address of server, or nullptr if none specified (i.e. default or local) + [[nodiscard]] char const *hostname() const; + + /// Server port number we're connected to. + [[nodiscard]] char const *port() const; + + /// Process ID for backend process, or 0 if inactive. + [[nodiscard]] int PQXX_PURE backendpid() const &noexcept; + + /// Socket currently used for connection, or -1 for none. Use with care! + /** Query the current socket number. This is intended for event loops based + * on functions such as select() or poll(), where you're waiting for any of + * multiple file descriptors to become ready for communication. + * + * Please try to stay away from this function. It is really only meant for + * event loops that need to wait on more than one file descriptor. If all + * you need is to block until a notification arrives, for instance, use + * await_notification(). If you want to issue queries and retrieve results + * in nonblocking fashion, check out the pipeline class. + */ + [[nodiscard]] int PQXX_PURE sock() const &noexcept; + + /// What version of the PostgreSQL protocol is this connection using? + /** The answer can be 0 (when there is no connection); 3 for protocol 3.0; or + * possibly higher values as newer protocol versions come into use. + */ + [[nodiscard]] int PQXX_PURE protocol_version() const noexcept; + + /// What version of the PostgreSQL server are we connected to? + /** The result is a bit complicated: each of the major, medium, and minor + * release numbers is written as a two-digit decimal number, and the three + * are then concatenated. Thus server version 9.4.2 will be returned as the + * decimal number 90402. If there is no connection to the server, this + * returns zero. + * + * @warning When writing version numbers in your code, don't add zero at the + * beginning! Numbers beginning with zero are interpreted as octal (base-8) + * in C++. Thus, 070402 is not the same as 70402, and 080000 is not a number + * at all because there is no digit "8" in octal notation. Use strictly + * decimal notation when it comes to these version numbers. + */ + [[nodiscard]] int PQXX_PURE server_version() const noexcept; + //@} + + /// @name Text encoding + /** + * Each connection is governed by a "client encoding," which dictates how + * strings and other text is represented in bytes. The database server will + * send text data to you in this encoding, and you should use it for the + * queries and data which you send to the server. + * + * Search the PostgreSQL documentation for "character set encodings" to find + * out more about the available encodings, how to extend them, and how to use + * them. Not all server-side encodings are compatible with all client-side + * encodings or vice versa. + * + * Encoding names are case-insensitive, so e.g. "UTF8" is equivalent to + * "utf8". + * + * You can change the client encoding, but this may not work when the + * connection is in a special state, such as when streaming a table. It's + * not clear what happens if you change the encoding during a transaction, + * and then abort the transaction. + */ + //@{ + /// Get client-side character encoding, by name. + [[nodiscard]] std::string get_client_encoding() const; + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(zview encoding) & + { + set_client_encoding(encoding.c_str()); + } + + /// Set client-side character encoding, by name. + /** + * @param encoding Name of the character set encoding to use. + */ + void set_client_encoding(char const encoding[]) &; + + /// Get the connection's encoding, as a PostgreSQL-defined code. + [[nodiscard]] int PQXX_PRIVATE encoding_id() const; + + //@} + + /// Set session variable, using SQL's `SET` command. + /** @deprecated To set a session variable, use @ref set_session_var. To set + * a transaction-local variable, execute an SQL `SET` command. + * + * @warning When setting a string value, you must escape and quote it first. + * Use the @ref quote() function to do that. + * + * @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + * + * @param var Variable to set. + * @param value New value for Var. This can be any SQL expression. If it's + * a string, be sure that it's properly escaped and quoted. + */ + [[deprecated("To set session variables, use set_session_var.")]] void + set_variable(std::string_view var, std::string_view value) &; + + /// Set one of the session variables to a new value. + /** This executes SQL, so do not do it while a pipeline or stream is active + * on the connection. + * + * The value you set here will last for the rest of the connection's + * duration, or until you set a new value. + * + * If you set the value while in a @ref dbtransaction (i.e. any transaction + * that is not a @ref nontransaction), then rolling back the transaction will + * undo the change. + * + * All applies to setting _session_ variables. You can also set the same + * variables as _local_ variables, in which case they will always revert to + * their previous value when the transaction ends (or when you overwrite them + * of course). To set a local variable, simply execute an SQL statement + * along the lines of "`SET LOCAL var = 'value'`" inside your transaction. + * + * @param var The variable to set. + * @param value The new value for the variable. + * @throw @ref variable_set_to_null if the value is null; this is not + * allowed. + */ + template + void set_session_var(std::string_view var, TYPE const &value) & + { + if constexpr (nullness::has_null) + { + if (nullness::is_null(value)) + throw variable_set_to_null{ + internal::concat("Attempted to set variable ", var, " to null.")}; + } + exec(internal::concat("SET ", quote_name(var), "=", quote(value))); + } + + /// Read session variable, using SQL's `SHOW` command. + /** @warning This executes an SQL query, so do not get or set variables while + * a table stream or pipeline is active on the same connection. + */ + [[deprecated("Use get_var instead.")]] std::string + get_variable(std::string_view); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * @return a blank `std::optional` if the variable's value is null, or its + * string value otherwise. + */ + std::string get_var(std::string_view var); + + /// Read currently applicable value of a variable. + /** This function executes an SQL statement, so it won't work while a + * @ref pipeline or query stream is active on the connection. + * + * If there is any possibility that the variable is null, ensure that `TYPE` + * can represent null values. + */ + template TYPE get_var_as(std::string_view var) + { + return from_string(get_var(var)); + } + + /** + * @name Notifications and Receivers + */ + //@{ + /// Check for pending notifications and take appropriate action. + /** This does not block. To wait for incoming notifications, either call + * await_notification() (it calls this function); or wait for incoming data + * on the connection's socket (i.e. wait to read), and then call this + * function repeatedly until it returns zero. After that, there are no more + * pending notifications so you may want to wait again. + * + * If any notifications are pending when you call this function, it + * processes them by finding any receivers that match the notification string + * and invoking those. If no receivers match, there is nothing to invoke but + * we do consider the notification processed. + * + * If any of the client-registered receivers throws an exception, the + * function will report it using the connection's errorhandlers. It does not + * re-throw the exceptions. + * + * @return Number of notifications processed. + */ + int get_notifs(); + + /// Wait for a notification to come in. + /** There are other events that will also terminate the wait, such as the + * backend failing. It will also wake up periodically. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs() repeatedly until it returns zero. + * + * @return Number of notifications processed. + */ + int await_notification(); + + /// Wait for a notification to come in, or for given timeout to pass. + /** There are other events that will also terminate the wait, such as the + * backend failing, or timeout expiring. + * + * If a notification comes in, the call will process it, along with any other + * notifications that may have been pending. + * + * To wait for notifications into your own event loop instead, wait until + * there is incoming data on the connection's socket to be read, then call + * @ref get_notifs repeatedly until it returns zero. + * + * @return Number of notifications processed + */ + int await_notification(std::time_t seconds, long microseconds); + //@} + + /** + * @name Password encryption + * + * Use this when setting a new password for the user if password encryption + * is enabled. Inputs are the SQL name for the user for whom you with to + * encrypt a password; the plaintext password; and the hash algorithm. + * + * The algorithm must be one of "md5", "scram-sha-256" (introduced in + * PostgreSQL 10), or `nullptr`. If the pointer is null, this will query + * the `password_encryption setting` from the server, and use the default + * algorithm as defined there. + * + * @return encrypted version of the password, suitable for encrypted + * PostgreSQL authentication. + * + * Thus you can change a user's password with: + * ```cxx + * void setpw(transaction_base &t, string const &user, string const &pw) + * { + * t.exec0("ALTER USER " + user + " " + * "PASSWORD '" + t.conn().encrypt_password(user,pw) + "'"); + * } + * ``` + * + * When building this against a libpq older than version 10, this will use + * an older function which only supports md5. In that case, requesting a + * different algorithm than md5 will result in a @ref feature_not_supported + * exception. + */ + //@{ + /// Encrypt a password for a given user. + [[nodiscard]] std::string + encrypt_password(zview user, zview password, zview algorithm) + { + return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str()); + } + /// Encrypt a password for a given user. + [[nodiscard]] std::string encrypt_password( + char const user[], char const password[], char const *algorithm = nullptr); + //@} + + /** + * @name Prepared statements + * + * PostgreSQL supports prepared SQL statements, i.e. statements that you can + * register under a name you choose, optimized once by the backend, and + * executed any number of times under the given name. + * + * Prepared statement definitions are not sensitive to transaction + * boundaries. A statement defined inside a transaction will remain defined + * outside that transaction, even if the transaction itself is subsequently + * aborted. Once a statement has been prepared, it will only go away if you + * close the connection or explicitly "unprepare" the statement. + * + * Use the `pqxx::transaction_base::exec_prepared` functions to execute a + * prepared statement. See @ref prepared for a full discussion. + * + * @warning Using prepared statements can save time, but if your statement + * takes parameters, it may also make your application significantly slower! + * The reason is that the server works out a plan for executing the query + * when you prepare it. At that time, of course it does not know the values + * for the parameters that you will pass. If you execute a query without + * preparing it, then the server works out the plan on the spot, with full + * knowledge of the parameter values. + * + * A statement's definition can refer to its parameters as `$1`, `$2`, etc. + * The first parameter you pass to the call provides a value for `$1`, and + * so on. + * + * Here's an example of how to use prepared statements. + * + * ```cxx + * using namespace pqxx; + * void foo(connection &c) + * { + * c.prepare("findtable", "select * from pg_tables where name=$1"); + * work tx{c}; + * result r = tx.exec_prepared("findtable", "mytable"); + * if (std::empty(r)) throw runtime_error{"mytable not found!"}; + * } + * ``` + */ + //@{ + + /// Define a prepared statement. + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(zview name, zview definition) & + { + prepare(name.c_str(), definition.c_str()); + } + + /** + * @param name unique name for the new prepared statement. + * @param definition SQL statement to prepare. + */ + void prepare(char const name[], char const definition[]) &; + + /// Define a nameless prepared statement. + /** + * This can be useful if you merely want to pass large binary parameters to a + * statement without otherwise wishing to prepare it. If you use this + * feature, always keep the definition and the use close together to avoid + * the nameless statement being redefined unexpectedly by code somewhere + * else. + */ + void prepare(char const definition[]) &; + void prepare(zview definition) & { return prepare(definition.c_str()); } + + /// Drop prepared statement. + void unprepare(std::string_view name); + + //@} + + // C++20: constexpr. Breaks ABI. + /// Suffix unique number to name to make it unique within session context. + /** Used internally to generate identifiers for SQL objects (such as cursors + * and nested transactions) based on a given human-readable base name. + */ + [[nodiscard]] std::string adorn_name(std::string_view); + + /** + * @defgroup escaping-functions String-escaping functions + */ + //@{ + + /// Escape string for use as SQL string literal on this connection. + /** @warning This accepts a length, and it does not require a terminating + * zero byte. But if there is a zero byte, escaping stops there even if + * it's not at the end of the string! + */ + [[deprecated("Use std::string_view or pqxx:zview.")]] std::string + esc(char const text[], std::size_t maxlen) const + { + return esc(std::string_view{text, maxlen}); + } + + /// Escape string for use as SQL string literal on this connection. + [[nodiscard]] std::string esc(char const text[]) const + { + return esc(std::string_view{text}); + } + +#if defined(PQXX_HAVE_SPAN) + /// Escape string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `text`, there must be at least 2 bytes of space in + * `buffer`; plus there must be one byte of space for a trailing zero. + * Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + [[nodiscard]] std::string_view + esc(std::string_view text, std::span buffer) + { + auto const size{std::size(text)}, space{std::size(buffer)}; + auto const needed{2 * size + 1}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + auto const data{buffer.data()}; + return {data, esc_to_buf(text, data)}; + } +#endif + + /// Escape string for use as SQL string literal on this connection. + /** @warning This is meant for text strings only. It cannot contain bytes + * whose value is zero ("nul bytes"). + */ + [[nodiscard]] std::string esc(std::string_view text) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** This is identical to `esc_raw(data)`. */ + template [[nodiscard]] std::string esc(DATA const &data) const + { + return esc_raw(data); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** Use this variant when you want to re-use the same buffer across multiple + * calls. If that's not the case, or convenience and simplicity are more + * important, use the single-argument variant. + * + * For every byte in `data`, there must be at least two bytes of space in + * `buffer`; plus there must be two bytes of space for a header and one for + * a trailing zero. Throws @ref range_error if this space is not available. + * + * Returns a reference to the escaped string, which is actually stored in + * `buffer`. + */ + template + [[nodiscard]] zview esc(DATA const &data, std::span buffer) const + { + auto const size{std::size(data)}, space{std::size(buffer)}; + auto const needed{internal::size_esc_bin(std::size(data))}; + if (space < needed) + throw range_error{internal::concat( + "Not enough room to escape binary string of ", size, " byte(s): need ", + needed, " bytes of buffer space, but buffer size is ", space, ".")}; + + std::basic_string_view view{std::data(data), std::size(data)}; + auto const out{std::data(buffer)}; + // Actually, in the modern format, we know beforehand exactly how many + // bytes we're going to fill. Just leave out the trailing zero. + internal::esc_bin(view, out); + return zview{out, needed - 1}; + } +#endif + + /// Escape binary string for use as SQL string literal on this connection. + [[deprecated("Use std::byte for binary data.")]] std::string + esc_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string esc_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + /** You can also just use @ref esc with a binary string. */ + [[nodiscard]] std::string + esc_raw(std::basic_string_view, std::span buffer) const; +#endif + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape binary string for use as SQL string literal on this connection. + /** You can also just use @ref esc with a binary string. */ + template + [[nodiscard]] std::string esc_raw(DATA const &data) const + { + return esc_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + +#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN) + /// Escape binary string for use as SQL string literal, into `buffer`. + template + [[nodiscard]] zview esc_raw(DATA const &data, std::span buffer) const + { + return this->esc(binary_cast(data), buffer); + } +#endif + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return unesc_raw(text.c_str()); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const text[]) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + * + * (The data must be encoded in PostgreSQL's "hex" format. The legacy + * "bytea" escape format, used prior to PostgreSQL 9.0, is no longer + * supported.) + */ + [[nodiscard]] std::basic_string + unesc_bin(std::string_view text) const + { + std::basic_string buf; + buf.resize(pqxx::internal::size_unesc_bin(std::size(text))); + pqxx::internal::unesc_bin(text, buf.data()); + return buf; + } + + /// Escape and quote a string of binary data. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const; + + /// Escape and quote a string of binary data. + std::string quote_raw(std::basic_string_view) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Escape and quote a string of binary data. + /** You can also just use @ref quote with binary data. */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return quote_raw( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table name. + /** When passing just a table name, this is just another name for + * @ref quote_name. + */ + [[nodiscard]] std::string quote_table(std::string_view name) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote a table path. + /** A table path consists of a table name, optionally prefixed by a schema + * name; and if both are given, they are in turn optionally prefixed by a + * database name. + * + * Each portion of the path (database name, schema name, table name) will be + * quoted separately, and they will be joined together by dots. So for + * example, `myschema.mytable` will become `"myschema"."mytable"`. + */ + [[nodiscard]] std::string quote_table(table_path) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Quote and comma-separate a series of column names. + /** Use this to save a bit of work in cases where you repeatedly need to pass + * the same list of column names, e.g. with @ref stream_to and @ref + * stream_from. Some functions that need to quote the columns list + * internally, will have a "raw" alternative which let you do the quoting + * yourself. It's a bit of extra work, but it can in rare cases let you + * eliminate some duplicate work in quoting them repeatedly. + */ + template + inline std::string quote_columns(STRINGS const &columns) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Represent object as SQL string, including quoting & escaping. + /** + * Recognises nulls and represents them as SQL nulls. They get no quotes. + */ + template + [[nodiscard]] inline std::string quote(T const &t) const; + + [[deprecated("Use std::byte for binary data.")]] std::string + quote(binarystring const &) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape and quote binary data for use as a BYTEA value in SQL statement. + [[nodiscard]] std::string + quote(std::basic_string_view bytes) const; + + // TODO: Make "into buffer" variant to eliminate a string allocation. + /// Escape string for literal LIKE match. + /** Use this when part of an SQL "LIKE" pattern should match only as a + * literal string, not as a pattern, even if it contains "%" or "_" + * characters that would normally act as wildcards. + * + * The string does not get string-escaped or quoted. You do that later. + * + * For instance, let's say you have a string `name` entered by the user, + * and you're searching a `file` column for items that match `name` + * followed by a dot and three letters. Even if `name` contains wildcard + * characters "%" or "_", you only want those to match literally, so "_" + * only matches "_" and "%" only matches a single "%". + * + * You do that by "like-escaping" `name`, appending the wildcard pattern + * `".___"`, and finally, escaping and quoting the result for inclusion in + * your query: + * + * ```cxx + * tx.exec( + * "SELECT file FROM item WHERE file LIKE " + + * tx.quote(tx.esc_like(name) + ".___")); + * ``` + * + * The SQL "LIKE" operator also lets you choose your own escape character. + * This is supported, but must be a single-byte character. + */ + [[nodiscard]] std::string + esc_like(std::string_view text, char escape_char = '\\') const; + //@} + + /// Attempt to cancel the ongoing query, if any. + /** You can use this from another thread, and/or while a query is executing + * in a pipeline, but it's up to you to ensure that you're not canceling the + * wrong query. This may involve locking. + */ + void cancel_query(); + +#if defined(_WIN32) || __has_include() + /// Set socket to blocking (true) or nonblocking (false). + /** @warning Do not use this unless you _really_ know what you're doing. + * @warning This function is available on most systems, but not necessarily + * all. + */ + void set_blocking(bool block) &; +#endif // defined(_WIN32) || __has_include() + + /// Set session verbosity. + /** Set the verbosity of error messages to "terse", "normal" (the default), + * or "verbose." + * + * If "terse", returned messages include severity, primary text, and + * position only; this will normally fit on a single line. "normal" produces + * messages that include the above plus any detail, hint, or context fields + * (these might span multiple lines). "verbose" includes all available + * fields. + */ + void set_verbosity(error_verbosity verbosity) &noexcept; + + /// Return pointers to the active errorhandlers. + /** The entries are ordered from oldest to newest handler. + * + * You may use this to find errorhandlers that your application wants to + * delete when destroying the connection. Be aware, however, that libpqxx + * may also add errorhandlers of its own, and those will be included in the + * list. If this is a problem for you, derive your errorhandlers from a + * custom base class derived from pqxx::errorhandler. Then use dynamic_cast + * to find which of the error handlers are yours. + * + * The pointers point to the real errorhandlers. The container it returns + * however is a copy of the one internal to the connection, not a reference. + */ + [[nodiscard]] std::vector get_errorhandlers() const; + + /// Return a connection string encapsulating this connection's options. + /** The connection must be currently open for this to work. + * + * Returns a reconstruction of this connection's connection string. It may + * not exactly match the connection string you passed in when creating this + * connection. + */ + [[nodiscard]] std::string connection_string() const; + + /// Explicitly close the connection. + /** The destructor will do this for you automatically. Still, there is a + * reason to `close()` objects explicitly where possible: if an error should + * occur while closing, `close()` can throw an exception. A destructor + * cannot. + * + * Closing a connection is idempotent. Closing a connection that's already + * closed does nothing. + */ + void close(); + + /// Seize control of a raw libpq connection. + /** @warning Do not do this. Please. It's for very rare, very specific + * use-cases. The mechanism may change (or break) in unexpected ways in + * future versions. + * + * @param raw_conn a raw libpq `PQconn` pointer. + */ + static connection seize_raw_connection(internal::pq::PGconn *raw_conn) + { + return connection{raw_conn}; + } + + /// Release the raw connection without closing it. + /** @warning Do not do this. It's for very rare, very specific use-cases. + * The mechanism may change (or break) in unexpected ways in future versions. + * + * The `connection` object becomes unusable after this. + */ + internal::pq::PGconn *release_raw_connection() && + { + return std::exchange(m_conn, nullptr); + } + +private: + friend class connecting; + enum connect_mode + { + connect_nonblocking + }; + connection(connect_mode, zview connection_string); + + /// For use by @ref seize_raw_connection. + explicit connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} {} + + /// Poll for ongoing connection, try to progress towards completion. + /** Returns a pair of "now please wait to read data from socket" and "now + * please wait to write data to socket." Both will be false when done. + * + * Throws an exception if polling indicates that the connection has failed. + */ + std::pair poll_connect(); + + // Initialise based on connection string. + void init(char const options[]); + // Initialise based on parameter names and values. + void init(char const *params[], char const *values[]); + void complete_init(); + + result make_result( + internal::pq::PGresult *pgr, std::shared_ptr const &query, + std::string_view desc = ""sv); + + void PQXX_PRIVATE set_up_state(); + + int PQXX_PRIVATE PQXX_PURE status() const noexcept; + + /// Escape a string, into a buffer allocated by the caller. + /** The buffer must have room for at least `2*std::size(text) + 1` bytes. + * + * Returns the number of bytes written, including the trailing zero. + */ + std::size_t esc_to_buf(std::string_view text, char *buf) const; + + friend class internal::gate::const_connection_largeobject; + char const *PQXX_PURE err_msg() const noexcept; + + void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept; + + result exec_prepared(std::string_view statement, internal::c_params const &); + + /// Throw @ref usage_error if this connection is not in a movable state. + void check_movable() const; + /// Throw @ref usage_error if not in a state where it can be move-assigned. + void check_overwritable() const; + + friend class internal::gate::connection_errorhandler; + void PQXX_PRIVATE register_errorhandler(errorhandler *); + void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept; + + friend class internal::gate::connection_transaction; + result exec(std::string_view, std::string_view = ""sv); + result + PQXX_PRIVATE exec(std::shared_ptr, std::string_view = ""sv); + void PQXX_PRIVATE register_transaction(transaction_base *); + void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept; + + friend class internal::gate::connection_stream_from; + std::pair>, std::size_t> + PQXX_PRIVATE read_copy_line(); + + friend class internal::gate::connection_stream_to; + void PQXX_PRIVATE write_copy_line(std::string_view); + void PQXX_PRIVATE end_copy_write(); + + friend class internal::gate::connection_largeobject; + internal::pq::PGconn *raw_connection() const { return m_conn; } + + friend class internal::gate::connection_notification_receiver; + void add_receiver(notification_receiver *); + void remove_receiver(notification_receiver *) noexcept; + + friend class internal::gate::connection_pipeline; + void PQXX_PRIVATE start_exec(char const query[]); + bool PQXX_PRIVATE consume_input() noexcept; + bool PQXX_PRIVATE is_busy() const noexcept; + internal::pq::PGresult *get_result(); + + friend class internal::gate::connection_dbtransaction; + friend class internal::gate::connection_sql_cursor; + + result exec_params(std::string_view query, internal::c_params const &args); + + /// Connection handle. + internal::pq::PGconn *m_conn = nullptr; + + /// Active transaction on connection, if any. + /** We don't use this for anything, except to check for open transactions + * when we close the connection or start a new transaction. + * + * We also don't allow move construction or move assignment while there's a + * transaction, since moving the connection in that case would leave one or + * more pointers back from the transaction to the connection dangling. + */ + transaction_base const *m_trans = nullptr; + + std::list m_errorhandlers; + + using receiver_list = + std::multimap; + /// Notification receivers. + receiver_list m_receivers; + + /// Unique number to use as suffix for identifiers (see adorn_name()). + int m_unique_id = 0; +}; + + +/// @deprecated Old base class for connection. They are now the same class. +using connection_base = connection; + + +/// An ongoing, non-blocking stepping stone to a connection. +/** Use this when you want to create a connection to the database, but without + * blocking your whole thread. It is only available on systems that have + * the `` header, and Windows. + * + * Connecting in this way is probably not "faster" (it's more complicated and + * has some extra overhead), but in some situations you can use it to make your + * application as a whole faster. It all depends on having other useful work + * to do in the same thread, and being able to wait on a socket. If you have + * other I/O going on at the same time, your event loop can wait for both the + * libpqxx socket and your own sockets, and wake up whenever any of them is + * ready to do work. + * + * Connecting in this way is not properly "asynchronous;" it's merely + * "nonblocking." This means it's not a super-high-performance mechanism like + * you might get with e.g. `io_uring`. In particular, if we need to look up + * the database hostname in DNS, that will happen synchronously. + * + * To use this, create the `connecting` object, passing a connection string. + * Then loop: If @ref wait_to_read returns true, wait for the socket to have + * incoming data on it. If @ref wait_to_write returns true, wait for the + * socket to be ready for writing. Then call @ref process to process any + * incoming or outgoing data. Do all of this until @ref done returns true (or + * there is an exception). Finally, call @ref produce to get the completed + * connection. + * + * For example: + * + * ```cxx + * pqxx::connecting cg{}; + * + * // Loop until we're done connecting. + * while (!cg.done()) + * { + * wait_for_fd(cg.sock(), cg.wait_to_read(), cg.wait_to_write()); + * cg.process(); + * } + * + * pqxx::connection conn = std::move(cg).produce(); + * + * // At this point, conn is a working connection. You can no longer use + * // cg at all. + * ``` + */ +class PQXX_LIBEXPORT connecting +{ +public: + /// Start connecting. + connecting(zview connection_string = ""_zv); + + connecting(connecting const &) = delete; + connecting(connecting &&) = default; + connecting &operator=(connecting const &) = delete; + connecting &operator=(connecting &&) = default; + + /// Get the socket. The socket may change during the connection process. + [[nodiscard]] int sock() const &noexcept { return m_conn.sock(); } + + /// Should we currently wait to be able to _read_ from the socket? + [[nodiscard]] constexpr bool wait_to_read() const &noexcept + { + return m_reading; + } + + /// Should we currently wait to be able to _write_ to the socket? + [[nodiscard]] constexpr bool wait_to_write() const &noexcept + { + return m_writing; + } + + /// Progress towards completion (but don't block). + void process() &; + + /// Is our connection finished? + [[nodiscard]] constexpr bool done() const &noexcept + { + return not m_reading and not m_writing; + } + + /// Produce the completed connection object. + /** Use this only once, after @ref done returned `true`. Once you have + * called this, the `connecting` instance has no more use or meaning. You + * can't call any of its member functions afterwards. + * + * This member function is rvalue-qualified, meaning that you can only call + * it on an rvalue instance of the class. If what you have is not an rvalue, + * turn it into one by wrapping it in `std::move()`. + */ + [[nodiscard]] connection produce() &&; + +private: + connection m_conn; + bool m_reading{false}; + bool m_writing{true}; +}; + + +template inline std::string connection::quote(T const &t) const +{ + if constexpr (nullness::always_null) + { + return "NULL"; + } + else + { + if (is_null(t)) + return "NULL"; + auto const text{to_string(t)}; + + // Okay, there's an easy way to do this and there's a hard way. The easy + // way was "quote, esc(to_string(t)), quote". I'm going with the hard way + // because it's going to save some string manipulation that will probably + // incur some unnecessary memory allocations and deallocations. + std::string buf{'\''}; + buf.resize(2 + 2 * std::size(text) + 1); + auto const content_bytes{esc_to_buf(text, buf.data() + 1)}; + auto const closing_quote{1 + content_bytes}; + buf[closing_quote] = '\''; + auto const end{closing_quote + 1}; + buf.resize(end); + return buf; + } +} + + +template +inline std::string connection::quote_columns(STRINGS const &columns) const +{ + return separated_list( + ","sv, std::cbegin(columns), std::cend(columns), + [this](auto col) { return this->quote_name(*col); }); +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +inline connection::connection(MAPPING const ¶ms) +{ + check_version(); + + std::vector keys, values; + if constexpr (std::ranges::sized_range) + { + auto const size{std::ranges::size(params) + 1}; + keys.reserve(size); + values.reserve(size); + } + for (auto const &[key, value] : params) + { + keys.push_back(internal::as_c_string(key)); + values.push_back(internal::as_c_string(value)); + } + keys.push_back(nullptr); + values.push_back(nullptr); + init(std::data(keys), std::data(values)); +} +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor new file mode 100644 index 0000000..e20b3a4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor @@ -0,0 +1,8 @@ +/** Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor.hxx new file mode 100644 index 0000000..b392e24 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/cursor.hxx @@ -0,0 +1,483 @@ +/* Definition of the iterator/container-style cursor classes. + * + * C++-style wrappers for SQL cursors. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_CURSOR +#define PQXX_H_CURSOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/result.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Common definitions for cursor types +/** In C++ terms, fetches are always done in pre-increment or pre-decrement + * fashion--i.e. the result does not include the row the cursor is on at the + * beginning of the fetch, and the cursor ends up being positioned on the last + * row in the result. + * + * There are singular positions akin to `end()` at both the beginning and the + * end of the cursor's range of movement, although these fit in so naturally + * with the semantics that one rarely notices them. The cursor begins at the + * first of these, but any fetch in the forward direction will move the cursor + * off this position and onto the first row before returning anything. + */ +class PQXX_LIBEXPORT cursor_base +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Cursor access-pattern policy + /** Allowing a cursor to move forward only can result in better performance, + * so use this access policy whenever possible. + */ + enum access_policy + { + /// Cursor can move forward only + forward_only, + /// Cursor can move back and forth + random_access + }; + + /// Cursor update policy + /** + * @warning Not all PostgreSQL versions support updatable cursors. + */ + enum update_policy + { + /// Cursor can be used to read data but not to write + read_only, + /// Cursor can be used to update data as well as read it + update + }; + + /// Cursor destruction policy + /** The normal thing to do is to make a cursor object the owner of the SQL + * cursor it represents. There may be cases, however, where a cursor needs + * to persist beyond the end of the current transaction (and thus also beyond + * the lifetime of the cursor object that created it!), where it can be + * "adopted" into a new cursor object. See the basic_cursor documentation + * for an explanation of cursor adoption. + * + * If a cursor is created with "loose" ownership policy, the object + * representing the underlying SQL cursor will not take the latter with it + * when its own lifetime ends, nor will its originating transaction. + * + * @warning Use this feature with care and moderation. Only one cursor + * object should be responsible for any one underlying SQL cursor at any + * given time. + */ + enum ownership_policy + { + /// Destroy SQL cursor when cursor object is closed at end of transaction + owned, + /// Leave SQL cursor in existence after close of object and transaction + loose + }; + + cursor_base() = delete; + cursor_base(cursor_base const &) = delete; + cursor_base &operator=(cursor_base const &) = delete; + + /** + * @name Special movement distances. + */ + //@{ + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read until end. + /** @return Maximum value for result::difference_type, so the cursor will + * attempt to read the largest possible result set. + */ + [[nodiscard]] static difference_type all() noexcept; + + /// Special value: read one row only. + /** @return Unsurprisingly, 1. + */ + [[nodiscard]] static constexpr difference_type next() noexcept { return 1; } + + /// Special value: read backwards, one row only. + /** @return Unsurprisingly, -1. + */ + [[nodiscard]] static constexpr difference_type prior() noexcept + { + return -1; + } + + // TODO: Make constexpr inline (but breaks ABI). + /// Special value: read backwards from current position back to origin. + /** @return Minimum value for result::difference_type. + */ + [[nodiscard]] static difference_type backward_all() noexcept; + + //@} + + /// Name of underlying SQL cursor + /** + * @returns Name of SQL cursor, which may differ from original given name. + * @warning Don't use this to access the SQL cursor directly without going + * through the provided wrapper classes! + */ + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_name; + } + +protected: + cursor_base(connection &, std::string_view Name, bool embellish_name = true); + + std::string const m_name; +}; +} // namespace pqxx + + +#include + + +namespace pqxx +{ +/// "Stateless cursor" class: easy API for retrieving parts of result sets +/** This is a front-end for SQL cursors, but with a more C++-like API. + * + * Actually, stateless_cursor feels entirely different from SQL cursors. You + * don't keep track of positions, fetches, and moves; you just say which rows + * you want. See the retrieve() member function. + */ +template +class stateless_cursor +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + + /// Create cursor. + /** + * @param tx The transaction within which you want to create the cursor. + * @param query The SQL query whose results the cursor should traverse. + * @param cname A hint for the cursor's name. The actual SQL cursor's name + * will be based on this (though not necessarily identical). + * @param hold Create a `WITH HOLD` cursor? Such cursors stay alive after + * the transaction has ended, so you can continue to use it. + */ + stateless_cursor( + transaction_base &tx, std::string_view query, std::string_view cname, + bool hold) : + m_cur{tx, query, cname, cursor_base::random_access, up, op, hold} + {} + + /// Adopt an existing scrolling SQL cursor. + /** This lets you define a cursor yourself, and then wrap it in a + * libpqxx-managed `stateless_cursor` object. + * + * @param tx The transaction within which you want to manage the cursor. + * @param adopted_cursor Your cursor's SQL name. + */ + stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) : + m_cur{tx, adopted_cursor, op} + { + // Put cursor in known position + m_cur.move(cursor_base::backward_all()); + } + + /// Close this cursor. + /** The destructor will do this for you automatically. + * + * Closing a cursor is idempotent. Closing a cursor that's already closed + * does nothing. + */ + void close() noexcept { m_cur.close(); } + + /// Number of rows in cursor's result set + /** @note This function is not const; it may need to scroll to find the size + * of the result set. + */ + [[nodiscard]] size_type size() + { + return internal::obtain_stateless_cursor_size(m_cur); + } + + /// Retrieve rows from begin_pos (inclusive) to end_pos (exclusive) + /** Rows are numbered starting from 0 to size()-1. + * + * @param begin_pos First row to retrieve. May be one row beyond the end of + * the result set, to avoid errors for empty result sets. Otherwise, must be + * a valid row number in the result set. + * @param end_pos Row up to which to fetch. Rows are returned ordered from + * begin_pos to end_pos, i.e. in ascending order if begin_pos < end_pos but + * in descending order if begin_pos > end_pos. The end_pos may be + * arbitrarily inside or outside the result set; only existing rows are + * included in the result. + */ + result retrieve(difference_type begin_pos, difference_type end_pos) + { + return internal::stateless_cursor_retrieve( + m_cur, result::difference_type(size()), begin_pos, end_pos); + } + + /// Return this cursor's name. + [[nodiscard]] constexpr std::string const &name() const noexcept + { + return m_cur.name(); + } + +private: + internal::sql_cursor m_cur; +}; + + +class icursor_iterator; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class icursor_iterator_icursorstream; +class icursorstream_icursor_iterator; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Simple read-only cursor represented as a stream of results +/** SQL cursors can be tricky, especially in C++ since the two languages seem + * to have been designed on different planets. An SQL cursor has two singular + * positions akin to `end()` on either side of the underlying result set. + * + * These cultural differences are hidden from view somewhat by libpqxx, which + * tries to make SQL cursors behave more like familiar C++ entities such as + * iterators, sequences, streams, and containers. + * + * Data is fetched from the cursor as a sequence of result objects. Each of + * these will contain the number of rows defined as the stream's stride, except + * of course the last block of data which may contain fewer rows. + * + * This class can create or adopt cursors that live outside any backend + * transaction, which your backend version may not support. + */ +class PQXX_LIBEXPORT icursorstream +{ +public: + using size_type = cursor_base::size_type; + using difference_type = cursor_base::difference_type; + + /// Set up a read-only, forward-only cursor. + /** Roughly equivalent to a C++ Standard Library istream, this cursor type + * supports only two operations: reading a block of rows while moving + * forward, and moving forward without reading any data. + * + * @param context Transaction context in which this cursor will be active. + * @param query SQL query whose results this cursor shall iterate. + * @param basename Suggested name for the SQL cursor; the library will append + * a unique code to ensure its uniqueness. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + */ + icursorstream( + transaction_base &context, std::string_view query, + std::string_view basename, difference_type sstride = 1); + + /// Adopt existing SQL cursor. Use with care. + /** Forms a cursor stream around an existing SQL cursor, as returned by e.g. + * a server-side function. The SQL cursor will be cleaned up by the stream's + * destructor as if it had been created by the stream; cleaning it up by hand + * or adopting the same cursor twice is an error. + * + * Passing the name of the cursor as a string is not allowed, both to avoid + * confusion with the other constructor and to discourage unnecessary use of + * adopted cursors. + * + * @warning It is technically possible to adopt a "WITH HOLD" cursor, i.e. a + * cursor that stays alive outside its creating transaction. However, any + * cursor stream (including the underlying SQL cursor, naturally) must be + * destroyed before its transaction context object is destroyed. Therefore + * the only way to use SQL's WITH HOLD feature is to adopt the cursor, but + * defer doing so until after entering the transaction context that will + * eventually destroy it. + * + * @param context Transaction context in which this cursor will be active. + * @param cname Result field containing the name of the SQL cursor to adopt. + * @param sstride Number of rows to fetch per read operation; must be a + * positive number. + * @param op Ownership policy. Determines whether the cursor underlying this + * stream will be destroyed when the stream is closed. + */ + icursorstream( + transaction_base &context, field const &cname, difference_type sstride = 1, + cursor_base::ownership_policy op = cursor_base::owned); + + /// Return `true` if this stream may still return more data. + constexpr operator bool() const &noexcept { return not m_done; } + + /// Read new value into given result object; same as operator `>>`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C.get(r1).get(r2);") + */ + icursorstream &get(result &res) + { + res = fetchblock(); + return *this; + } + /// Read new value into given result object; same as `get(result&)`. + /** The result set may continue any number of rows from zero to the chosen + * stride, inclusive. An empty result will only be returned if there are no + * more rows to retrieve. + * + * @param res Write the retrieved data into this result object. + * @return Reference to this very stream, to facilitate "chained" invocations + * ("C >> r1 >> r2;") + */ + icursorstream &operator>>(result &res) { return get(res); } + + /// Move given number of rows forward without reading data. + /** Ignores any stride that you may have set. It moves by a given number of + * rows, not a number of strides. + * + * @return Reference to this stream itself, to facilitate "chained" + * invocations. + */ + icursorstream &ignore(std::streamsize n = 1) &; + + /// Change stride, i.e. the number of rows to fetch per read operation. + /** + * @param stride Must be a positive number. + */ + void set_stride(difference_type stride) &; + [[nodiscard]] constexpr difference_type stride() const noexcept + { + return m_stride; + } + +private: + result fetchblock(); + + friend class internal::gate::icursorstream_icursor_iterator; + size_type forward(size_type n = 1); + void insert_iterator(icursor_iterator *) noexcept; + void remove_iterator(icursor_iterator *) const noexcept; + + void service_iterators(difference_type); + + internal::sql_cursor m_cur; + + difference_type m_stride; + difference_type m_realpos, m_reqpos; + + mutable icursor_iterator *m_iterators; + + bool m_done; +}; + + +/// Approximate istream_iterator for icursorstream. +/** Intended as an implementation of an input_iterator (as defined by the C++ + * Standard Library), this class supports only two basic operations: reading + * the current element, and moving forward. In addition to the minimal + * guarantees for istream_iterators, this class supports multiple successive + * reads of the same position (the current result set is cached in the + * iterator) even after copying and even after new data have been read from the + * stream. This appears to be a requirement for input_iterators. Comparisons + * are also supported in the general case. + * + * The iterator does not care about its own position, however. Moving an + * iterator forward moves the underlying stream forward and reads the data from + * the new stream position, regardless of the iterator's old position in the + * stream. + * + * The stream's stride defines the granularity for all iterator movement or + * access operations, i.e. "ici += 1" advances the stream by one stride's worth + * of rows, and "*ici++" reads one stride's worth of rows from the stream. + * + * @warning Do not read from the underlying stream or its cursor, move its read + * position, or change its stride, between the time the first icursor_iterator + * on it is created and the time its last icursor_iterator is destroyed. + * + * @warning Manipulating these iterators within the context of a single cursor + * stream is not thread-safe. Creating a new iterator, copying one, + * or destroying one affects the stream as a whole. + */ +class PQXX_LIBEXPORT icursor_iterator +{ +public: + using iterator_category = std::input_iterator_tag; + using value_type = result; + using pointer = result const *; + using reference = result const &; + using istream_type = icursorstream; + using size_type = istream_type::size_type; + using difference_type = istream_type::difference_type; + + icursor_iterator() noexcept; + explicit icursor_iterator(istream_type &) noexcept; + icursor_iterator(icursor_iterator const &) noexcept; + ~icursor_iterator() noexcept; + + result const &operator*() const + { + refresh(); + return m_here; + } + result const *operator->() const + { + refresh(); + return &m_here; + } + icursor_iterator &operator++(); + icursor_iterator operator++(int); + icursor_iterator &operator+=(difference_type); + icursor_iterator &operator=(icursor_iterator const &) noexcept; + + [[nodiscard]] bool operator==(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + [[nodiscard]] bool operator<(icursor_iterator const &rhs) const; + [[nodiscard]] bool operator>(icursor_iterator const &rhs) const + { + return rhs < *this; + } + [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const + { + return not(*this > rhs); + } + [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const + { + return not(*this < rhs); + } + +private: + void refresh() const; + + friend class internal::gate::icursor_iterator_icursorstream; + difference_type pos() const noexcept { return m_pos; } + void fill(result const &); + + icursorstream *m_stream{nullptr}; + result m_here; + difference_type m_pos; + icursor_iterator *m_prev{nullptr}, *m_next{nullptr}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction new file mode 100644 index 0000000..fa8d264 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction @@ -0,0 +1,8 @@ +/** pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/dbtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction.hxx new file mode 100644 index 0000000..d85cb17 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/dbtransaction.hxx @@ -0,0 +1,70 @@ +/* Definition of the pqxx::dbtransaction abstract base class. + * + * pqxx::dbransaction defines a real transaction on the database. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/dbtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_DBTRANSACTION +#define PQXX_H_DBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/transaction_base.hxx" + +namespace pqxx +{ +/// Abstract transaction base class: bracket transactions on the database. +/** + * @ingroup transactions + * + * Use a dbtransaction-derived object such as "work" (transaction<>) to enclose + * operations on a database in a single "unit of work." This ensures that the + * whole series of operations either succeeds as a whole or fails completely. + * In no case will it leave half-finished work behind in the database. + * + * Once processing on a transaction has succeeded and any changes should be + * allowed to become permanent in the database, call commit(). If something + * has gone wrong and the changes should be forgotten, call abort() instead. + * If you do neither, an implicit abort() is executed at destruction time. + * + * It is an error to abort a transaction that has already been committed, or to + * commit a transaction that has already been aborted. Aborting an already + * aborted transaction or committing an already committed one is allowed, to + * make error handling easier. Repeated aborts or commits have no effect after + * the first one. + * + * Database transactions are not suitable for guarding long-running processes. + * If your transaction code becomes too long or too complex, consider ways to + * break it up into smaller ones. Unfortunately there is no universal recipe + * for this. + * + * The actual operations for committing/aborting the backend transaction are + * implemented by a derived class. The implementing concrete class must also + * call @ref close from its destructor. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE dbtransaction : public transaction_base +{ +protected: + /// Begin transaction. + explicit dbtransaction(connection &c) : transaction_base{c} {} + /// Begin transaction. + dbtransaction(connection &c, std::string_view tname) : + transaction_base{c, tname} + {} + /// Begin transaction. + dbtransaction( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + transaction_base{c, tname, rollback_cmd} + {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler new file mode 100644 index 0000000..ea572ee --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler @@ -0,0 +1,8 @@ +/** pqxx::errorhandler class. + * + * Callbacks for handling errors and warnings. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler.hxx new file mode 100644 index 0000000..2ffb570 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/errorhandler.hxx @@ -0,0 +1,92 @@ +/* Definition of the pqxx::errorhandler class. + * + * pqxx::errorhandler handlers errors and warnings in a database session. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/errorhandler instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ERRORHANDLER +#define PQXX_H_ERRORHANDLER + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/types.hxx" + + +namespace pqxx::internal::gate +{ +class errorhandler_connection; +} + + +namespace pqxx +{ +/** + * @addtogroup errorhandler + */ +//@{ + +/// Base class for error-handler callbacks. +/** To receive errors and warnings from a connection, subclass this with your + * own error-handler functor, and instantiate it for the connection. Destroying + * the handler un-registers it. + * + * A connection can have multiple error handlers at the same time. When the + * database connection emits an error or warning message, it passes the message + * to each error handler, starting with the most recently registered one and + * progressing towards the oldest one. However an error handler may also + * instruct the connection not to pass the message to further handlers by + * returning "false." + * + * @warning Strange things happen when a result object outlives its parent + * connection. If you register an error handler on a connection, then you must + * not access the result after destroying the connection. This applies even if + * you destroy the error handler first! + */ +class PQXX_LIBEXPORT errorhandler +{ +public: + explicit errorhandler(connection &); + virtual ~errorhandler(); + + /// Define in subclass: receive an error or warning message from the + /// database. + /** + * @return Whether the same error message should also be passed to the + * remaining, older errorhandlers. + */ + virtual bool operator()(char const msg[]) noexcept = 0; + + errorhandler() = delete; + errorhandler(errorhandler const &) = delete; + errorhandler &operator=(errorhandler const &) = delete; + +private: + connection *m_home; + + friend class internal::gate::errorhandler_connection; + void unregister() noexcept; +}; + + +/// An error handler that suppresses any previously registered error handlers. +class quiet_errorhandler : public errorhandler +{ +public: + /// Suppress error notices. + quiet_errorhandler(connection &conn) : errorhandler{conn} {} + + /// Revert to previous handling of error notices. + virtual bool operator()(char const[]) noexcept override { return false; } +}; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except new file mode 100644 index 0000000..e5dd508 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except @@ -0,0 +1,8 @@ +/** libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except.hxx new file mode 100644 index 0000000..24f9594 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/except.hxx @@ -0,0 +1,447 @@ +/* Definition of libpqxx exception classes. + * + * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ... + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/except instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_EXCEPT +#define PQXX_H_EXCEPT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + + +namespace pqxx +{ +/** + * @addtogroup exception Exception classes + * + * These exception classes follow, roughly, the two-level hierarchy defined by + * the PostgreSQL SQLSTATE error codes (see Appendix A of the PostgreSQL + * documentation corresponding to your server version). This is not a complete + * mapping though. There are other differences as well, e.g. the error code + * for `statement_completion_unknown` has a separate status in libpqxx as + * @ref in_doubt_error, and `too_many_connections` is classified as a + * `broken_connection` rather than a subtype of `insufficient_resources`. + * + * @see http://www.postgresql.org/docs/9.4/interactive/errcodes-appendix.html + * + * @{ + */ + +/// Run-time failure encountered by libpqxx, similar to std::runtime_error. +struct PQXX_LIBEXPORT failure : std::runtime_error +{ + explicit failure(std::string const &); +}; + + +/// Exception class for lost or failed backend connection. +/** + * @warning When this happens on Unix-like systems, you may also get a SIGPIPE + * signal. That signal aborts the program by default, so if you wish to be + * able to continue after a connection breaks, be sure to disarm this signal. + * + * If you're working on a Unix-like system, see the manual page for + * `signal` (2) on how to deal with SIGPIPE. The easiest way to make this + * signal harmless is to make your program ignore it: + * + * ```cxx + * #include + * + * int main() + * { + * signal(SIGPIPE, SIG_IGN); + * // ... + * ``` + */ +struct PQXX_LIBEXPORT broken_connection : failure +{ + broken_connection(); + explicit broken_connection(std::string const &); +}; + + +/// The caller attempted to set a variable to null, which is not allowed. +struct PQXX_LIBEXPORT variable_set_to_null : failure +{ + variable_set_to_null(); + explicit variable_set_to_null(std::string const &); +}; + + +/// Exception class for failed queries. +/** Carries, in addition to a regular error message, a copy of the failed query + * and (if available) the SQLSTATE value accompanying the error. + */ +class PQXX_LIBEXPORT sql_error : public failure +{ + /// Query string. Empty if unknown. + std::string const m_query; + /// SQLSTATE string describing the error type, if known; or empty string. + std::string const m_sqlstate; + +public: + explicit sql_error( + std::string const &whatarg = "", std::string const &Q = "", + char const sqlstate[] = nullptr); + virtual ~sql_error() noexcept override; + + /// The query whose execution triggered the exception + [[nodiscard]] PQXX_PURE std::string const &query() const noexcept; + + /// SQLSTATE error code if known, or empty string otherwise. + [[nodiscard]] PQXX_PURE std::string const &sqlstate() const noexcept; +}; + + +/// "Help, I don't know whether transaction was committed successfully!" +/** Exception that might be thrown in rare cases where the connection to the + * database is lost while finishing a database transaction, and there's no way + * of telling whether it was actually executed by the backend. In this case + * the database is left in an indeterminate (but consistent) state, and only + * manual inspection will tell which is the case. + */ +struct PQXX_LIBEXPORT in_doubt_error : failure +{ + explicit in_doubt_error(std::string const &); +}; + + +/// The backend saw itself forced to roll back the ongoing transaction. +struct PQXX_LIBEXPORT transaction_rollback : sql_error +{ + explicit transaction_rollback( + std::string const &whatarg, std::string const &q = "", + char const sqlstate[] = nullptr); +}; + + +/// Transaction failed to serialize. Please retry it. +/** Can only happen at transaction isolation levels REPEATABLE READ and + * SERIALIZABLE. + * + * The current transaction cannot be committed without violating the guarantees + * made by its isolation level. This is the effect of a conflict with another + * ongoing transaction. The transaction may still succeed if you try to + * perform it again. + */ +struct PQXX_LIBEXPORT serialization_failure : transaction_rollback +{ + explicit serialization_failure( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// We can't tell whether our last statement succeeded. +struct PQXX_LIBEXPORT statement_completion_unknown : transaction_rollback +{ + explicit statement_completion_unknown( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// The ongoing transaction has deadlocked. Retrying it may help. +struct PQXX_LIBEXPORT deadlock_detected : transaction_rollback +{ + explicit deadlock_detected( + std::string const &whatarg, std::string const &q, + char const sqlstate[] = nullptr); +}; + + +/// Internal error in libpqxx library +struct PQXX_LIBEXPORT internal_error : std::logic_error +{ + explicit internal_error(std::string const &); +}; + + +/// Error in usage of libpqxx library, similar to std::logic_error +struct PQXX_LIBEXPORT usage_error : std::logic_error +{ + explicit usage_error(std::string const &); +}; + + +/// Invalid argument passed to libpqxx, similar to std::invalid_argument +struct PQXX_LIBEXPORT argument_error : std::invalid_argument +{ + explicit argument_error(std::string const &); +}; + + +/// Value conversion failed, e.g. when converting "Hello" to int. +struct PQXX_LIBEXPORT conversion_error : std::domain_error +{ + explicit conversion_error(std::string const &); +}; + + +/// Could not convert value to string: not enough buffer space. +struct PQXX_LIBEXPORT conversion_overrun : conversion_error +{ + explicit conversion_overrun(std::string const &); +}; + + +/// Something is out of range, similar to std::out_of_range +struct PQXX_LIBEXPORT range_error : std::out_of_range +{ + explicit range_error(std::string const &); +}; + + +/// Query returned an unexpected number of rows. +struct PQXX_LIBEXPORT unexpected_rows : public range_error +{ + explicit unexpected_rows(std::string const &msg) : range_error{msg} {} +}; + + +/// Database feature not supported in current setup. +struct PQXX_LIBEXPORT feature_not_supported : sql_error +{ + explicit feature_not_supported( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Error in data provided to SQL statement. +struct PQXX_LIBEXPORT data_exception : sql_error +{ + explicit data_exception( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT integrity_constraint_violation : sql_error +{ + explicit integrity_constraint_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT restrict_violation : integrity_constraint_violation +{ + explicit restrict_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT not_null_violation : integrity_constraint_violation +{ + explicit not_null_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT foreign_key_violation : integrity_constraint_violation +{ + explicit foreign_key_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT unique_violation : integrity_constraint_violation +{ + explicit unique_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT check_violation : integrity_constraint_violation +{ + explicit check_violation( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + integrity_constraint_violation{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_state : sql_error +{ + explicit invalid_cursor_state( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_sql_statement_name : sql_error +{ + explicit invalid_sql_statement_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT invalid_cursor_name : sql_error +{ + explicit invalid_cursor_name( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT syntax_error : sql_error +{ + /// Approximate position in string where error occurred, or -1 if unknown. + int const error_position; + + explicit syntax_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr, int pos = -1) : + sql_error{err, Q, sqlstate}, error_position{pos} + {} +}; + +struct PQXX_LIBEXPORT undefined_column : syntax_error +{ + explicit undefined_column( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_function : syntax_error +{ + explicit undefined_function( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT undefined_table : syntax_error +{ + explicit undefined_table( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + syntax_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT insufficient_privilege : sql_error +{ + explicit insufficient_privilege( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Resource shortage on the server +struct PQXX_LIBEXPORT insufficient_resources : sql_error +{ + explicit insufficient_resources( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT disk_full : insufficient_resources +{ + explicit disk_full( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT out_of_memory : insufficient_resources +{ + explicit out_of_memory( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + insufficient_resources{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT too_many_connections : broken_connection +{ + explicit too_many_connections(std::string const &err) : + broken_connection{err} + {} +}; + +/// PL/pgSQL error +/** Exceptions derived from this class are errors from PL/pgSQL procedures. + */ +struct PQXX_LIBEXPORT plpgsql_error : sql_error +{ + explicit plpgsql_error( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + sql_error{err, Q, sqlstate} + {} +}; + +/// Exception raised in PL/pgSQL procedure +struct PQXX_LIBEXPORT plpgsql_raise : plpgsql_error +{ + explicit plpgsql_raise( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_no_data_found : plpgsql_error +{ + explicit plpgsql_no_data_found( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT plpgsql_too_many_rows : plpgsql_error +{ + explicit plpgsql_too_many_rows( + std::string const &err, std::string const &Q = "", + char const sqlstate[] = nullptr) : + plpgsql_error{err, Q, sqlstate} + {} +}; + +struct PQXX_LIBEXPORT blob_already_exists : failure +{ + explicit blob_already_exists(std::string const &); +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field new file mode 100644 index 0000000..37cb69e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field @@ -0,0 +1,8 @@ +/** pqxx::field class. + * + * pqxx::field refers to a field in a query result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field.hxx new file mode 100644 index 0000000..b8b869f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/field.hxx @@ -0,0 +1,542 @@ +/* Definitions for the pqxx::field class. + * + * pqxx::field refers to a field in a query result. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_FIELD +#define PQXX_H_FIELD + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/array.hxx" +#include "pqxx/composite.hxx" +#include "pqxx/result.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/types.hxx" + +namespace pqxx +{ +/// Reference to a field in a result set. +/** A field represents one entry in a row. It represents an actual value + * in the result set, and can be converted to various types. + */ +class PQXX_LIBEXPORT field +{ +public: + using size_type = field_size_type; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + /** Create field as reference to a field in a result set. + * @param r Row that this field is part of. + * @param c Column number of this field. + */ + [[deprecated( + "Do not construct fields yourself. Get them from the row.")]] field(row const &r, row_size_type c) noexcept; + + /// Constructor. Do not call this yourself; libpqxx will do it for you. + [[deprecated( + "Do not construct fields yourself. Get them from the " + "row.")]] field() noexcept = default; + + /** + * @name Comparison + */ + //@{ + // TODO: noexcept. Breaks ABI. + /// Byte-by-byte comparison of two fields (all nulls are considered equal) + /** @warning null handling is still open to discussion and change! + * + * Handling of null values differs from that in SQL where a comparison + * involving a null value yields null, so nulls are never considered equal + * to one another or even to themselves. + * + * Null handling also probably differs from the closest equivalent in C++, + * which is the NaN (Not-a-Number) value, a singularity comparable to + * SQL's null. This is because the builtin == operator demands that a == a. + * + * The usefulness of this operator is questionable. No interpretation + * whatsoever is imposed on the data; 0 and 0.0 are considered different, + * as are null vs. the empty string, or even different (but possibly + * equivalent and equally valid) encodings of the same Unicode character + * etc. + */ + [[nodiscard]] PQXX_PURE bool operator==(field const &) const; + + /// Byte-by-byte comparison (all nulls are considered equal) + /** @warning See operator==() for important information about this operator + */ + [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /** + * @name Column information + */ + //@{ + /// Column name. + [[nodiscard]] PQXX_PURE char const *name() const &; + + /// Column type. + [[nodiscard]] oid PQXX_PURE type() const; + + /// What table did this column come from? + [[nodiscard]] PQXX_PURE oid table() const; + + /// Return row number. The first row is row 0, the second is row 1, etc. + PQXX_PURE constexpr row_size_type num() const noexcept { return col(); } + + /// What column number in its originating table did this column come from? + [[nodiscard]] PQXX_PURE row_size_type table_column() const; + //@} + + /** + * @name Content access + */ + //@{ + /// Read as `string_view`, or an empty one if null. + /** The result only remains usable while the data for the underlying + * @ref result exists. Once all `result` objects referring to that data have + * been destroyed, the `string_view` will no longer point to valid memory. + */ + [[nodiscard]] PQXX_PURE std::string_view view() const & + { + return std::string_view(c_str(), size()); + } + + /// Read as plain C string. + /** Since the field's data is stored internally in the form of a + * zero-terminated C string, this is the fastest way to read it. Use the + * to() or as() functions to convert the string to other types such as + * `int`, or to C++ strings. + * + * Do not use this for BYTEA values, or other binary values. To read those, + * convert the value to your desired type using `to()` or `as()`. For + * example: `f.as>()`. + */ + [[nodiscard]] PQXX_PURE char const *c_str() const &; + + /// Is this field's value null? + [[nodiscard]] PQXX_PURE bool is_null() const noexcept; + + /// Return number of bytes taken up by the field's value. + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + + /// Read value into obj; or if null, leave obj untouched and return `false`. + /** This can be used with optional types (except pointers other than C-style + * strings). + */ + template + auto to(T &obj) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + if (is_null()) + { + return false; + } + else + { + auto const bytes{c_str()}; + from_string(bytes, obj); + return true; + } + } + + /// Read field as a composite value, write its components into `fields`. + /** @warning This is still experimental. It may change or be replaced. + * + * Returns whether the field was null. If it was, it will not touch the + * values in `fields`. + */ + template bool composite_to(T &...fields) const + { + if (is_null()) + { + return false; + } + else + { + parse_composite(m_home.m_encoding, view(), fields...); + return true; + } + } + + /// Read value into obj; or leave obj untouched and return `false` if null. + template bool operator>>(T &obj) const { return to(obj); } + + /// Read value into obj; or if null, use default value and return `false`. + /** This can be used with `std::optional`, as well as with standard smart + * pointer types, but not with raw pointers. If the conversion from a + * PostgreSQL string representation allocates a pointer (e.g. using `new`), + * then the object's later deallocation should be baked in as well, right + * from the point where the object is created. So if you want a pointer, use + * a smart pointer, not a raw pointer. + * + * There is one exception, of course: C-style strings. Those are just + * pointers to the field's internal text data. + */ + template + auto to(T &obj, T const &default_value) const -> typename std::enable_if_t< + (not std::is_pointer::value or std::is_same::value), + bool> + { + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = from_string(this->view()); + return not null; + } + + /// Return value as object of given type, or default value if null. + /** Note that unless the function is instantiated with an explicit template + * argument, the Default value's type also determines the result type. + */ + template T as(T const &default_value) const + { + if (is_null()) + return default_value; + else + return from_string(this->view()); + } + + /// Return value as object of given type, or throw exception if null. + /** Use as `as>()` or `as()` as + * an alternative to `get()`; this is disabled for use with raw pointers + * (other than C-strings) because storage for the value can't safely be + * allocated here + */ + template T as() const + { + if (is_null()) + { + if constexpr (not nullness::has_null) + internal::throw_null_conversion(type_name); + else + return nullness::null(); + } + else + { + return from_string(this->view()); + } + } + + /// Return value wrapped in some optional type (empty for nulls). + /** Use as `get()` as before to obtain previous behavior, or specify + * container type with `get()` + */ + template class O = std::optional> + constexpr O get() const + { + return as>(); + } + + // TODO: constexpr noexcept, once array_parser constructor gets those. + /// Parse the field as an SQL array. + /** Call the parser to retrieve values (and structure) from the array. + * + * Make sure the @ref result object stays alive until parsing is finished. If + * you keep the @ref row of `field` object alive, it will keep the @ref + * result object alive as well. + */ + array_parser as_array() const & + { + return array_parser{c_str(), m_home.m_encoding}; + } + //@} + + +protected: + constexpr result const &home() const noexcept { return m_home; } + constexpr result::size_type idx() const noexcept { return m_row; } + constexpr row_size_type col() const noexcept { return m_col; } + + // TODO: Create gates. + friend class pqxx::result; + friend class pqxx::row; + field( + result const &r, result_size_type row_num, row_size_type col_num) noexcept + : + m_col{col_num}, m_home{r}, m_row{row_num} + {} + + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + row_size_type m_col; + +private: + result m_home; + result::size_type m_row; +}; + + +template<> inline bool field::to(std::string &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = std::string{view()}; + return not null; +} + + +template<> +inline bool field::to( + std::string &obj, std::string const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = std::string{view()}; + return not null; +} + + +/// Specialization: `to(char const *&)`. +/** The buffer has the same lifetime as the data in this result (i.e. of this + * result object, or the last remaining one copied from it etc.), so take care + * not to use it after the last result object referring to this query result is + * destroyed. + */ +template<> inline bool field::to(char const *&obj) const +{ + bool const null{is_null()}; + if (not null) + obj = c_str(); + return not null; +} + + +template<> inline bool field::to(std::string_view &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = view(); + return not null; +} + + +template<> +inline bool field::to( + std::string_view &obj, std::string_view const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = view(); + return not null; +} + + +template<> inline std::string_view field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return view(); +} + + +template<> +inline std::string_view +field::as(std::string_view const &default_value) const +{ + return is_null() ? default_value : view(); +} + + +template<> inline bool field::to(zview &obj) const +{ + bool const null{is_null()}; + if (not null) + obj = zview{c_str(), size()}; + return not null; +} + + +template<> +inline bool field::to(zview &obj, zview const &default_value) const +{ + bool const null{is_null()}; + if (null) + obj = default_value; + else + obj = zview{c_str(), size()}; + return not null; +} + + +template<> inline zview field::as() const +{ + if (is_null()) + PQXX_UNLIKELY + internal::throw_null_conversion(type_name); + return zview{c_str(), size()}; +} + + +template<> inline zview field::as(zview const &default_value) const +{ + return is_null() ? default_value : zview{c_str(), size()}; +} + + +template> +class field_streambuf : public std::basic_streambuf +{ +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = std::ios::openmode; + using seekdir = std::ios::seekdir; + + explicit field_streambuf(field const &f) : m_field{f} { initialize(); } + +protected: + virtual int sync() override { return traits_type::eof(); } + + virtual pos_type seekoff(off_type, seekdir, openmode) override + { + return traits_type::eof(); + } + virtual pos_type seekpos(pos_type, openmode) override + { + return traits_type::eof(); + } + virtual int_type overflow(int_type) override { return traits_type::eof(); } + virtual int_type underflow() override { return traits_type::eof(); } + +private: + field const &m_field; + + int_type initialize() + { + auto g{static_cast(const_cast(m_field.c_str()))}; + this->setg(g, g, g + std::size(m_field)); + return int_type(std::size(m_field)); + } +}; + + +/// Input stream that gets its data from a result field +/** Use this class exactly as you would any other istream to read data from a + * field. All formatting and streaming operations of `std::istream` are + * supported. What you'll typically want to use, however, is the fieldstream + * alias (which defines a @ref basic_fieldstream for `char`). This is similar + * to how e.g. `std::ifstream` relates to `std::basic_ifstream`. + * + * This class has only been tested for the char type (and its default traits). + */ +template> +class basic_fieldstream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + basic_fieldstream(field const &f) : super{nullptr}, m_buf{f} + { + super::init(&m_buf); + } + +private: + field_streambuf m_buf; +}; + +using fieldstream = basic_fieldstream; + +/// Write a result field to any type of stream +/** This can be convenient when writing a field to an output stream. More + * importantly, it lets you write a field to e.g. a `stringstream` which you + * can then use to read, format and convert the field in ways that to() does + * not support. + * + * Example: parse a field into a variable of the nonstandard + * "long long" type. + * + * ```cxx + * extern result R; + * long long L; + * stringstream S; + * + * // Write field's string into S + * S << R[0][0]; + * + * // Parse contents of S into L + * S >> L; + * ``` + */ +template +inline std::basic_ostream & +operator<<(std::basic_ostream &s, field const &value) +{ + s.write(value.c_str(), std::streamsize(std::size(value))); + return s; +} + + +/// Convert a field's value to type `T`. +/** Unlike the "regular" `from_string`, this knows how to deal with null + * values. + */ +template inline T from_string(field const &value) +{ + if (value.is_null()) + { + if constexpr (nullness::has_null) + return nullness::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + return from_string(value.view()); + } +} + + +/// Convert a field's value to `nullptr_t`. +/** Yes, you read that right. This conversion does nothing useful. It always + * returns `nullptr`. + * + * Except... what if the field is not null? In that case, this throws + * @ref conversion_error. + */ +template<> +inline std::nullptr_t from_string(field const &value) +{ + if (not value.is_null()) + throw conversion_error{ + "Extracting non-null field into nullptr_t variable."}; + return nullptr; +} + + +/// Convert a field to a string. +template<> PQXX_LIBEXPORT std::string to_string(field const &value); +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/array-composite.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/array-composite.hxx new file mode 100644 index 0000000..d2b6603 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/array-composite.hxx @@ -0,0 +1,305 @@ +#if !defined(PQXX_ARRAY_COMPOSITE_HXX) +# define PQXX_ARRAY_COMPOSITE_HXX + +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +// Find the end of a double-quoted string. +/** `input[pos]` must be the opening double quote. + * + * Returns the offset of the first position after the closing quote. + */ +inline std::size_t scan_double_quoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + // XXX: find_char<'"', '\\'>(). + auto next{scan(input, size, pos)}; + bool at_quote{false}; + for (pos = next, next = scan(input, size, pos); pos < size; + pos = next, next = scan(input, size, pos)) + { + if (at_quote) + { + if (next - pos == 1 and input[pos] == '"') + { + // We just read a pair of double quotes. Carry on. + at_quote = false; + } + else + { + // We just read one double quote, and now we're at a character that's + // not a second double quote. Ergo, that last character was the + // closing double quote and this is the position right after it. + return pos; + } + } + else if (next - pos == 1) + { + switch (input[pos]) + { + case '\\': + // Backslash escape. Skip ahead by one more character. + pos = next; + next = scan(input, size, pos); + break; + + case '"': + // This is either the closing double quote, or the first of a pair of + // double quotes. + at_quote = true; + break; + } + } + else + { + // Multibyte character. Carry on. + } + } + if (not at_quote) + throw argument_error{ + "Missing closing double-quote: " + std::string{input}}; + return pos; +} + + +/// Un-quote and un-escape a double-quoted SQL string. +inline std::string parse_double_quoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + // Maximum output size is same as the input size, minus the opening and + // closing quotes. Or in the extreme opposite case, the real number could be + // half that. Usually it'll be a pretty close estimate. + output.reserve(std::size_t(end - pos - 2)); + + for (auto here{scan(input, end, pos)}, next{scan(input, end, here)}; + here < end - 1; here = next, next = scan(input, end, here)) + { + // A backslash here is always an escape. So is a double-quote, since we're + // inside the double-quoted string. In either case, we can just ignore the + // escape character and use the next character. This is the one redeeming + // feature of SQL's escaping system. + if ((next - here == 1) and (input[here] == '\\' or input[here] == '"')) + { + // Skip escape. + here = next; + next = scan(input, end, here); + } + output.append(input + here, input + next); + } + return output; +} + + +/// Find the end of an unquoted string in an array or composite-type value. +/** Stops when it gets to the end of the input; or when it sees any of the + * characters in STOP which has not been escaped. + * + * For array values, STOP is a comma, a semicolon, or a closing brace. For + * a value of a composite type, STOP is a comma or a closing parenthesis. + */ +template +inline std::size_t scan_unquoted_string( + char const input[], std::size_t size, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + bool at_backslash{false}; + auto next{scan(input, size, pos)}; + while ((pos < size) and + ((next - pos) > 1 or at_backslash or ((input[pos] != STOP) and ...))) + { + pos = next; + next = scan(input, size, pos); + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + } + return pos; +} + + +/// Parse an unquoted array entry or cfield of a composite-type field. +inline std::string parse_unquoted_string( + char const input[], std::size_t end, std::size_t pos, + pqxx::internal::glyph_scanner_func *scan) +{ + std::string output; + bool at_backslash{false}; + output.reserve(end - pos); + for (auto next{scan(input, end, pos)}; pos < end; + pos = next, next = scan(input, end, pos)) + { + at_backslash = + ((not at_backslash) and ((next - pos) == 1) and (input[pos] == '\\')); + if (not at_backslash) + output.append(input + pos, next - pos); + } + return output; +} + + +/// Parse a field of a composite-type value. +/** `T` is the C++ type of the field we're parsing, and `index` is its + * zero-based number. + * + * Strip off the leading parenthesis or bracket yourself before parsing. + * However, this function will parse the lcosing parenthesis or bracket. + * + * After a successful parse, `pos` will point at `std::end(text)`. + * + * For the purposes of parsing, ranges and arrays count as compositve values, + * so this function supports parsing those. If you specifically need a closing + * parenthesis, check afterwards that `text` did not end in a bracket instead. + * + * @param index Index of the current field, zero-based. It will increment for + * the next field. + * @param input Full input text for the entire composite-type value. + * @param pos Starting position (in `input`) of the field that we're parsing. + * After parsing, this will point at the beginning of the next field if + * there is one, or one position past the last character otherwise. + * @param field Destination for the parsed value. + * @param scan Glyph scanning function for the relevant encoding type. + * @param last_field Number of the last field in the value (zero-based). When + * parsing the last field, this will equal `index`. + */ +template +inline void parse_composite_field( + std::size_t &index, std::string_view input, std::size_t &pos, T &field, + glyph_scanner_func *scan, std::size_t last_field) +{ + assert(index <= last_field); + auto next{scan(std::data(input), std::size(input), pos)}; + if ((next - pos) != 1) + throw conversion_error{"Non-ASCII character in composite-type syntax."}; + + // Expect a field. + switch (input[pos]) + { + case ',': + case ')': + case ']': + // The field is empty, i.e, null. + if constexpr (nullness::has_null) + field = nullness::null(); + else + throw conversion_error{ + "Can't read composite field " + to_string(index) + ": C++ type " + + type_name + " does not support nulls."}; + break; + + case '"': { + auto const stop{scan_double_quoted_string( + std::data(input), std::size(input), pos, scan)}; + auto const text{ + parse_double_quoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + + default: { + auto const stop{scan_unquoted_string<',', ')', ']'>( + std::data(input), std::size(input), pos, scan)}; + auto const text{parse_unquoted_string(std::data(input), stop, pos, scan)}; + field = from_string(text); + pos = stop; + } + break; + } + + // Expect a comma or a closing parenthesis. + next = scan(std::data(input), std::size(input), pos); + + if ((next - pos) != 1) + throw conversion_error{ + "Unexpected non-ASCII character after composite field: " + + std::string{input}}; + + if (index < last_field) + { + if (input[pos] != ',') + throw conversion_error{ + "Found '" + std::string{input[pos]} + + "' in composite value where comma was expected: " + std::data(input)}; + } + else + { + if (input[pos] == ',') + throw conversion_error{ + "Composite value contained more fields than the expected " + + to_string(last_field) + ": " + std::data(input)}; + if (input[pos] != ')' and input[pos] != ']') + throw conversion_error{ + "Composite value has unexpected characters where closing parenthesis " + "was expected: " + + std::string{input}}; + if (next != std::size(input)) + throw conversion_error{ + "Composite value has unexpected text after closing parenthesis: " + + std::string{input}}; + } + + pos = next; + ++index; +} + + +/// Conservatively estimate buffer size needed for a composite field. +template +inline std::size_t size_composite_field_buffer(T const &field) +{ + if constexpr (is_unquoted_safe) + { + // Safe to copy, without quotes or escaping. Drop the terminating zero. + return size_buffer(field) - 1; + } + else + { + // + Opening quote. + // + Field budget. + // - Terminating zero. + // + Escaping for each byte in the field's string representation. + // - Escaping for terminating zero. + // + Closing quote. + return 1 + 2 * (size_buffer(field) - 1) + 1; + } +} + + +template +inline void write_composite_field(char *&pos, char *end, T const &field) +{ + if constexpr (is_unquoted_safe) + { + // No need for quoting or escaping. Convert it straight into its final + // place in the buffer, and "backspace" the trailing zero. + pos = string_traits::into_buf(pos, end, field) - 1; + } + else + { + // The field may need escaping, which means we need an intermediate buffer. + // To avoid allocating that at run time, we use the end of the buffer that + // we have. + auto const budget{size_buffer(field)}; + *pos++ = '"'; + + // Now escape buf into its final position. + for (char const c : string_traits::to_buf(end - budget, end, field)) + { + if ((c == '"') or (c == '\\')) + *pos++ = '\\'; + + *pos++ = c; + } + + *pos++ = '"'; + } + + *pos++ = ','; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/callgate.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/callgate.hxx new file mode 100644 index 0000000..42f7703 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/callgate.hxx @@ -0,0 +1,70 @@ +#ifndef PQXX_H_CALLGATE +#define PQXX_H_CALLGATE + +/* +Here's what a typical gate class definition looks like: + +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE @gateclass@ : callgate<@host@> +{ + friend class @client@; + + @gateclass@(reference x) : super(x) {} + + // Methods here. Use home() to access the host-class object. +}; +} // namespace pqxx::internal::gate +*/ + +namespace pqxx::internal +{ +/// Base class for call gates. +/** + * A call gate defines a limited, private interface on the host class that + * specified client classes can access. + * + * The metaphor works as follows: the gate stands in front of a "home," which + * is really a class, and only lets specific friends in. + * + * To implement a call gate that gives client C access to host H, + * * derive a gate class from callgate; + * * make the gate class a friend of H; + * * make C a friend of the gate class; and + * * implement "stuff C can do with H" as private members in the gate class. + * + * This special kind of "gated" friendship gives C private access to H, but + * only through an expressly limited interface. The gate class can access its + * host object as home(). + * + * Keep gate classes entirely stateless. They should be ultra-lightweight + * wrappers for their host classes, and be optimized away as much as possible + * by the compiler. Once you start adding state, you're on a slippery slope + * away from the pure, clean, limited interface pattern that gate classes are + * meant to implement. + * + * Ideally, all member functions of the gate class should be one-liners passing + * calls straight on to the host class. It can be useful however to break this + * rule temporarily during inter-class refactoring. + */ +template class PQXX_PRIVATE callgate +{ +protected: + /// This class, to keep constructors easy. + using super = callgate; + /// A reference to the host class. Helps keep constructors easy. + using reference = HOME &; + + callgate(reference x) : m_home(x) {} + + /// The home object. The gate class has full "private" access. + reference home() const noexcept { return m_home; } + +private: + reference m_home; +}; +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/concat.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/concat.hxx new file mode 100644 index 0000000..cd28bde --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/concat.hxx @@ -0,0 +1,45 @@ +#if !defined(PQXX_CONCAT_HXX) +# define PQXX_CONCAT_HXX + +# include +# include + +# include "pqxx/strconv.hxx" + +namespace pqxx::internal +{ +/// Convert item to a string, write it into [here, end). +template +void render_item(TYPE const &item, char *&here, char *end) +{ + here = string_traits::into_buf(here, end, item) - 1; +} + + +// C++20: Support non-random_access_range ranges. +/// Efficiently combine a bunch of items into one big string. +/** Use this as an optimised version of string concatentation. It takes just + * about any type; it will represent each item as a string according to its + * @ref string_traits. + * + * This is a simpler, more specialised version of @ref separated_list for a + * statically known series of items, possibly of different types. + */ +template +[[nodiscard]] inline std::string concat(TYPE... item) +{ + std::string buf; + // Size to accommodate string representations of all inputs, minus their + // terminating zero bytes. + buf.resize(size_buffer(item...)); + + char *const data{buf.data()}; + char *here = data; + char *end = data + std::size(buf); + (render_item(item, here, end), ...); + + buf.resize(static_cast(here - data)); + return buf; +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/conversions.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/conversions.hxx new file mode 100644 index 0000000..1df4fde --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/conversions.hxx @@ -0,0 +1,1188 @@ +#include +#include +#include +#include +#include +#include + +#if defined(PQXX_HAVE_SPAN) && __has_include() +# include +#endif + +#include +#include +#include + +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" + + +/* Internal helpers for string conversion, and conversion implementations. + * + * Do not include this header directly. The libpqxx headers do it for you. + */ +namespace pqxx::internal +{ +/// Convert a number in [0, 9] to its ASCII digit. +inline constexpr char number_to_digit(int i) noexcept +{ + return static_cast(i + '0'); +} + + +/// Compute numeric value of given textual digit (assuming that it is a digit). +constexpr int digit_to_number(char c) noexcept +{ + return c - '0'; +} + + +/// Summarize buffer overrun. +/** Don't worry about the exact parameter types: the sizes will be reasonably + * small, and nonnegative. + */ +std::string PQXX_LIBEXPORT +state_buffer_overrun(int have_bytes, int need_bytes); + + +template +inline std::string state_buffer_overrun(HAVE have_bytes, NEED need_bytes) +{ + return state_buffer_overrun( + static_cast(have_bytes), static_cast(need_bytes)); +} + + +/// Throw exception for attempt to convert null to given type. +[[noreturn]] PQXX_LIBEXPORT void +throw_null_conversion(std::string const &type); + + +/// Deliberately nonfunctional conversion traits for `char` types. +/** There are no string conversions for `char` and its signed and unsigned + * variants. Such a conversion would be dangerously ambiguous: should we treat + * it as text, or as a small integer? It'd be an open invitation for bugs. + * + * But the error message when you get this wrong is very cryptic. So, we + * derive dummy @ref string_traits implementations from this dummy type, and + * ensure that the compiler disallows their use. The compiler error message + * will at least contain a hint of the root of the problem. + */ +template struct disallowed_ambiguous_char_conversion +{ + static char *into_buf(char *, char *, CHAR_TYPE) = delete; + static constexpr zview + to_buf(char *, char *, CHAR_TYPE const &) noexcept = delete; + + static constexpr std::size_t + size_buffer(CHAR_TYPE const &) noexcept = delete; + static CHAR_TYPE from_string(std::string_view) = delete; +}; + + +template PQXX_LIBEXPORT extern std::string to_string_float(T); + + +/// Generic implementation for into_buf, on top of to_buf. +template +inline char *generic_into_buf(char *begin, char *end, T const &value) +{ + zview const text{string_traits::to_buf(begin, end, value)}; + auto const space{end - begin}; + // Include the trailing zero. + auto const len = std::size(text) + 1; + if (internal::cmp_greater(len, space)) + throw conversion_overrun{ + "Not enough buffer space to insert " + type_name + ". " + + state_buffer_overrun(space, len)}; + std::memmove(begin, text.data(), len); + return begin + len; +} + + +/// String traits for builtin integral types (though not bool). +template struct integral_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + static constexpr std::size_t size_buffer(T const &) noexcept + { + /** Includes a sign if needed; the number of base-10 digits which the type + * can reliably represent; the one extra base-10 digit which the type can + * only partially represent; and the terminating zero. + */ + return std::is_signed_v + std::numeric_limits::digits10 + 1 + 1; + } +}; + + +/// String traits for builtin floating-point types. +template struct float_traits +{ + static PQXX_LIBEXPORT T from_string(std::string_view text); + static PQXX_LIBEXPORT zview to_buf(char *begin, char *end, T const &value); + static PQXX_LIBEXPORT char *into_buf(char *begin, char *end, T const &value); + + // Return a nonnegative integral value's number of decimal digits. + static constexpr std::size_t digits10(std::size_t value) noexcept + { + if (value < 10) + return 1; + else + return 1 + digits10(value / 10); + } + + static constexpr std::size_t size_buffer(T const &) noexcept + { + using lims = std::numeric_limits; + // See #328 for a detailed discussion on the maximum number of digits. + // + // In a nutshell: for the big cases, the scientific notation is always + // the shortest one, and therefore the one that to_chars will pick. + // + // So... How long can the scientific notation get? 1 (for sign) + 1 (for + // decimal point) + 1 (for 'e') + 1 (for exponent sign) + max_digits10 + + // max number of digits in the exponent + 1 (terminating zero). + // + // What's the max number of digits in the exponent? It's the max number of + // digits out of the most negative exponent and the most positive one. + // + // The longest positive exponent is easy: 1 + ceil(log10(max_exponent10)). + // (The extra 1 is because 10^n takes up 1 + n digits, not n.) + // + // The longest negative exponent is a bit harder: min_exponent10 gives us + // the smallest power of 10 which a normalised version of T can represent. + // But the smallest denormalised power of 10 that T can represent is + // another max_digits10 powers of 10 below that. + // needs a minus sign. + // + // All this stuff messes with my head a bit because it's on the order of + // log10(log10(n)). It's easy to get the number of logs wrong. + auto const max_pos_exp{digits10(lims::max_exponent10)}; + // Really want std::abs(lims::min_exponent10), but MSVC 2017 apparently has + // problems with std::abs. So we use -lims::min_exponent10 instead. + auto const max_neg_exp{ + digits10(lims::max_digits10 - lims::min_exponent10)}; + return 1 + // Sign. + 1 + // Decimal point. + std::numeric_limits::max_digits10 + // Mantissa digits. + 1 + // Exponent "e". + 1 + // Exponent sign. + // Spell this weirdly to stop Windows compilers from reading this as + // a call to their "max" macro when NOMINMAX is not defined. + (std::max)(max_pos_exp, max_neg_exp) + // Exponent digits. + 1; // Terminating zero. + } +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// The built-in arithmetic types do not have inherent null values. +template +struct nullness>> : no_null +{}; + + +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits + : internal::integral_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; +template<> +struct string_traits : internal::float_traits +{}; +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct string_traits +{ + static PQXX_LIBEXPORT bool from_string(std::string_view text); + + static constexpr zview to_buf(char *, char *, bool const &value) noexcept + { + return value ? "true"_zv : "false"_zv; + } + + static char *into_buf(char *begin, char *end, bool const &value) + { + return pqxx::internal::generic_into_buf(begin, end, value); + } + + static constexpr std::size_t size_buffer(bool const &) noexcept { return 6; } +}; + + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + +/// We don't support conversion to/from `char` types. +/** Why are these disallowed? Because they are ambiguous. It's not inherently + * clear whether we should treat values of these types as text or as small + * integers. Either choice would lead to bugs. + */ +template<> +struct string_traits + : internal::disallowed_ambiguous_char_conversion +{}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + /// Technically, you could have an optional of an always-null type. + static constexpr bool always_null = nullness::always_null; + static constexpr bool is_null(std::optional const &v) noexcept + { + return ((not v.has_value()) or pqxx::is_null(*v)); + } + static constexpr std::optional null() { return {}; } +}; + + +template +inline constexpr format param_format(std::optional const &value) +{ + return param_format(*value); +} + + +template struct string_traits> +{ + static char *into_buf(char *begin, char *end, std::optional const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview to_buf(char *begin, char *end, std::optional const &value) + { + if (value.has_value()) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::optional from_string(std::string_view text) + { + return std::optional{ + std::in_place, string_traits::from_string(text)}; + } + + static std::size_t size_buffer(std::optional const &value) noexcept + { + return pqxx::size_buffer(value.value()); + } +}; + + +template +inline constexpr bool is_unquoted_safe>{is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = (nullness::has_null or ...); + static constexpr bool always_null = (nullness::always_null and ...); + static constexpr bool is_null(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { + return nullness>::is_null(i); + }, + value); + } + + // We don't support `null()` for `std::variant`. + /** It would be technically possible to have a `null` in the case where just + * one of the types has a null, but it gets complicated and arbitrary. + */ + static constexpr std::variant null() = delete; +}; + + +template struct string_traits> +{ + static char * + into_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::into_buf(begin, end, i); + }, + value); + } + static zview to_buf(char *begin, char *end, std::variant const &value) + { + return std::visit( + [begin, end](auto const &i) { + return string_traits>::to_buf(begin, end, i); + }, + value); + } + static std::size_t size_buffer(std::variant const &value) noexcept + { + return std::visit( + [](auto const &i) noexcept { return pqxx::size_buffer(i); }, value); + } + + /** There's no from_string for std::variant. We could have one with a rule + * like "pick the first type which fits the value," but we'd have to look + * into how natural that API feels to users. + */ + static std::variant from_string(std::string_view) = delete; +}; + + +template +inline constexpr format param_format(std::variant const &value) +{ + return std::visit([](auto &v) { return param_format(v); }, value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + (is_unquoted_safe and ...)}; + + +template inline T from_string(std::stringstream const &text) +{ + return from_string(text.str()); +} + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullptr_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullptr_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullptr_t = nullptr) noexcept + { + return 0; + } + static std::nullptr_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::nullopt_t) = delete; + + static constexpr zview + to_buf(char *, char *, std::nullopt_t const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::nullopt_t) noexcept + { + return 0; + } + static std::nullopt_t from_string(std::string_view) = delete; +}; + + +template<> struct string_traits +{ + static char *into_buf(char *, char *, std::monostate) = delete; + + static constexpr zview + to_buf(char *, char *, std::monostate const &) noexcept + { + return {}; + } + + static constexpr std::size_t size_buffer(std::monostate) noexcept + { + return 0; + } + static std::monostate from_string(std::string_view) = delete; +}; + + +template<> inline constexpr bool is_unquoted_safe{true}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() noexcept { return nullptr; } +}; + + +/// String traits for C-style string ("pointer to char const"). +template<> struct string_traits +{ + static char const *from_string(std::string_view text) { return text.data(); } + + static zview to_buf(char *begin, char *end, char const *const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, char const *const &value) + { + auto const space{end - begin}; + // Count the trailing zero, even though std::strlen() and friends don't. + auto const len{std::strlen(value) + 1}; + if (space < ptrdiff_t(len)) + throw conversion_overrun{ + "Could not copy string: buffer too small. " + + pqxx::internal::state_buffer_overrun(space, len)}; + std::memmove(begin, value, len); + return begin + len; + } + + static std::size_t size_buffer(char const *const &value) noexcept + { + return std::strlen(value) + 1; + } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(char const *t) noexcept + { + return t == nullptr; + } + static constexpr char const *null() { return nullptr; } +}; + + +/// String traits for non-const C-style string ("pointer to char"). +template<> struct string_traits +{ + static char *into_buf(char *begin, char *end, char *const &value) + { + return string_traits::into_buf(begin, end, value); + } + static zview to_buf(char *begin, char *end, char *const &value) + { + return string_traits::to_buf(begin, end, value); + } + static std::size_t size_buffer(char *const &value) noexcept + { + return string_traits::size_buffer(value); + } + + /// Don't allow conversion to this type since it breaks const-safety. + static char *from_string(std::string_view) = delete; +}; + + +template struct nullness : no_null +{}; + + +/// String traits for C-style string constant ("array of char"). +/** @warning This assumes that every array-of-char is a C-style string literal. + * So, it must include a trailing zero. and it must have static duration. + */ +template struct string_traits +{ + static constexpr zview + to_buf(char *, char *, char const (&value)[N]) noexcept + { + return zview{value, N - 1}; + } + + static char *into_buf(char *begin, char *end, char const (&value)[N]) + { + if (internal::cmp_less(end - begin, size_buffer(value))) + throw conversion_overrun{ + "Could not convert char[] to string: too long for buffer."}; + std::memcpy(begin, value, N); + return begin + N; + } + static constexpr std::size_t size_buffer(char const (&)[N]) noexcept + { + return N; + } + + /// Don't allow conversion to this type. + static void from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::string from_string(std::string_view text) + { + return std::string{text}; + } + + static char *into_buf(char *begin, char *end, std::string const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not convert string to string: too long for buffer."}; + // Include the trailing zero. + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + static zview to_buf(char *begin, char *end, std::string const &value) + { + return generic_to_buf(begin, end, value); + } + + static std::size_t size_buffer(std::string const &value) noexcept + { + return std::size(value) + 1; + } +}; + + +/// There's no real null for `std::string_view`. +/** I'm not sure how clear-cut this is: a `string_view` may have a null + * data pointer, which is analogous to a null `char` pointer. + */ +template<> struct nullness : no_null +{}; + + +/// String traits for `string_view`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, std::string_view const &value) + { + if (internal::cmp_greater_equal(std::size(value), end - begin)) + throw conversion_overrun{ + "Could not store string_view: too long for buffer."}; + value.copy(begin, std::size(value)); + begin[std::size(value)] = '\0'; + return begin + std::size(value) + 1; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static std::string_view from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +/// String traits for `zview`. +template<> struct string_traits +{ + static constexpr std::size_t + size_buffer(std::string_view const &value) noexcept + { + return std::size(value) + 1; + } + + static char *into_buf(char *begin, char *end, zview const &value) + { + auto const size{std::size(value)}; + if (internal::cmp_less_equal(end - begin, std::size(value))) + throw conversion_overrun{"Not enough buffer space to store this zview."}; + value.copy(begin, size); + begin[size] = '\0'; + return begin + size + 1; + } + + static std::string_view to_buf(char *begin, char *end, zview const &value) + { + return {into_buf(begin, end, value), std::size(value)}; + } + + /// Don't convert to this type; it has nowhere to store its contents. + static zview from_string(std::string_view) = delete; +}; + + +template<> struct nullness : no_null +{}; + + +template<> struct string_traits +{ + static std::size_t size_buffer(std::stringstream const &) = delete; + + static std::stringstream from_string(std::string_view text) + { + std::stringstream stream; + stream.write(text.data(), std::streamsize(std::size(text))); + return stream; + } + + static char *into_buf(char *, char *, std::stringstream const &) = delete; + static std::string_view + to_buf(char *, char *, std::stringstream const &) = delete; +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullptr_t const &) noexcept + { + return true; + } + static constexpr std::nullptr_t null() noexcept { return nullptr; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::nullopt_t const &) noexcept + { + return true; + } + static constexpr std::nullopt_t null() noexcept { return std::nullopt; } +}; + + +template<> struct nullness +{ + static constexpr bool has_null = true; + static constexpr bool always_null = true; + static constexpr bool is_null(std::monostate const &) noexcept + { + return true; + } + static constexpr std::monostate null() noexcept { return {}; } +}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::unique_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::unique_ptr null() { return {}; } +}; + + +template +struct string_traits> +{ + static std::unique_ptr from_string(std::string_view text) + { + return std::make_unique(string_traits::from_string(text)); + } + + static char * + into_buf(char *begin, char *end, std::unique_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + + static zview + to_buf(char *begin, char *end, std::unique_ptr const &value) + { + if (value) + return string_traits::to_buf(begin, end, *value); + else + return {}; + } + + static std::size_t + size_buffer(std::unique_ptr const &value) noexcept + { + return pqxx::size_buffer(*value.get()); + } +}; + + +template +inline format param_format(std::unique_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template struct nullness> +{ + static constexpr bool has_null = true; + static constexpr bool always_null = false; + static constexpr bool is_null(std::shared_ptr const &t) noexcept + { + return not t or pqxx::is_null(*t); + } + static constexpr std::shared_ptr null() { return {}; } +}; + + +template struct string_traits> +{ + static std::shared_ptr from_string(std::string_view text) + { + return std::make_shared(string_traits::from_string(text)); + } + + static zview to_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::to_buf(begin, end, *value); + } + static char * + into_buf(char *begin, char *end, std::shared_ptr const &value) + { + return string_traits::into_buf(begin, end, *value); + } + static std::size_t size_buffer(std::shared_ptr const &value) noexcept + { + return pqxx::size_buffer(*value); + } +}; + + +template format param_format(std::shared_ptr const &value) +{ + return param_format(*value); +} + + +template +inline constexpr bool is_unquoted_safe>{ + is_unquoted_safe}; + + +template<> +struct nullness> + : no_null> +{}; + + +#if defined(PQXX_HAVE_CONCEPTS) +template struct nullness : no_null +{}; + + +template inline constexpr format param_format(DATA const &) +{ + return format::binary; +} + + +template struct string_traits +{ + static std::size_t size_buffer(DATA const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf(char *begin, char *end, DATA const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, DATA const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static DATA from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; +#endif // PQXX_HAVE_CONCEPTS + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview + to_buf(char *begin, char *end, std::basic_string const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::basic_string const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + static std::basic_string from_string(std::string_view text) + { + auto const size{pqxx::internal::size_unesc_bin(std::size(text))}; + std::basic_string buf; + buf.resize(size); + pqxx::internal::unesc_bin(text, reinterpret_cast(buf.data())); + return buf; + } +}; + + +template<> +inline constexpr format param_format(std::basic_string const &) +{ + return format::binary; +} + + +template<> +struct nullness> + : no_null> +{}; + + +template<> struct string_traits> +{ + static std::size_t + size_buffer(std::basic_string_view const &value) noexcept + { + return internal::size_esc_bin(std::size(value)); + } + + static zview to_buf( + char *begin, char *end, std::basic_string_view const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf( + char *begin, char *end, std::basic_string_view const &value) + { + auto const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to escape binary data."}; + internal::esc_bin(value, begin); + return begin + budget; + } + + // There's no from_string, because there's nobody to hold the data. +}; + +template<> +inline constexpr format param_format(std::basic_string_view const &) +{ + return format::binary; +} +} // namespace pqxx + + +namespace pqxx::internal +{ +/// String traits for SQL arrays. +template struct array_string_traits +{ +private: + using elt_type = strip_t>; + using elt_traits = string_traits; + static constexpr zview s_null{"NULL"}; + +public: + static zview to_buf(char *begin, char *end, Container const &value) + { + return generic_to_buf(begin, end, value); + } + + static char *into_buf(char *begin, char *end, Container const &value) + { + std::size_t const budget{size_buffer(value)}; + if (internal::cmp_less(end - begin, budget)) + throw conversion_overrun{ + "Not enough buffer space to convert array to string."}; + + char *here = begin; + *here++ = '{'; + + bool nonempty{false}; + for (auto const &elt : value) + { + if (is_null(elt)) + { + s_null.copy(here, std::size(s_null)); + here += std::size(s_null); + } + else if constexpr (is_sql_array) + { + // Render nested array in-place. Then erase the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else if constexpr (is_unquoted_safe) + { + // No need to quote or escape. Just convert the value straight into + // its place in the array, and "backspace" the trailing zero. + here = elt_traits::into_buf(here, end, elt) - 1; + } + else + { + *here++ = '"'; + + // Use the tail end of the destination buffer as an intermediate + // buffer. + auto const elt_budget{pqxx::size_buffer(elt)}; + for (char const c : elt_traits::to_buf(end - elt_budget, end, elt)) + { + if (c == '\\' or c == '"') + *here++ = '\\'; + *here++ = c; + } + *here++ = '"'; + } + *here++ = array_separator; + nonempty = true; + } + + // Erase that last comma, if present. + if (nonempty) + here--; + + *here++ = '}'; + *here++ = '\0'; + + return here; + } + + static std::size_t size_buffer(Container const &value) noexcept + { + if constexpr (is_unquoted_safe) + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + return acc + + (pqxx::is_null(elt) ? + std::size(s_null) : + elt_traits::size_buffer(elt)) - + 1; + }); + else + return 3 + std::accumulate( + std::begin(value), std::end(value), std::size_t{}, + [](std::size_t acc, elt_type const &elt) { + // Opening and closing quotes, plus worst-case escaping, + // but don't count the trailing zeroes. + std::size_t const elt_size{ + pqxx::is_null(elt) ? std::size(s_null) : + elt_traits::size_buffer(elt) - 1}; + return acc + 2 * elt_size + 2; + }); + } + + // We don't yet support parsing of array types using from_string. Doing so + // would require a reference to the connection. +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::vector const &) +{ + return format::text; +} + + +/// A `std::vector` is a binary string. Other vectors are not. +template +inline constexpr format param_format(std::vector const &) +{ + return format::binary; +} + + +template inline constexpr bool is_sql_array>{true}; + + +template +struct nullness> : no_null> +{}; + + +template +struct string_traits> + : internal::array_string_traits> +{}; + + +/// We don't know how to pass array params in binary format, so pass as text. +template +inline constexpr format param_format(std::array const &) +{ + return format::text; +} + + +/// An array of `std::byte` is a binary string. +template +inline constexpr format param_format(std::array const &) +{ + return format::binary; +} + + +template +inline constexpr bool is_sql_array>{true}; +} // namespace pqxx + + +namespace pqxx +{ +template inline std::string to_string(T const &value) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + std::string buf; + // We can't just reserve() space; modifying the terminating zero leads to + // undefined behaviour. + buf.resize(size_buffer(value)); + auto const data{buf.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(buf), value)}; + buf.resize(static_cast(end - data - 1)); + return buf; +} + + +template<> inline std::string to_string(float const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(long double const &value) +{ + return internal::to_string_float(value); +} +template<> inline std::string to_string(std::stringstream const &value) +{ + return value.str(); +} + + +template inline void into_string(T const &value, std::string &out) +{ + if (is_null(value)) + throw conversion_error{ + "Attempt to convert null " + type_name + " to a string."}; + + // We can't just reserve() data; modifying the terminating zero leads to + // undefined behaviour. + out.resize(size_buffer(value) + 1); + auto const data{out.data()}; + auto const end{ + string_traits::into_buf(data, data + std::size(out), value)}; + out.resize(static_cast(end - data - 1)); +} +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encoding_group.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encoding_group.hxx new file mode 100644 index 0000000..e17736e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encoding_group.hxx @@ -0,0 +1,60 @@ +/** Enum type for supporting encodings in libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODING_GROUP +#define PQXX_H_ENCODING_GROUP + +#include + +namespace pqxx::internal +{ +// Types of encodings supported by PostgreSQL, see +// https://www.postgresql.org/docs/current/static/multibyte.html#CHARSET-TABLE +enum class encoding_group +{ + // Handles all single-byte fixed-width encodings + MONOBYTE, + + // Multibyte encodings. + // Many of these can embed ASCII-like bytes inside multibyte characters, + // notably Big5, SJIS, SHIFT_JIS_2004, GP18030, GBK, JOHAB, UHC. + BIG5, + EUC_CN, + // TODO: Merge EUC_JP and EUC_JIS_2004? + EUC_JP, + EUC_JIS_2004, + EUC_KR, + EUC_TW, + GB18030, + GBK, + JOHAB, + MULE_INTERNAL, + // TODO: Merge SJIS and SHIFT_JIS_2004? + SJIS, + SHIFT_JIS_2004, + UHC, + UTF8, +}; + + +// TODO:: Can we just use string_view now? +/// Function type: "find the end of the current glyph." +/** This type of function takes a text buffer, and a location in that buffer, + * and returns the location one byte past the end of the current glyph. + * + * The start offset marks the beginning of the current glyph. It must fall + * within the buffer. + * + * There are multiple different glyph scanner implementations, for different + * kinds of encodings. + */ +using glyph_scanner_func = + std::size_t(char const buffer[], std::size_t buffer_len, std::size_t start); +} // namespace pqxx::internal + +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encodings.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encodings.hxx new file mode 100644 index 0000000..ba7fecc --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/encodings.hxx @@ -0,0 +1,90 @@ +/** Internal string encodings support for libpqxx + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ENCODINGS +#define PQXX_H_ENCODINGS + +#include "pqxx/internal/encoding_group.hxx" + +#include +#include + + +namespace pqxx::internal +{ +char const *name_encoding(int encoding_id); + +/// Convert libpq encoding enum or encoding name to its libpqxx group. +encoding_group enc_group(int /* libpq encoding ID */); +encoding_group enc_group(std::string_view); + + +/// Look up the glyph scanner function for a given encoding group. +/** To identify the glyph boundaries in a buffer, call this to obtain the + * scanner function appropriate for the buffer's encoding. Then, repeatedly + * call the scanner function to find the glyphs. + */ +PQXX_LIBEXPORT glyph_scanner_func *get_glyph_scanner(encoding_group); + + +// TODO: For ASCII search, treat UTF8/EUC_*/MULE_INTERNAL as MONOBYTE. + +/// Find any of the ASCII characters `NEEDLE` in `haystack`. +/** Scans through `haystack` until it finds a single-byte character that + * matches any value in `NEEDLE`. + * + * If it finds one, returns its offset. If not, returns the end of the + * haystack. + */ +template +inline std::size_t find_char( + glyph_scanner_func *scanner, std::string_view haystack, + std::size_t here = 0u) +{ + auto const sz{std::size(haystack)}; + auto const data{std::data(haystack)}; + while (here < sz) + { + auto next{scanner(data, sz, here)}; + // (For some reason gcc had a problem with a right-fold here. But clang + // was fine.) + if ((... or (data[here] == NEEDLE))) + { + // Also check against a multibyte character starting with a bytes which + // just happens to match one of the ASCII bytes we're looking for. It'd + // be cleaner to check that first, but either works. So, let's apply the + // most selective filter first and skip this check in almost all cases. + if (next == here + 1) + return here; + } + + // Nope, no hit. Move on. + here = next; + } + return sz; +} + + +/// Iterate over the glyphs in a buffer. +/** Scans the glyphs in the buffer, and for each, passes its begin and its + * one-past-end pointers to `callback`. + */ +template +inline void for_glyphs( + encoding_group enc, CALLABLE callback, char const buffer[], + std::size_t buffer_len, std::size_t start = 0) +{ + auto const scan{get_glyph_scanner(enc)}; + for (std::size_t here = start, next; here < buffer_len; here = next) + { + next = scan(buffer, buffer_len, here); + callback(buffer + here, buffer + next); + } +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-errorhandler.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-errorhandler.hxx new file mode 100644 index 0000000..ffc12a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-errorhandler.hxx @@ -0,0 +1,26 @@ +#include + +namespace pqxx +{ +class connection; +class errorhandler; +} // namespace pqxx + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_errorhandler : callgate +{ + friend class pqxx::errorhandler; + + connection_errorhandler(reference x) : super(x) {} + + void register_errorhandler(errorhandler *h) + { + home().register_errorhandler(h); + } + void unregister_errorhandler(errorhandler *h) + { + home().unregister_errorhandler(h); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-largeobject.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-largeobject.hxx new file mode 100644 index 0000000..49feaf9 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-largeobject.hxx @@ -0,0 +1,35 @@ +#include + +#include +#include + +namespace pqxx +{ +class blob; +class largeobject; +} // namespace pqxx + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + connection_largeobject(reference x) : super(x) {} + + pq::PGconn *raw_connection() const { return home().raw_connection(); } +}; + + +class PQXX_PRIVATE const_connection_largeobject : callgate +{ + friend class pqxx::blob; + friend class pqxx::largeobject; + + const_connection_largeobject(reference x) : super(x) {} + + std::string error_message() const { return home().err_msg(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-notification_receiver.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-notification_receiver.hxx new file mode 100644 index 0000000..0bcb2db --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-notification_receiver.hxx @@ -0,0 +1,29 @@ +#include + +#include "pqxx/connection.hxx" + + +namespace pqxx +{ +class notification_receiver; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_notification_receiver : callgate +{ + friend class pqxx::notification_receiver; + + connection_notification_receiver(reference x) : super(x) {} + + void add_receiver(notification_receiver *receiver) + { + home().add_receiver(receiver); + } + void remove_receiver(notification_receiver *receiver) noexcept + { + home().remove_receiver(receiver); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-pipeline.hxx new file mode 100644 index 0000000..c6ae6e1 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-pipeline.hxx @@ -0,0 +1,23 @@ +#include "pqxx/internal/libpq-forward.hxx" +#include + +#include "pqxx/pipeline.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_pipeline : callgate +{ + friend class pqxx::pipeline; + + connection_pipeline(reference x) : super(x) {} + + void start_exec(char const query[]) { home().start_exec(query); } + pqxx::internal::pq::PGresult *get_result() { return home().get_result(); } + void cancel_query() { home().cancel_query(); } + + bool consume_input() noexcept { return home().consume_input(); } + bool is_busy() const noexcept { return home().is_busy(); } + + int encoding_id() { return home().encoding_id(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-sql_cursor.hxx new file mode 100644 index 0000000..51a8898 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-sql_cursor.hxx @@ -0,0 +1,19 @@ +#include + +namespace pqxx::internal +{ +class sql_cursor; +} + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + connection_sql_cursor(reference x) : super(x) {} + + result exec(char const query[]) { return home().exec(query); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_from.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_from.hxx new file mode 100644 index 0000000..8961e71 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_from.hxx @@ -0,0 +1,15 @@ +#include + +#include "pqxx/connection.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_from : callgate +{ + friend class pqxx::stream_from; + + connection_stream_from(reference x) : super{x} {} + + auto read_copy_line() { return home().read_copy_line(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_to.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_to.hxx new file mode 100644 index 0000000..a6974fb --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-stream_to.hxx @@ -0,0 +1,17 @@ +#include + +#include "pqxx/stream_to.hxx" + + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_stream_to : callgate +{ + friend class pqxx::stream_to; + + connection_stream_to(reference x) : super(x) {} + + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-transaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-transaction.hxx new file mode 100644 index 0000000..74d6592 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/connection-transaction.hxx @@ -0,0 +1,44 @@ +#include + +namespace pqxx +{ +class connection; +} + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE connection_transaction : callgate +{ + friend class pqxx::transaction_base; + + connection_transaction(reference x) : super(x) {} + + template result exec(STRING query, std::string_view desc) + { + return home().exec(query, desc); + } + + void register_transaction(transaction_base *t) + { + home().register_transaction(t); + } + void unregister_transaction(transaction_base *t) noexcept + { + home().unregister_transaction(t); + } + + auto read_copy_line() { return home().read_copy_line(); } + void write_copy_line(std::string_view line) { home().write_copy_line(line); } + void end_copy_write() { home().end_copy_write(); } + + result exec_prepared(zview statement, internal::c_params const &args) + { + return home().exec_prepared(statement, args); + } + + result exec_params(zview query, internal::c_params const &args) + { + return home().exec_params(query, args); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/errorhandler-connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/errorhandler-connection.hxx new file mode 100644 index 0000000..5560ced --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/errorhandler-connection.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE errorhandler_connection : callgate +{ + friend class pqxx::connection; + + errorhandler_connection(reference x) : super(x) {} + + void unregister() noexcept { home().unregister(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx new file mode 100644 index 0000000..296d221 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursor_iterator_icursorstream : callgate +{ + friend class pqxx::icursorstream; + + icursor_iterator_icursorstream(reference x) : super(x) {} + + icursor_iterator::difference_type pos() const noexcept + { + return home().pos(); + } + + icursor_iterator *get_prev() { return home().m_prev; } + void set_prev(icursor_iterator *i) { home().m_prev = i; } + + icursor_iterator *get_next() { return home().m_next; } + void set_next(icursor_iterator *i) { home().m_next = i; } + + void fill(result const &r) { home().fill(r); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx new file mode 100644 index 0000000..56056d5 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx @@ -0,0 +1,32 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE icursorstream_icursor_iterator : callgate +{ + friend class pqxx::icursor_iterator; + + icursorstream_icursor_iterator(reference x) : super(x) {} + + void insert_iterator(icursor_iterator *i) noexcept + { + home().insert_iterator(i); + } + + void remove_iterator(icursor_iterator *i) const noexcept + { + home().remove_iterator(i); + } + + icursorstream::size_type forward() { return home().forward(); } + icursorstream::size_type forward(icursorstream::size_type n) + { + return home().forward(n); + } + + void service_iterators(icursorstream::difference_type p) + { + home().service_iterators(p); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-connection.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-connection.hxx new file mode 100644 index 0000000..daa0808 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-connection.hxx @@ -0,0 +1,14 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_connection : callgate +{ + friend class pqxx::connection; + + result_connection(reference x) : super(x) {} + + operator bool() const { return bool(home()); } + bool operator!() const { return not home(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-creation.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-creation.hxx new file mode 100644 index 0000000..3d9205f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-creation.hxx @@ -0,0 +1,24 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_creation : callgate +{ + friend class pqxx::connection; + friend class pqxx::pipeline; + + result_creation(reference x) : super(x) {} + + static result create( + internal::pq::PGresult *rhs, std::shared_ptr const &query, + encoding_group enc) + { + return result(rhs, query, enc); + } + + void check_status(std::string_view desc = ""sv) const + { + return home().check_status(desc); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-pipeline.hxx new file mode 100644 index 0000000..3ebe436 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-pipeline.hxx @@ -0,0 +1,16 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_pipeline : callgate +{ + friend class pqxx::pipeline; + + result_pipeline(reference x) : super(x) {} + + std::shared_ptr query_ptr() const + { + return home().query_ptr(); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-sql_cursor.hxx new file mode 100644 index 0000000..78b4507 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/result-sql_cursor.hxx @@ -0,0 +1,13 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE result_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + + result_sql_cursor(reference x) : super(x) {} + + char const *cmd_status() const noexcept { return home().cmd_status(); } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-sql_cursor.hxx new file mode 100644 index 0000000..4ed78dc --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-sql_cursor.hxx @@ -0,0 +1,10 @@ +#include + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_sql_cursor : callgate +{ + friend class pqxx::internal::sql_cursor; + transaction_sql_cursor(reference x) : super(x) {} +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-transaction_focus.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-transaction_focus.hxx new file mode 100644 index 0000000..ca7939a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/gates/transaction-transaction_focus.hxx @@ -0,0 +1,30 @@ +#include + +#include "pqxx/transaction_base.hxx" + +namespace pqxx::internal::gate +{ +class PQXX_PRIVATE transaction_transaction_focus : callgate +{ + friend class pqxx::transaction_focus; + + transaction_transaction_focus(reference x) : super(x) {} + + void register_focus(transaction_focus *focus) + { + home().register_focus(focus); + } + void unregister_focus(transaction_focus *focus) noexcept + { + home().unregister_focus(focus); + } + void register_pending_error(zview error) + { + home().register_pending_error(error); + } + void register_pending_error(std::string &&error) + { + home().register_pending_error(std::move(error)); + } +}; +} // namespace pqxx::internal::gate diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-post.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-post.hxx new file mode 100644 index 0000000..ff6bf89 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-post.hxx @@ -0,0 +1,22 @@ +/* Compiler deficiency workarounds for compiling libpqxx headers. + * + * To be included at the end of each libpqxx header, in order to restore the + * client program's settings. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +// NO GUARDS HERE! This code should be executed every time! + +#if defined(_MSC_VER) +# pragma warning(pop) // Restore compiler's warning state +#endif + +#if !defined(PQXX_HEADER_PRE) +# error "Include pqxx/internal/header-post.hxx AFTER its 'pre' counterpart." +#endif + +#undef PQXX_HEADER_PRE diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-pre.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-pre.hxx new file mode 100644 index 0000000..abc1a39 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/header-pre.hxx @@ -0,0 +1,169 @@ +/* Compiler settings for compiling libpqxx headers, and workarounds for all. + * + * Include this before including any other libpqxx headers from within libpqxx. + * And to balance it out, also include header-post.hxx at the end of the batch + * of headers. + * + * The public libpqxx headers (e.g. ``) include this already; + * there's no need to do this from within an application. + * + * Include this file at the highest aggregation level possible to avoid nesting + * and to keep things simple. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ + +// NO GUARD HERE! This part should be included every time this file is. +#if defined(_MSC_VER) + +// Save compiler's warning state, and set warning level 4 for maximum +// sensitivity to warnings. +# pragma warning(push, 4) + +// Visual C++ generates some entirely unreasonable warnings. Disable them. +// Copy constructor could not be generated. +# pragma warning(disable : 4511) +// Assignment operator could not be generated. +# pragma warning(disable : 4512) +// Can't expose outside classes without exporting them. Except the MSVC docs +// say please ignore the warning if it's a standard library class. +# pragma warning(disable : 4251) +// Can't derive library classes from outside classes without exporting them. +// Except the MSVC docs say please ignore the warning if the parent class is +// in the standard library. +# pragma warning(disable : 4275) +// Can't inherit from non-exported class. +# pragma warning(disable : 4275) + +#endif // _MSC_VER + + +#if defined(PQXX_HEADER_PRE) +# error "Avoid nesting #include of pqxx/internal/header-pre.hxx." +#endif + +#define PQXX_HEADER_PRE + + +// Workarounds & definitions that need to be included even in library's headers +#include "pqxx/config-public-compiler.h" + +// Enable ISO-646 alternative operaotr representations: "and" instead of "&&" +// etc. on older compilers. C++20 removes this header. +#if __has_include() +# include +#endif + + +#if defined(PQXX_HAVE_GCC_PURE) +/// Declare function "pure": no side effects, only reads globals and its args. +# define PQXX_PURE __attribute__((pure)) +#else +# define PQXX_PURE /* pure */ +#endif + + +#if defined(__GNUC__) +/// Tell the compiler to optimise a function for size, not speed. +# define PQXX_COLD __attribute__((cold)) +#else +# define PQXX_COLD /* cold */ +#endif + + +// Workarounds for Windows +#ifdef _WIN32 + +/* For now, export DLL symbols if _DLL is defined. This is done automatically + * by the compiler when linking to the dynamic version of the runtime library, + * according to "gzh" + */ +# if defined(PQXX_SHARED) && !defined(PQXX_LIBEXPORT) +# define PQXX_LIBEXPORT __declspec(dllimport) +# endif // PQXX_SHARED && !PQXX_LIBEXPORT + + +// Workarounds for Microsoft Visual C++ +# ifdef _MSC_VER + +// Suppress vtables on abstract classes. +# define PQXX_NOVTABLE __declspec(novtable) + +// Automatically link with the appropriate libpq (static or dynamic, debug or +// release). The default is to use the release DLL. Define PQXX_PQ_STATIC to +// link to a static version of libpq, and _DEBUG to link to a debug version. +// The two may be combined. +# if defined(PQXX_AUTOLINK) +# if defined(PQXX_PQ_STATIC) +# ifdef _DEBUG +# pragma comment(lib, "libpqd") +# else +# pragma comment(lib, "libpq") +# endif +# else +# ifdef _DEBUG +# pragma comment(lib, "libpqddll") +# else +# pragma comment(lib, "libpqdll") +# endif +# endif +# endif + +// If we're not compiling libpqxx itself, automatically link with the +// appropriate libpqxx library. To link with the libpqxx DLL, define +// PQXX_SHARED; the default is to link with the static library. A static link +// is the recommended practice. +// +// The preprocessor macro PQXX_INTERNAL is used to detect whether we +// are compiling the libpqxx library itself. When you compile the library +// yourself using your own project file, make sure to include this macro. +# if defined(PQXX_AUTOLINK) && !defined(PQXX_INTERNAL) +# ifdef PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxxD") +# else +# pragma comment(lib, "libpqxx") +# endif +# else // !PQXX_SHARED +# ifdef _DEBUG +# pragma comment(lib, "libpqxx_staticD") +# else +# pragma comment(lib, "libpqxx_static") +# endif +# endif +# endif + +# endif // _MSC_VER + +#elif defined(PQXX_HAVE_GCC_VISIBILITY) // !_WIN32 + +# define PQXX_LIBEXPORT __attribute__((visibility("default"))) +# define PQXX_PRIVATE __attribute__((visibility("hidden"))) + +#endif // PQXX_HAVE_GCC_VISIBILITY + + +#ifndef PQXX_LIBEXPORT +# define PQXX_LIBEXPORT /* libexport */ +#endif + +#ifndef PQXX_PRIVATE +# define PQXX_PRIVATE /* private */ +#endif + +#ifndef PQXX_NOVTABLE +# define PQXX_NOVTABLE /* novtable */ +#endif + +// C++20: Assume support. +#if defined(PQXX_HAVE_LIKELY) +# define PQXX_LIKELY [[likely]] +# define PQXX_UNLIKELY [[unlikely]] +#else +# define PQXX_LIKELY /* [[likely]] */ +# define PQXX_UNLIKELY /* [[unlikely]] */ +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-post.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-post.hxx new file mode 100644 index 0000000..cebcf05 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-post.hxx @@ -0,0 +1,15 @@ +/// End a code block started by "ignore-deprecated-pre.hxx". + +#if !defined(PQXX_IGNORING_DEPRECATED) +# error "Ended an 'ignore-deprecated' block while none was active." +#endif + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#undef PQXX_IGNORING_DEPRECATED diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-pre.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-pre.hxx new file mode 100644 index 0000000..8ac57af --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/ignore-deprecated-pre.hxx @@ -0,0 +1,28 @@ +/** Start a block of deprecated code which may call other deprecated code. + * + * Most compilers will emit warnings when deprecated code is invoked from + * non-deprecated code. But some compilers (notably gcc) will always emit the + * warning even when the calling code is also deprecated. + * + * This header starts a block where those warnings are suppressed. It can be + * included inside a code block. + * + * Always match the #include with a closing #include of + * "ignore-deprecated-post.hxx". To avoid mistakes, keep the enclosed area as + * small as possible. + */ +#if defined(PQXX_IGNORING_DEPRECATED) +# error "Started an 'ignore-deprecated' block inside another." +#endif + +#define PQXX_IGNORING_DEPRECATED + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4996) +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/libpq-forward.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/libpq-forward.hxx new file mode 100644 index 0000000..9e74f79 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/libpq-forward.hxx @@ -0,0 +1,31 @@ +/** Minimal forward declarations of libpq types needed in libpqxx headers. + * + * DO NOT INCLUDE THIS FILE when building client programs. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +extern "C" +{ + struct pg_conn; + struct pg_result; + struct pgNotify; +} + +/// Forward declarations of libpq types as needed in libpqxx headers. +namespace pqxx::internal::pq +{ +using PGconn = pg_conn; +using PGresult = pg_result; +using PGnotify = pgNotify; +using PQnoticeProcessor = void (*)(void *, char const *); +} // namespace pqxx::internal::pq + +namespace pqxx +{ +/// PostgreSQL database row identifier. +using oid = unsigned int; +} // namespace pqxx diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iter.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iter.hxx new file mode 100644 index 0000000..1fa1f7d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iter.hxx @@ -0,0 +1,124 @@ +/** Result loops. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITER +#define PQXX_H_RESULT_ITER + +#include + +#include "pqxx/strconv.hxx" + +namespace pqxx +{ +class result; +} // namespace pqxx + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Iterator for looped unpacking of a result. +template class result_iter +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + result_iter() = default; + + explicit result_iter(result const &home) : + m_home{&home}, m_size{std::size(home)} + { + if (not std::empty(home)) + read(); + } + result_iter(result_iter const &) = default; + + result_iter &operator++() + { + m_index++; + if (m_index >= m_size) + m_home = nullptr; + else + read(); + return *this; + } + + /// Comparison only works for comparing to end(). + bool operator==(result_iter const &rhs) const + { + return m_home == rhs.m_home; + } + bool operator!=(result_iter const &rhs) const { return not(*this == rhs); } + + value_type const &operator*() const { return m_value; } + +private: + void read() { (*m_home)[m_index].convert(m_value); } + + result const *m_home{nullptr}; + result::size_type m_index{0}; + result::size_type m_size; + value_type m_value; +}; + + +template class result_iteration +{ +public: + using iterator = result_iter; + explicit result_iteration(result const &home) : m_home{home} + { + constexpr auto tup_size{sizeof...(TYPE)}; + if (home.columns() != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", to_string(tup_size), + " field(s) from a result with ", to_string(home.columns()), + " column(s).")}; + } + iterator begin() const + { + if (std::size(m_home) == 0) + return end(); + else + return iterator{m_home}; + } + iterator end() const { return {}; } + +private: + pqxx::result const &m_home; +}; +} // namespace pqxx::internal + + +template inline auto pqxx::result::iter() const +{ + return pqxx::internal::result_iteration{*this}; +} + + +template +inline void pqxx::result::for_each(CALLABLE &&func) const +{ + using args_tuple = internal::args_t; + constexpr auto sz{std::tuple_size_v}; + static_assert( + sz > 0, + "Callback for for_each must take parameters, one for each column in the " + "result."); + + auto const cols{this->columns()}; + if (sz != cols) + throw usage_error{internal::concat( + "Callback to for_each takes ", sz, "parameter", (sz == 1) ? "" : "s", + ", but result set has ", cols, "field", (cols == 1) ? "" : "s", ".")}; + + using pass_tuple = pqxx::internal::strip_types_t; + for (auto const r : *this) std::apply(func, r.as_tuple()); +} +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iterator.hxx new file mode 100644 index 0000000..3f27a1d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/result_iterator.hxx @@ -0,0 +1,389 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT_ITERATOR +#define PQXX_H_RESULT_ITERATOR + +#include "pqxx/row.hxx" + + +/* Result iterator. + * + * Don't include this header from your own application; it is included for you + * by other libpqxx headers. + */ + +namespace pqxx +{ +/// Iterator for rows in a result. Use as result::const_iterator. +/** A result, once obtained, cannot be modified. Therefore there is no + * plain iterator type for result. However its const_iterator type can be + * used to inspect its rows without changing them. + */ +class PQXX_LIBEXPORT const_result_iterator : public row +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = row const; + using pointer = row const *; + using reference = row; + using size_type = result_size_type; + using difference_type = result_difference_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create an iterator, but in an unusable state. + const_result_iterator() noexcept = default; + /// Copy an iterator. + const_result_iterator(const_result_iterator const &) noexcept = default; + /// Move an iterator. + const_result_iterator(const_result_iterator &&) noexcept = default; + + /// Begin iterating a @ref row. + const_result_iterator(row const &t) noexcept : row{t} {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /** + * @name Dereferencing operators + * + * An iterator "points to" its own row, which is also itself. This makes it + * easy to address a @ref result as a two-dimensional container, without + * going through the intermediate step of dereferencing the iterator. It + * makes the interface similar to C pointer/array semantics. + * + * IIRC Alex Stepanov, the inventor of the STL, once remarked that having + * this as standard behaviour for pointers would be useful in some + * algorithms. So even if this makes me look foolish, I would seem to be in + * distinguished company. + */ + //@{ + /// Dereference the iterator. + [[nodiscard]] pointer operator->() const { return this; } + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Dereference the iterator. + [[nodiscard]] reference operator*() const { return *this; } +#include "pqxx/internal/ignore-deprecated-post.hxx" + //@} + + /** + * @name Field access + */ + //@{ + using row::back; + using row::front; + using row::operator[]; + using row::at; + using row::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_result_iterator &operator=(const_result_iterator const &rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(rhs); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator &operator=(const_result_iterator &&rhs) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::operator=(std::move(rhs)); +#include "pqxx/internal/ignore-deprecated-post.hxx" + return *this; + } + + const_result_iterator operator++(int); + const_result_iterator &operator++() + { + ++m_index; + return *this; + } + const_result_iterator operator--(int); + const_result_iterator &operator--() + { + --m_index; + return *this; + } + + const_result_iterator &operator+=(difference_type i) + { + m_index += i; + return *this; + } + const_result_iterator &operator-=(difference_type i) + { + m_index -= i; + return *this; + } + + /// Interchange two iterators in an exception-safe manner. + void swap(const_result_iterator &other) noexcept + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row::swap(other); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool operator==(const_result_iterator const &i) const + { + return m_index == i.m_index; + } + [[nodiscard]] bool operator!=(const_result_iterator const &i) const + { + return m_index != i.m_index; + } + [[nodiscard]] bool operator<(const_result_iterator const &i) const + { + return m_index < i.m_index; + } + [[nodiscard]] bool operator<=(const_result_iterator const &i) const + { + return m_index <= i.m_index; + } + [[nodiscard]] bool operator>(const_result_iterator const &i) const + { + return m_index > i.m_index; + } + [[nodiscard]] bool operator>=(const_result_iterator const &i) const + { + return m_index >= i.m_index; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_result_iterator operator+(difference_type) const; + friend const_result_iterator + operator+(difference_type, const_result_iterator const &); + [[nodiscard]] inline const_result_iterator operator-(difference_type) const; + [[nodiscard]] inline difference_type + operator-(const_result_iterator const &) const; + //@} + +private: + friend class pqxx::result; + const_result_iterator(pqxx::result const *r, result_size_type i) noexcept : + row{*r, i, r->columns()} + {} +}; + + +/// Reverse iterator for result. Use as result::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_result_iterator + : private const_result_iterator +{ +public: + using super = const_result_iterator; + using iterator_type = const_result_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + /// Create an iterator, but in an unusable state. + const_reverse_result_iterator() = default; + /// Copy an iterator. + const_reverse_result_iterator(const_reverse_result_iterator const &rhs) = + default; + /// Copy a reverse iterator from a regular iterator. + explicit const_reverse_result_iterator(const_result_iterator const &rhs) : + const_result_iterator{rhs} + { + super::operator--(); + } + + /// Move a regular iterator into a reverse iterator. + explicit const_reverse_result_iterator(const_result_iterator const &&rhs) : + const_result_iterator{std::move(rhs)} + { + super::operator--(); + } + + /// Return the underlying "regular" iterator (as per standard library). + [[nodiscard]] PQXX_PURE const_result_iterator base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + /// Dereference iterator. + using const_result_iterator::operator->; + /// Dereference iterator. + using const_result_iterator::operator*; + //@} + + /** + * @name Field access + */ + //@{ + using const_result_iterator::back; + using const_result_iterator::front; + using const_result_iterator::operator[]; + using const_result_iterator::at; + using const_result_iterator::rownumber; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_result_iterator & + operator=(const_reverse_result_iterator const &r) + { + iterator_type::operator=(r); + return *this; + } + const_reverse_result_iterator &operator=(const_reverse_result_iterator &&r) + { + iterator_type::operator=(std::move(r)); + return *this; + } + const_reverse_result_iterator &operator++() + { + iterator_type::operator--(); + return *this; + } + const_reverse_result_iterator operator++(int); + const_reverse_result_iterator &operator--() + { + iterator_type::operator++(); + return *this; + } + const_reverse_result_iterator operator--(int); + const_reverse_result_iterator &operator+=(difference_type i) + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_result_iterator &operator-=(difference_type i) + { + iterator_type::operator+=(i); + return *this; + } + + void swap(const_reverse_result_iterator &other) noexcept + { + const_result_iterator::swap(other); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_result_iterator + operator+(difference_type i) const + { + return const_reverse_result_iterator(base() - i); + } + [[nodiscard]] const_reverse_result_iterator operator-(difference_type i) + { + return const_reverse_result_iterator(base() + i); + } + [[nodiscard]] difference_type + operator-(const_reverse_result_iterator const &rhs) const + { + return rhs.const_result_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_result_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_result_iterator const &rhs) const noexcept + { + return not operator==(rhs); + } + + [[nodiscard]] bool operator<(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] bool operator<=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] bool operator>(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] bool operator>=(const_reverse_result_iterator const &rhs) const + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +inline const_result_iterator +const_result_iterator::operator+(result::difference_type o) const +{ + return {&m_result, size_type(result::difference_type(m_index) + o)}; +} + +inline const_result_iterator +operator+(result::difference_type o, const_result_iterator const &i) +{ + return i + o; +} + +inline const_result_iterator +const_result_iterator::operator-(result::difference_type o) const +{ + return {&m_result, result_size_type(result::difference_type(m_index) - o)}; +} + +inline result::difference_type +const_result_iterator::operator-(const const_result_iterator &i) const +{ + return result::difference_type(num() - i.num()); +} + +inline const_result_iterator result::end() const noexcept +{ + return {this, size()}; +} + + +inline const_result_iterator result::cend() const noexcept +{ + return end(); +} + + +inline const_reverse_result_iterator +operator+(result::difference_type n, const_reverse_result_iterator const &i) +{ + return const_reverse_result_iterator{i.base() - n}; +} + +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/sql_cursor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/sql_cursor.hxx new file mode 100644 index 0000000..a26d063 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/sql_cursor.hxx @@ -0,0 +1,118 @@ +/** Internal wrapper for SQL cursors. Supports higher-level cursor classes. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SQL_CURSOR +#define PQXX_H_SQL_CURSOR + +namespace pqxx::internal +{ +/// Cursor with SQL positioning semantics. +/** Thin wrapper around an SQL cursor, with SQL's ideas of positioning. + * + * SQL cursors have pre-increment/pre-decrement semantics, with on either end + * of the result set a special position that does not repesent a row. This + * class models SQL cursors for the purpose of implementing more C++-like + * semantics on top. + * + * Positions of actual rows are numbered starting at 1. Position 0 exists but + * does not refer to a row. There is a similar non-row position at the end of + * the result set. + * + * Don't use this at home. You deserve better. Use the stateles_cursor + * instead. + */ +class PQXX_LIBEXPORT sql_cursor : public cursor_base +{ +public: + sql_cursor( + transaction_base &t, std::string_view query, std::string_view cname, + cursor_base::access_policy ap, cursor_base::update_policy up, + cursor_base::ownership_policy op, bool hold); + + sql_cursor( + transaction_base &t, std::string_view cname, + cursor_base::ownership_policy op); + + ~sql_cursor() noexcept { close(); } + + result fetch(difference_type rows, difference_type &displacement); + result fetch(difference_type rows) + { + difference_type d = 0; + return fetch(rows, d); + } + difference_type move(difference_type rows, difference_type &displacement); + difference_type move(difference_type rows) + { + difference_type d = 0; + return move(rows, d); + } + + /// Current position, or -1 for unknown + /** + * The starting position, just before the first row, counts as position zero. + * + * Position may be unknown if (and only if) this cursor was adopted, and has + * never hit its starting position (position zero). + */ + difference_type pos() const noexcept { return m_pos; } + + /// End position, or -1 for unknown + /** + * Returns the final position, just after the last row in the result set. The + * starting position, just before the first row, counts as position zero. + * + * End position is unknown until it is encountered during use. + */ + difference_type endpos() const noexcept { return m_endpos; } + + /// Return zero-row result for this cursor. + result const &empty_result() const noexcept { return m_empty_result; } + + void close() noexcept; + +private: + difference_type adjust(difference_type hoped, difference_type actual); + static std::string stridestring(difference_type); + /// Initialize cached empty result. Call only at beginning or end! + void init_empty_result(transaction_base &); + + /// Connection in which this cursor lives. + connection &m_home; + + /// Zero-row result from this cursor (or plain empty one if cursor is + /// adopted) + result m_empty_result; + + result m_cached_current_row; + + /// Is this cursor adopted (as opposed to created by this cursor object)? + bool m_adopted; + + /// Will this cursor object destroy its SQL cursor when it dies? + cursor_base::ownership_policy m_ownership; + + /// At starting position (-1), somewhere in the middle (0), or past end (1) + int m_at_end; + + /// Position, or -1 for unknown + difference_type m_pos; + + /// End position, or -1 for unknown + difference_type m_endpos = -1; +}; + + +PQXX_LIBEXPORT result_size_type obtain_stateless_cursor_size(sql_cursor &); +PQXX_LIBEXPORT result stateless_cursor_retrieve( + sql_cursor &, result::difference_type size, + result::difference_type begin_pos, result::difference_type end_pos); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/statement_parameters.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/statement_parameters.hxx new file mode 100644 index 0000000..b078bf6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/statement_parameters.hxx @@ -0,0 +1,131 @@ +/** Common implementation for statement parameter lists. + * + * These are used for both prepared statements and parameterized statements. + * + * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STATEMENT_PARAMETER +#define PQXX_H_STATEMENT_PARAMETER + +#include +#include +#include +#include +#include + +#include "pqxx/binarystring.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/util.hxx" + + +namespace pqxx::internal +{ +template +constexpr inline auto const iterator_identity{ + [](decltype(*std::declval()) x) { return x; }}; + + +/// Marker type: pass a dynamically-determined number of statement parameters. +/** @deprecated Use @ref params instead. + * + * Normally when invoking a prepared or parameterised statement, the number + * of parameters is known at compile time. For instance, + * `t.exec_prepared("foo", 1, "x");` executes statement `foo` with two + * parameters, an `int` and a C string. + * + * But sometimes you may want to pass a number of parameters known only at run + * time. In those cases, a @ref dynamic_params encodes a dynamically + * determined number of parameters. You can mix these with regular, static + * parameter lists, and you can re-use them for multiple statement invocations. + * + * A dynamic_params object does not store copies of its parameters, so make + * sure they remain accessible until you've executed the statement. + * + * The ACCESSOR is an optional callable (such as a lambda). If you pass an + * accessor `a`, then each parameter `p` goes into your statement as `a(p)`. + */ +template)> +class dynamic_params +{ +public: + /// Wrap a sequence of pointers or iterators. + constexpr dynamic_params(IT begin, IT end) : + m_begin(begin), m_end(end), m_accessor(iterator_identity) + {} + + /// Wrap a sequence of pointers or iterators. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + constexpr dynamic_params(IT begin, IT end, ACCESSOR &acc) : + m_begin(begin), m_end(end), m_accessor(acc) + {} + + /// Wrap a container. + template + explicit constexpr dynamic_params(C &container) : + dynamic_params(std::begin(container), std::end(container)) + {} + + /// Wrap a container. + /** This version takes an accessor callable. If you pass an accessor `acc`, + * then any parameter `p` will go into the statement's parameter list as + * `acc(p)`. + */ + template + explicit constexpr dynamic_params(C &container, ACCESSOR &acc) : + dynamic_params(std::begin(container), std::end(container), acc) + {} + + constexpr IT begin() const noexcept { return m_begin; } + constexpr IT end() const noexcept { return m_end; } + + constexpr auto access(decltype(*std::declval()) value) const + -> decltype(std::declval()(value)) + { + return m_accessor(value); + } + +private: + IT const m_begin, m_end; + ACCESSOR m_accessor = iterator_identity; +}; + + +/// Internal type: encode statement parameters. +/** Compiles arguments for prepared statements and parameterised queries into + * a format that can be passed into libpq. + * + * Objects of this type are meant to be short-lived: a `c_params` lives and + * dies entirely within the call to execute. So, for example, if you pass in a + * non-null pointer as a parameter, @ref params may simply use that pointer as + * a parameter value, without arranging longer-term storage for the data to + * which it points. All values referenced by parameters must remain "live" + * until the parameterised or prepared statement has been executed. + */ +struct PQXX_LIBEXPORT c_params +{ + c_params() = default; + /// Copying these objects is pointless and expensive. Don't do it. + c_params(c_params const &) = delete; + c_params(c_params &&) = default; + + /// Pre-allocate storage for `n` parameters. + void reserve(std::size_t n) &; + + /// As used by libpq: pointers to parameter values. + std::vector values; + /// As used by libpq: lengths of non-null arguments, in bytes. + std::vector lengths; + /// As used by libpq: effectively boolean "is this a binary parameter?" + std::vector formats; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/stream_iterator.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/stream_iterator.hxx new file mode 100644 index 0000000..f240dcf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/stream_iterator.hxx @@ -0,0 +1,105 @@ +/** Stream iterators. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_ITERATOR +#define PQXX_H_STREAM_ITERATOR + +#include + +namespace pqxx +{ +class stream_from; +} + + +namespace pqxx::internal +{ +// C++20: Replace with generator? +/// Input iterator for stream_from. +/** Just barely enough to support range-based "for" loops. Don't assume that + * any of the usual behaviour works beyond that. + */ +template class stream_input_iterator +{ +public: + using value_type = std::tuple; + + /// Construct an "end" iterator. + stream_input_iterator() = default; + + explicit stream_input_iterator(stream_from &home) : m_home(&home) + { + advance(); + } + stream_input_iterator(stream_input_iterator const &) = default; + + stream_input_iterator &operator++() + { + advance(); + return *this; + } + + value_type const &operator*() const { return m_value; } + + /// Comparison only works for comparing to end(). + bool operator==(stream_input_iterator const &rhs) const + { + return m_home == rhs.m_home; + } + /// Comparison only works for comparing to end(). + bool operator!=(stream_input_iterator const &rhs) const + { + return not(*this == rhs); + } + +private: + void advance() + { + if (m_home == nullptr) + throw usage_error{"Moving stream_from iterator beyond end()."}; + if (not((*m_home) >> m_value)) + m_home = nullptr; + } + + stream_from *m_home{nullptr}; + value_type m_value; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from. +template class stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit stream_input_iteration(stream_from &home) : m_home{home} {} + iterator begin() const { return iterator{m_home}; } + iterator end() const { return {}; } + +private: + stream_from &m_home; +}; + + +// C++20: Replace with generator? +/// Iteration over a @ref stream_from, deleting it once done. +template class owning_stream_input_iteration +{ +public: + using iterator = stream_input_iterator; + explicit owning_stream_input_iteration(std::unique_ptr &&home) : + m_home{std::move(home)} + {} + iterator begin() const { return iterator{*m_home.get()}; } + iterator end() const { return {}; } + +private: + std::unique_ptr m_home; +}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/wait.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/wait.hxx new file mode 100644 index 0000000..7a82e65 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/internal/wait.hxx @@ -0,0 +1,18 @@ +#if !defined(PQXX_WAIT_HXX) +# define PQXX_WAIT_HXX + +namespace pqxx::internal +{ +/// Wait. +/** This is normally `std::this_thread::sleep_for()`. But MinGW's `thread` + * header doesn't work, so we must be careful about including it. + */ +void PQXX_LIBEXPORT wait_for(unsigned int microseconds); + + +/// Wait for a socket to be ready for reading/writing, or timeout. +PQXX_LIBEXPORT void wait_fd( + int fd, bool for_read, bool for_write, unsigned seconds = 1, + unsigned microseconds = 0); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation new file mode 100644 index 0000000..1b80132 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation @@ -0,0 +1,8 @@ +/** Transaction isolation levels. + * + * Policies and traits describing SQL transaction isolation levels + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation.hxx new file mode 100644 index 0000000..0698c6a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/isolation.hxx @@ -0,0 +1,75 @@ +/* Definitions for transaction isolation levels, and such. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/isolation instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ISOLATION +#define PQXX_H_ISOLATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Should a transaction be read-only, or read-write? +/** No, this is not an isolation level. So it really doesn't belong here. + * But it's not really worth a separate header. + */ +enum class write_policy +{ + read_only, + read_write +}; + + +/// Transaction isolation levels. +/** These are as defined in the SQL standard. But there are a few notes + * specific to PostgreSQL. + * + * First, postgres does not support "read uncommitted." The lowest level you + * can get is "read committed," which is better. PostgreSQL is built on the + * MVCC paradigm, which guarantees "read committed" isolation without any + * additional performance overhead, so there was no point in providing the + * lower level. + * + * Second, "repeatable read" also makes more isolation guarantees than the + * standard requires. According to the standard, this level prevents "dirty + * reads" and "nonrepeatable reads," but not "phantom reads." In postgres, + * it actually prevents all three. + * + * Third, "serializable" is only properly supported starting at postgres 9.1. + * If you request "serializable" isolation on an older backend, you will get + * the same isolation as in "repeatable read." It's better than the + * "repeatable read" defined in the SQL standard, but not a complete + * implementation of the standard's "serializable" isolation level. + * + * In general, a lower isolation level will allow more surprising interactions + * between ongoing transactions, but improve performance. A higher level + * gives you more protection from subtle concurrency bugs, but sometimes it + * may not be possible to complete your transaction without avoiding paradoxes + * in the data. In that case a transaction may fail, and the application will + * have to re-do the whole thing based on the latest state of the database. + * (If you want to retry your code in that situation, have a look at the + * transactor framework.) + * + * Study the levels and design your application with the right level in mind. + */ +enum isolation_level +{ + // PostgreSQL only has the better isolation levels. + // read_uncommitted, + + read_committed, + repeatable_read, + serializable, +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject new file mode 100644 index 0000000..1f2f947 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject @@ -0,0 +1,8 @@ +/** Large Objects interface. + * + * Supports direct access to large objects, as well as through I/O streams + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject.hxx new file mode 100644 index 0000000..ebafc51 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/largeobject.hxx @@ -0,0 +1,735 @@ +/* Large Objects interface. Deprecated; use blob instead. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_LARGEOBJECT +#define PQXX_H_LARGEOBJECT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/dbtransaction.hxx" + + +namespace pqxx +{ +/// Identity of a large object. +/** @deprecated Use the @ref blob class instead. + * + * Encapsulates the identity of a large object. + * + * A largeobject must be accessed only from within a backend transaction, but + * the object's identity remains valid as long as the object exists. + */ +class PQXX_LIBEXPORT largeobject +{ +public: + using size_type = large_object_size_type; + + /// Refer to a nonexistent large object (similar to what a null pointer + /// does). + [[deprecated("Use blob instead.")]] largeobject() noexcept = default; + + /// Create new large object. + /** @param t Backend transaction in which the object is to be created. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(dbtransaction &t); + + /// Wrap object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param o Object identifier for the given object. + */ + [[deprecated("Use blob instead.")]] explicit largeobject(oid o) noexcept : + m_id{o} + {} + + /// Import large object from a local file. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + */ + [[deprecated("Use blob instead.")]] largeobject( + dbtransaction &t, std::string_view file); + + /// Take identity of an opened large object. + /** Copy identity of already opened large object. Note that this may be done + * as an implicit conversion. + * @param o Already opened large object to copy identity from. + */ + [[deprecated("Use blob instead.")]] largeobject( + largeobjectaccess const &o) noexcept; + + /// Object identifier. + /** The number returned by this function identifies the large object in the + * database we're connected to (or oid_none is returned if we refer to the + * null object). + */ + [[nodiscard]] oid id() const noexcept { return m_id; } + + /** + * @name Identity comparisons + * + * These operators compare the object identifiers of large objects. This has + * nothing to do with the objects' actual contents; use them only for keeping + * track of containers of references to large objects and such. + */ + //@{ + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator==(largeobject const &other) const + { + return m_id == other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator!=(largeobject const &other) const + { + return m_id != other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<=(largeobject const &other) const + { + return m_id <= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>=(largeobject const &other) const + { + return m_id >= other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator<(largeobject const &other) const + { + return m_id < other.m_id; + } + /// Compare object identities + /** @warning Only valid between large objects in the same database. */ + [[nodiscard]] bool operator>(largeobject const &other) const + { + return m_id > other.m_id; + } + //@} + + /// Export large object's contents to a local file + /** Writes the data stored in the large object to the given file. + * @param t Transaction in which the object is to be accessed + * @param file A filename on the client's filesystem + */ + void to_file(dbtransaction &t, std::string_view file) const; + + /// Delete large object from database + /** Unlike its low-level equivalent cunlink, this will throw an exception if + * deletion fails. + * @param t Transaction in which the object is to be deleted + */ + void remove(dbtransaction &t) const; + +protected: + PQXX_PURE static internal::pq::PGconn * + raw_connection(dbtransaction const &T); + + PQXX_PRIVATE std::string reason(connection const &, int err) const; + +private: + oid m_id = oid_none; +}; + + +/// Accessor for large object's contents. +/** @deprecated Use the `blob` class instead. + */ +class PQXX_LIBEXPORT largeobjectaccess : private largeobject +{ +public: + using largeobject::size_type; + using off_type = size_type; + using pos_type = size_type; + + /// Open mode: `in`, `out` (can be combined using "bitwise or"). + /** According to the C++ standard, these should be in `std::ios_base`. We + * take them from derived class `std::ios` instead, which is easier on the + * eyes. + * + * Historical note: taking it from std::ios was originally a workaround for a + * problem with gcc 2.95. + */ + using openmode = std::ios::openmode; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + + /// Seek direction: `beg`, `cur`, `end`. + using seekdir = std::ios::seekdir; + + /// Create new large object and open it. + /** + * @param t Backend transaction in which the object is to be created. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] explicit largeobjectaccess( + dbtransaction &t, openmode mode = default_mode); + + /// Open large object with given oid. + /** Convert combination of a transaction and object identifier into a + * large object identity. Does not affect the database. + * @param t Transaction in which the object is to be accessed. + * @param o Object identifier for the given object. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, oid o, openmode mode = default_mode); + + /// Open given large object. + /** Open a large object with the given identity for reading and/or writing. + * @param t Transaction in which the object is to be accessed. + * @param o Identity for the large object to be accessed. + * @param mode Access mode, defaults to ios_base::in | ios_base::out | + * ios_base::binary. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, largeobject o, openmode mode = default_mode); + + /// Import large object from a local file and open it. + /** Creates a large object containing the data found in the given file. + * @param t Backend transaction in which the large object is to be created. + * @param file A filename on the client program's filesystem. + * @param mode Access mode, defaults to ios_base::in | ios_base::out. + */ + [[deprecated("Use blob instead.")]] largeobjectaccess( + dbtransaction &t, std::string_view file, openmode mode = default_mode); + + ~largeobjectaccess() noexcept { close(); } + + /// Object identifier. + /** The number returned by this function uniquely identifies the large object + * in the context of the database we're connected to. + */ + using largeobject::id; + + /// Export large object's contents to a local file. + /** Writes the data stored in the large object to the given file. + * @param file A filename on the client's filesystem. + */ + void to_file(std::string_view file) const + { + largeobject::to_file(m_trans, file); + } + + using largeobject::to_file; + + /** + * @name High-level access to object contents. + */ + //@{ + /// Write data to large object. + /** @warning The size of a write is currently limited to 2GB. + * + * @param buf Data to write. + * @param len Number of bytes from Buf to write. + */ + void write(char const buf[], std::size_t len); + + /// Write string to large object. + /** If not all bytes could be written, an exception is thrown. + * @param buf Data to write; no terminating zero is written. + */ + void write(std::string_view buf) { write(std::data(buf), std::size(buf)); } + + /// Read data from large object. + /** Throws an exception if an error occurs while reading. + * @param buf Location to store the read data in. + * @param len Number of bytes to try and read. + * @return Number of bytes read, which may be less than the number requested + * if the end of the large object is reached. + */ + size_type read(char buf[], std::size_t len); + + /// Seek in large object's data stream. + /** Throws an exception if an error occurs. + * @return The new position in the large object + */ + size_type seek(size_type dest, seekdir dir); + + /// Report current position in large object's data stream. + /** Throws an exception if an error occurs. + * @return The current position in the large object. + */ + [[nodiscard]] size_type tell() const; + //@} + + /** + * @name Low-level access to object contents. + * + * These functions provide a more "C-like" access interface, returning + * special values instead of throwing exceptions on error. These functions + * are generally best avoided in favour of the high-level access functions, + * which behave more like C++ functions should. + * + * Due to libpq's underlying API, some operations are limited to "int" + * sizes, typically 2 GB, even though a large object can grow much larger. + */ + //@{ + /// Seek in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param dest Offset to go to. + * @param dir Origin to which dest is relative: ios_base::beg (from beginning + * of the object), ios_base::cur (from current access position), or + * ios_base;:end (from end of object). + * @return New position in large object, or -1 if an error occurred. + */ + pos_type cseek(off_type dest, seekdir dir) noexcept; + + /// Write to large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Data to write. + * @param len Number of bytes to write. + * @return Number of bytes actually written, or -1 if an error occurred. + */ + off_type cwrite(char const buf[], std::size_t len) noexcept; + + /// Read from large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @param buf Area where incoming bytes should be stored. + * @param len Number of bytes to read. + * @return Number of bytes actually read, or -1 if an error occurred.. + */ + off_type cread(char buf[], std::size_t len) noexcept; + + /// Report current position in large object's data stream. + /** Does not throw exception in case of error; inspect return value and + * `errno` instead. + * @return Current position in large object, of -1 if an error occurred. + */ + [[nodiscard]] pos_type ctell() const noexcept; + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Issue message to transaction's notice processor. + void process_notice(zview) noexcept; + //@} + + using largeobject::remove; + + using largeobject::operator==; + using largeobject::operator!=; + using largeobject::operator<; + using largeobject::operator<=; + using largeobject::operator>; + using largeobject::operator>=; + + largeobjectaccess() = delete; + largeobjectaccess(largeobjectaccess const &) = delete; + largeobjectaccess operator=(largeobjectaccess const &) = delete; + +private: + PQXX_PRIVATE std::string reason(int err) const; + internal::pq::PGconn *raw_connection() const + { + return largeobject::raw_connection(m_trans); + } + + PQXX_PRIVATE void open(openmode mode); + void close() noexcept; + + dbtransaction &m_trans; + int m_fd = -1; +}; + + +/// Streambuf to use large objects in standard I/O streams. +/** @deprecated Access large objects directly using the @ref blob class. + * + * The standard streambuf classes provide uniform access to data storage such + * as files or string buffers, so they can be accessed using standard input or + * output streams. This streambuf implementation provided similar access to + * large objects, so they could be read and written using the same stream + * classes. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class largeobject_streambuf : public std::basic_streambuf +{ + using size_type = largeobject::size_type; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + using openmode = largeobjectaccess::openmode; + using seekdir = largeobjectaccess::seekdir; + + /// Default open mode: in, out, binary. + static constexpr auto default_mode{ + std::ios::in | std::ios::out | std::ios::binary}; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, largeobject o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + [[deprecated("Use blob instead.")]] largeobject_streambuf( + dbtransaction &t, oid o, openmode mode = default_mode, + size_type buf_size = 512) : + m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr} + { + initialize(mode); + } + + virtual ~largeobject_streambuf() noexcept + { + delete[] m_p; + delete[] m_g; + } + + /// For use by large object stream classes. + void process_notice(zview const &s) { m_obj.process_notice(s); } + +protected: + virtual int sync() override + { + // setg() sets eback, gptr, egptr. + this->setg(this->eback(), this->eback(), this->egptr()); + return overflow(eof()); + } + + virtual pos_type seekoff(off_type offset, seekdir dir, openmode) override + { + return adjust_eof(m_obj.cseek(largeobjectaccess::off_type(offset), dir)); + } + + virtual pos_type seekpos(pos_type pos, openmode) override + { + largeobjectaccess::pos_type const newpos{ + m_obj.cseek(largeobjectaccess::off_type(pos), std::ios::beg)}; + return adjust_eof(newpos); + } + + virtual int_type overflow(int_type ch) override + { + auto *const pp{this->pptr()}; + if (pp == nullptr) + return eof(); + auto *const pb{this->pbase()}; + int_type res{0}; + + if (pp > pb) + { + auto const write_sz{pp - pb}; + auto const written_sz{ + m_obj.cwrite(pb, static_cast(pp - pb))}; + if (internal::cmp_less_equal(written_sz, 0)) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + "libpq reports error"}; + else if (write_sz != written_sz) + throw internal_error{ + "pqxx::largeobject: write failed " + "(is transaction still valid on write or flush?), " + + std::to_string(written_sz) + "/" + std::to_string(write_sz) + + " bytes written"}; + auto const out{adjust_eof(written_sz)}; + + if constexpr (std::is_arithmetic_v) + res = check_cast(out, "largeobject position"sv); + else + res = int_type(out); + } + this->setp(m_p, m_p + m_bufsize); + + // Write that one more character, if it's there. + if (ch != eof()) + { + *this->pptr() = static_cast(ch); + this->pbump(1); + } + return res; + } + + virtual int_type overflow() { return overflow(eof()); } + + virtual int_type underflow() override + { + if (this->gptr() == nullptr) + return eof(); + auto *const eb{this->eback()}; + auto const res{adjust_eof( + m_obj.cread(this->eback(), static_cast(m_bufsize)))}; + this->setg( + eb, eb, eb + (res == eof() ? 0 : static_cast(res))); + return (res == eof() or res == 0) ? eof() : traits_type::to_int_type(*eb); + } + +private: + /// Shortcut for traits_type::eof(). + static int_type eof() { return traits_type::eof(); } + + /// Helper: change error position of -1 to EOF (probably a no-op). + template static std::streampos adjust_eof(INTYPE pos) + { + bool const at_eof{pos == -1}; + if constexpr (std::is_arithmetic_v) + { + return check_cast( + (at_eof ? eof() : pos), "large object seek"sv); + } + else + { + return std::streampos(at_eof ? eof() : pos); + } + } + + void initialize(openmode mode) + { + if ((mode & std::ios::in) != 0) + { + m_g = new char_type[unsigned(m_bufsize)]; + this->setg(m_g, m_g, m_g); + } + if ((mode & std::ios::out) != 0) + { + m_p = new char_type[unsigned(m_bufsize)]; + this->setp(m_p, m_p + m_bufsize); + } + } + + size_type const m_bufsize; + largeobjectaccess m_obj; + + /// Get & put buffers. + char_type *m_g, *m_p; +}; + + +/// Input stream that gets its data from a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This class worked like any other istream, but to read data from a large + * object. It supported all formatting and streaming operations of + * `std::istream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_ilostream : public std::basic_istream +{ + using super = std::basic_istream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_ilostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Identifier of a large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_ilostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::in | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + +private: + largeobject_streambuf m_buf; +}; + +using ilostream = basic_ilostream; + + +/// Output stream that writes data back to a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like any other ostream, but to write data to a large object. + * It supported all formatting and streaming operations of `std::ostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_olostream : public std::basic_ostream +{ + using super = std::basic_ostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// Create a basic_olostream. + /** + * @param t transaction in which this stream is to exist. + * @param o a large object to access. + * @param buf_size size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_olostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{t, o, std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_olostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using olostream = basic_olostream; + + +/// Stream that reads and writes a large object. +/** @deprecated Access large objects directly using the @ref blob class. + * + * This worked like a std::iostream, but to read data from, or write data to, a + * large object. It supported all formatting and streaming operations of + * `std::iostream`. + * + * This functionality was considered too fragile and complex, so it has been + * replaced with a single, much simpler class. + */ +template> +class basic_lostream : public std::basic_iostream +{ + using super = std::basic_iostream; + +public: + using char_type = CHAR; + using traits_type = TRAITS; + using int_type = typename traits_type::int_type; + using pos_type = typename traits_type::pos_type; + using off_type = typename traits_type::off_type; + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + /// Create a basic_lostream. + /** + * @param t Transaction in which this stream is to exist. + * @param o Large object to access. + * @param buf_size Size of buffer to use internally (optional). + */ + [[deprecated("Use blob instead.")]] basic_lostream( + dbtransaction &t, oid o, largeobject::size_type buf_size = 512) : + super{nullptr}, + m_buf{ + t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size} + { + super::init(&m_buf); + } + + ~basic_lostream() + { + try + { + m_buf.pubsync(); + m_buf.pubsync(); + } + catch (std::exception const &e) + { + m_buf.process_notice(e.what()); + } + } + +private: + largeobject_streambuf m_buf; +}; + +using lostream = basic_lostream; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction new file mode 100644 index 0000000..bb5b797 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction @@ -0,0 +1,8 @@ +/** pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction.hxx new file mode 100644 index 0000000..c507155 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/nontransaction.hxx @@ -0,0 +1,76 @@ +/* Definition of the pqxx::nontransaction class. + * + * pqxx::nontransaction provides nontransactional database access + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/nontransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NONTRANSACTION +#define PQXX_H_NONTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/connection.hxx" +#include "pqxx/result.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +using namespace std::literals; + +/// Simple "transaction" class offering no transactional integrity. +/** + * @ingroup transactions + * + * nontransaction, like transaction or any other transaction_base-derived + * class, provides access to a database through a connection. Unlike its + * siblings, however, nontransaction does not maintain any kind of + * transactional integrity. This may be useful eg. for read-only access to the + * database that does not require a consistent, atomic view on its data; or for + * operations that are not allowed within a backend transaction, such as + * creating tables. + * + * For queries that update the database, however, a real transaction is likely + * to be faster unless the transaction consists of only a single record update. + * + * Also, you can keep a nontransaction open for as long as you like. Actual + * back-end transactions are limited in lifespan, and will sometimes fail just + * because they took too long to execute or were left idle for too long. This + * will not happen with a nontransaction (although the connection may still + * time out, e.g. when the network is unavailable for a very long time). + * + * Any query executed in a nontransaction is committed immediately, and neither + * commit() nor abort() has any effect. + * + * Database features that require a backend transaction, such as cursors or + * large objects, will not work in a nontransaction. + */ +class PQXX_LIBEXPORT nontransaction final : public transaction_base +{ +public: + /// Constructor. + /** Create a "dummy" transaction. + * @param c Connection in which this "transaction" will operate. + * @param tname Optional tname for the transaction, beginning with a letter + * and containing only letters and digits. + */ + nontransaction(connection &c, std::string_view tname = ""sv) : + transaction_base{c, tname, std::shared_ptr{}} + { + register_transaction(); + } + + virtual ~nontransaction() override { close(); } + +private: + virtual void do_commit() override {} +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification new file mode 100644 index 0000000..a0bd1c7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification @@ -0,0 +1,8 @@ +/** pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification.hxx new file mode 100644 index 0000000..b59b856 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/notification.hxx @@ -0,0 +1,94 @@ +/* Definition of the pqxx::notification_receiver functor interface. + * + * pqxx::notification_receiver handles incoming notifications. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/notification instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_NOTIFICATION +#define PQXX_H_NOTIFICATION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// "Observer" base class for notifications. +/** @addtogroup notification Notifications and Receivers + * + * To listen on a notification issued using the NOTIFY command, derive your own + * class from notification_receiver and define its function-call operator to + * perform whatever action you wish to take when the given notification + * arrives. Then create an object of that class and pass it to your connection. + * DO NOT use raw SQL to listen for notifications, or your attempts to listen + * won't be resumed when a connection fails--and you'll have no way to notice. + * + * Notifications never arrive inside a transaction, not even in a + * nontransaction. Therefore, you are free to open a transaction of your own + * inside your receiver's function invocation operator. + * + * Notifications you are listening for may arrive anywhere within libpqxx code, + * but be aware that **PostgreSQL defers notifications occurring inside + * transactions.** (This was done for excellent reasons; just think about what + * happens if the transaction where you happen to handle an incoming + * notification is later rolled back for other reasons). So if you're keeping + * a transaction open, don't expect any of your receivers on the same + * connection to be notified. + * + * (For very similar reasons, outgoing notifications are also not sent until + * the transaction that sends them commits.) + * + * Multiple receivers on the same connection may listen on a notification of + * the same name. An incoming notification is processed by invoking all + * receivers (zero or more) of the same name. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE notification_receiver +{ +public: + /// Register the receiver with a connection. + /** + * @param c Connnection to operate on. + * @param channel Name of the notification to listen for. + */ + notification_receiver(connection &c, std::string_view channel); + /// Register the receiver with a connection. + notification_receiver(notification_receiver const &) = delete; + /// Register the receiver with a connection. + notification_receiver &operator=(notification_receiver const &) = delete; + /// Deregister the receiver. + virtual ~notification_receiver(); + + /// The channel that this receiver listens on. + [[nodiscard]] std::string const &channel() const & { return m_channel; } + + // TODO: Change API to take payload as zview instead of string ref. + /// Overridable: action to invoke when notification arrives. + /** + * @param payload An optional string that may have been passed to the NOTIFY + * command. + * @param backend_pid Process ID of the database backend process that served + * our connection when the notification arrived. The actual process ID + * behind the connection may have changed by the time this method is called. + */ + virtual void operator()(std::string const &payload, int backend_pid) = 0; + +protected: + connection &conn() const noexcept { return m_conn; } + +private: + connection &m_conn; + std::string m_channel; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params new file mode 100644 index 0000000..4098782 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params @@ -0,0 +1,8 @@ +/** Helper classes for passing statement parameters. + * + * Use these for prepared statements and parameterised statements. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/params.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params.hxx new file mode 100644 index 0000000..2d29cdf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/params.hxx @@ -0,0 +1,383 @@ +/* Helpers for prepared statements and parameterised statements. + * + * See the connection class for more about such statements. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PARAMS +#define PQXX_H_PARAMS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/statement_parameters.hxx" +#include "pqxx/types.hxx" + + +/// @deprecated The new @ref params class replaces all of this. +namespace pqxx::prepare +{ +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * sequence ranging from `begin` to `end` exclusively. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic sequences. + * + * @param begin A pointer or iterator for iterating parameters. + * @param end A pointer or iterator for iterating parameters. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(IT begin, IT end) +{ + return pqxx::internal::dynamic_params(begin, end); +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C const &container) +{ + using IT = typename C::const_iterator; +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} + + +/// Pass a number of statement parameters only known at runtime. +/** @deprecated Use @ref params instead. + * + * When you call any of the `exec_params` functions, the number of arguments + * is normally known at compile time. This helper function supports the case + * where it is not. + * + * Use this function to pass a variable number of parameters, based on a + * container of parameter values. + * + * The technique combines with the regular static parameters. You can use it + * to insert dynamic parameter lists in any place, or places, among the call's + * parameters. You can even insert multiple dynamic containers. + * + * @param container A container of parameter values. + * @param accessor For each parameter `p`, pass `accessor(p)`. + * @return An object representing the parameters. + */ +template +[[deprecated("Use the params class instead.")]] constexpr inline auto +make_dynamic_params(C &container, ACCESSOR accessor) +{ + using IT = decltype(std::begin(container)); +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return pqxx::internal::dynamic_params{container, accessor}; +#include "pqxx/internal/ignore-deprecated-post.hxx" +} +} // namespace pqxx::prepare + + +namespace pqxx +{ +/// Generate parameter placeholders for use in an SQL statement. +/** When you want to pass parameters to a prepared statement or a parameterised + * statement, you insert placeholders into the SQL. During invocation, the + * database replaces those with the respective parameter values you passed. + * + * The placeholders look like `$1` (for the first parameter value), `$2` (for + * the second), and so on. You can just write those directly in your + * statement. But for those rare cases where it becomes difficult to track + * which number a placeholder should have, you can use a `placeholders` object + * to count and generate them in order. + */ +template class placeholders +{ +public: + /// Maximum number of parameters we support. + static inline constexpr unsigned int max_params{ + (std::numeric_limits::max)()}; + + placeholders() + { + static constexpr auto initial{"$1\0"sv}; + initial.copy(std::data(m_buf), std::size(initial)); + } + + /// Read an ephemeral version of the current placeholder text. + /** @warning Changing the current placeholder number will overwrite this. + * Use the view immediately, or lose it. + */ + constexpr zview view() const &noexcept + { + return zview{std::data(m_buf), m_len}; + } + + /// Read the current placeholder text, as a `std::string`. + /** This will be slightly slower than converting to a `zview`. With most + * C++ implementations however, until you get into ridiculous numbers of + * parameters, the string will benefit from the Short String Optimization, or + * SSO. + */ + std::string get() const { return std::string(std::data(m_buf), m_len); } + + /// Move on to the next parameter. + void next() & + { + if (m_current >= max_params) + throw range_error{pqxx::internal::concat( + "Too many parameters in one statement: limit is ", max_params, ".")}; + ++m_current; + if (m_current % 10 == 0) + { + // Carry the 1. Don't get too clever for this relatively rare + // case, just rewrite the entire number. Leave the $ in place + // though. + char *const data{std::data(m_buf)}; + char *const end{string_traits::into_buf( + data + 1, data + std::size(m_buf), m_current)}; + // (Subtract because we don't include the trailing zero.) + m_len = check_cast(end - data, "placeholders counter") - 1; + } + else + { + PQXX_LIKELY + // Shortcut for the common case: just increment that last digit. + ++m_buf[m_len - 1]; + } + } + + /// Return the current placeholder number. The initial placeholder is 1. + COUNTER count() const noexcept { return m_current; } + +private: + /// Current placeholder number. Starts at 1. + COUNTER m_current = 1; + + /// Length of the current placeholder string, not including trailing zero. + COUNTER m_len = 2; + + /// Text buffer where we render the placeholders, with a trailing zero. + /** We keep reusing this for every subsequent placeholder, just because we + * don't like string allocations. + * + * Maximum length is the maximum base-10 digits that COUNTER can fully + * represent, plus 1 more for the extra digit that it can only partially + * fill up, plus room for the dollar sign and the trailing zero. + */ + std::array::digits10 + 3> m_buf; +}; + + +/// Build a parameter list for a parameterised or prepared statement. +/** When calling a parameterised statement or a prepared statement, you can + * pass parameters into the statement directly in the invocation, as + * additional arguments to `exec_prepared` or `exec_params`. But in + * complex cases, sometimes that's just not convenient. + * + * In those situations, you can create a `params` and append your parameters + * into that, one by one. Then you pass the `params` to `exec_prepared` or + * `exec_params`. + * + * Combinations also work: if you have a `params` containing a string + * parameter, and you call `exec_params` with an `int` argument followed by + * your `params`, you'll be passing the `int` as the first parameter and + * the string as the second. You can even insert a `params` in a `params`, + * or pass two `params` objects to a statement. + */ +class PQXX_LIBEXPORT params +{ +public: + params() = default; + + /// Pre-populate a `params` with `args`. Feel free to add more later. + template constexpr params(Args &&...args) + { + reserve(sizeof...(args)); + append_pack(std::forward(args)...); + } + + /// Pre-allocate room for at least `n` parameters. + /** This is not needed, but it may improve efficiency. + * + * Reserve space if you're going to add parameters individually, and you've + * got some idea of how many there are going to be. It may save some + * memory re-allocations. + */ + void reserve(std::size_t n) &; + + // C++20: constexpr. + /// Get the number of parameters currently in this `params`. + [[nodiscard]] auto size() const noexcept { return m_params.size(); } + + // C++20: Use the vector's ssize() directly and go noexcept+constexpr. + /// Get the number of parameters (signed). + /** Unlike `size()`, this is not yet `noexcept`. That's because C++17's + * `std::vector` does not have a `ssize()` member function. These member + * functions are `noexcept`, but `std::size()` and `std::ssize()` are + * not. + */ + [[nodiscard]] auto ssize() const { return pqxx::internal::ssize(m_params); } + + /// Append a null value. + void append() &; + + /// Append a non-null zview parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(zview) &; + + /// Append a non-null string parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the @ref zview variant if you can, or `std::move()` + */ + void append(std::string const &) &; + + /// Append a non-null string parameter. + void append(std::string &&) &; + + /// Append a non-null binary parameter. + /** The underlying data must stay valid for as long as the `params` + * remains active. + */ + void append(std::basic_string_view) &; + + /// Append a non-null binary parameter. + /** Copies the underlying data into internal storage. For best efficiency, + * use the `std::basic_string_view` variant if you can, or + * `std::move()`. + */ + void append(std::basic_string const &) &; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Append a non-null binary parameter. + /** The `data` object must stay in place and unchanged, for as long as the + * `params` remains active. + */ + template void append(DATA const &data) & + { + append( + std::basic_string_view{std::data(data), std::size(data)}); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Append a non-null binary parameter. + void append(std::basic_string &&) &; + + /// @deprecated Append binarystring parameter. + /** The binarystring must stay valid for as long as the `params` remains + * active. + */ + void append(binarystring const &value) &; + + /// Append all parameters from value. + template + void append(pqxx::internal::dynamic_params const &value) & + { + for (auto ¶m : value) append(value.access(param)); + } + + void append(params const &value) &; + + void append(params &&value) &; + + /// Append a non-null parameter, converting it to its string + /// representation. + template void append(TYPE const &value) & + { + // TODO: Pool storage for multiple string conversions in one buffer? + if constexpr (nullness>::always_null) + { + ignore_unused(value); + m_params.emplace_back(); + } + else if (is_null(value)) + { + m_params.emplace_back(); + } + else + { + m_params.emplace_back(entry{to_string(value)}); + } + } + + /// Append all elements of `range` as parameters. + template void append_multi(RANGE const &range) & + { +#if defined(PQXX_HAVE_CONCEPTS) + if constexpr (std::ranges::sized_range) + reserve(std::size(*this) + std::size(range)); +#endif + for (auto &value : range) append(value); + } + + /// For internal use: Generate a `params` object for use in calls. + /** The params object encapsulates the pointers which we will need to pass + * to libpq when calling a parameterised or prepared statement. + * + * The pointers in the params will refer to storage owned by either the + * params object, or the caller. This is not a problem because a + * `c_params` object is guaranteed to live only while the call is going on. + * As soon as we climb back out of that call tree, we're done with that + * data. + */ + pqxx::internal::c_params make_c_params() const; + +private: + /// Recursively append a pack of params. + template + void append_pack(Arg &&arg, More &&...args) + { + this->append(std::forward(arg)); + // Recurse for remaining args. + append_pack(std::forward(args)...); + } + + /// Terminating case: append an empty parameter pack. It's not hard BTW. + constexpr void append_pack() noexcept {} + + // The way we store a parameter depends on whether it's binary or text + // (most types are text), and whether we're responsible for storing the + // contents. + using entry = std::variant< + std::nullptr_t, zview, std::string, std::basic_string_view, + std::basic_string>; + std::vector m_params; + + static constexpr std::string_view s_overflow{ + "Statement parameter length overflow."sv}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline new file mode 100644 index 0000000..bf82884 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline @@ -0,0 +1,8 @@ +/** pqxx::pipeline class. + * + * Throughput-optimized query interface. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline.hxx new file mode 100644 index 0000000..049dcdd --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pipeline.hxx @@ -0,0 +1,237 @@ +/* Definition of the pqxx::pipeline class. + * + * Throughput-optimized mechanism for executing queries. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_PIPELINE +#define PQXX_H_PIPELINE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +// TODO: libpq 14 introduced a similar "pipeline mode." Can we use that? + +/// Processes several queries in FIFO manner, optimized for high throughput. +/** Use a pipeline if you want to keep doing useful work while your queries are + * executing. Result retrieval is decoupled from execution request; queries + * "go in at the front" and results "come out the back." + * + * Actually, you can retrieve the results in any order if you want, but it may + * lead to surprising "time travel" effects if any of the queries fails. In + * particular, syntax errors in the queries can confuse things and show up too + * early in the stream of results. + * + * Generally, if any of the queries fails, it will throw an exception at the + * point where you request its result. But it may happen earlier, especially + * if you request results out of chronological order. + * + * @warning While a pipeline is active, you cannot execute queries, open + * streams, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT pipeline : public transaction_focus +{ +public: + /// Identifying numbers for queries. + using query_id = long; + + pipeline(pipeline const &) = delete; + pipeline &operator=(pipeline const &) = delete; + + /// Start a pipeline. + explicit pipeline(transaction_base &t) : transaction_focus{t, s_classname} + { + init(); + } + /// Start a pipeline. Assign it a name, for more helpful error messages. + pipeline(transaction_base &t, std::string_view tname) : + transaction_focus{t, s_classname, tname} + { + init(); + } + + /// Close the pipeline. + ~pipeline() noexcept; + + /// Add query to the pipeline. + /** Queries accumulate in the pipeline, which sends them to the backend in a + * batch separated by semicolons. The queries you insert must not use this + * trick themselves, or the pipeline will get hopelessly confused! + * + * @return Identifier for this query, unique only within this pipeline. + */ + query_id insert(std::string_view) &; + + /// Wait for all ongoing or pending operations to complete, and detach. + /** Detaches from the transaction when done. + * + * This does not produce the queries' results, so it may not report any + * errors which may have occurred in their execution. To be sure that your + * statements succeeded, call @ref retrieve until the pipeline is empty. + */ + void complete(); + + /// Forget all ongoing or pending operations and retrieved results. + /** Queries already sent to the backend may still be completed, depending + * on implementation and timing. + * + * Any error state (unless caused by an internal error) will also be cleared. + * This is mostly useful in a nontransaction, since a backend transaction is + * aborted automatically when an error occurs. + * + * Detaches from the transaction when done. + */ + void flush(); + + /// Cancel ongoing query, if any. + /** May cancel any or all of the queries that have been inserted at this + * point whose results have not yet been retrieved. If the pipeline lives in + * a backend transaction, that transaction may be left in a nonfunctional + * state in which it can only be aborted. + * + * Therefore, either use this function in a nontransaction, or abort the + * transaction after calling it. + */ + void cancel(); + + /// Is result for given query available? + [[nodiscard]] bool is_finished(query_id) const; + + /// Retrieve result for given query. + /** If the query failed for whatever reason, this will throw an exception. + * The function will block if the query has not finished yet. + * @warning If results are retrieved out-of-order, i.e. in a different order + * than the one in which their queries were inserted, errors may "propagate" + * to subsequent queries. + */ + result retrieve(query_id qid) + { + return retrieve(m_queries.find(qid)).second; + } + + /// Retrieve oldest unretrieved result (possibly wait for one). + /** @return The query's identifier and its result set. */ + std::pair retrieve(); + + [[nodiscard]] bool empty() const noexcept { return std::empty(m_queries); } + + /// Set maximum number of queries to retain before issuing them to the + /// backend. + /** The pipeline will perform better if multiple queries are issued at once, + * but retaining queries until the results are needed (as opposed to issuing + * them to the backend immediately) may negate any performance benefits the + * pipeline can offer. + * + * Recommended practice is to set this value no higher than the number of + * queries you intend to insert at a time. + * @param retain_max A nonnegative "retention capacity;" passing zero will + * cause queries to be issued immediately + * @return Old retention capacity + */ + int retain(int retain_max = 2) &; + + + /// Resume retained query emission. Harmless when not needed. + void resume() &; + +private: + struct PQXX_PRIVATE Query + { + explicit Query(std::string_view q) : + query{std::make_shared(q)} + {} + + std::shared_ptr query; + result res; + }; + + using QueryMap = std::map; + + void init(); + void attach(); + void detach(); + + /// Upper bound to query id's. + static constexpr query_id qid_limit() noexcept + { + // Parenthesise this to work around an eternal Visual C++ problem: + // Without the extra parentheses, unless NOMINMAX is defined, the + // preprocessor will mistake this "max" for its annoying built-in macro + // of the same name. + return (std::numeric_limits::max)(); + } + + /// Create new query_id. + PQXX_PRIVATE query_id generate_id(); + + bool have_pending() const noexcept + { + return m_issuedrange.second != m_issuedrange.first; + } + + PQXX_PRIVATE void issue(); + + /// The given query failed; never issue anything beyond that. + void set_error_at(query_id qid) noexcept + { + PQXX_UNLIKELY + if (qid < m_error) + m_error = qid; + } + + /// Throw pqxx::internal_error. + [[noreturn]] PQXX_PRIVATE void internal_error(std::string const &err); + + PQXX_PRIVATE bool obtain_result(bool expect_none = false); + + PQXX_PRIVATE void obtain_dummy(); + PQXX_PRIVATE void get_further_available_results(); + PQXX_PRIVATE void check_end_results(); + + /// Receive any results that happen to be available; it's not urgent. + PQXX_PRIVATE void receive_if_available(); + + /// Receive results, up to stop if possible. + PQXX_PRIVATE void receive(pipeline::QueryMap::const_iterator stop); + std::pair retrieve(pipeline::QueryMap::iterator); + + QueryMap m_queries; + std::pair m_issuedrange; + int m_retain = 0; + int m_num_waiting = 0; + query_id m_q_id = 0; + + /// Is there a "dummy query" pending? + bool m_dummy_pending = false; + + /// Point at which an error occurred; no results beyond it will be available + query_id m_error = qid_limit(); + + /// Encoding. + /** We store this in the object to avoid the risk of exceptions at awkward + * moments. + */ + internal::encoding_group m_encoding; + + static constexpr std::string_view s_classname{"pipeline"}; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pqxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pqxx new file mode 100644 index 0000000..17a8eaa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/pqxx @@ -0,0 +1,28 @@ +/// Convenience header: include all libpqxx definitions. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/array.hxx" +#include "pqxx/binarystring.hxx" +#include "pqxx/blob.hxx" +#include "pqxx/connection.hxx" +#include "pqxx/cursor.hxx" +#include "pqxx/errorhandler.hxx" +#include "pqxx/except.hxx" +#include "pqxx/largeobject.hxx" +#include "pqxx/nontransaction.hxx" +#include "pqxx/notification.hxx" +#include "pqxx/params.hxx" +#include "pqxx/pipeline.hxx" +#include "pqxx/prepared_statement.hxx" +#include "pqxx/result.hxx" +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/internal/result_iter.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/transactor.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement new file mode 100644 index 0000000..674be70 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement.hxx new file mode 100644 index 0000000..674be70 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/prepared_statement.hxx @@ -0,0 +1,3 @@ +/// @deprecated Include @c instead. + +#include "params.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range new file mode 100644 index 0000000..11985ec --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range @@ -0,0 +1,6 @@ +/** Client-side support for SQL range types. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/range.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range.hxx new file mode 100644 index 0000000..dc480e4 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/range.hxx @@ -0,0 +1,515 @@ +#ifndef PQXX_H_RANGE +#define PQXX_H_RANGE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include + +#include "pqxx/internal/array-composite.hxx" +#include "pqxx/internal/concat.hxx" + +namespace pqxx +{ +/// An _unlimited_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should extend + * to infinity on that side. + * + * An unlimited boundary is always inclusive of "infinity" values, if the + * range's value type supports them. + */ +struct no_bound +{ + template constexpr bool extends_down_to(TYPE const &) const + { + return true; + } + template constexpr bool extends_up_to(TYPE const &) const + { + return true; + } +}; + + +/// An _inclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should include + * the value. + */ +template class inclusive_bound +{ +public: + inclusive_bound() = delete; + explicit inclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an inclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return not(value < m_value); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return not(m_value < value); + } + +private: + TYPE m_value; +}; + + +/// An _exclusive_ boundary value to a @ref pqxx::range. +/** Use this as a lower or upper bound for a range if the range should _not_ + * include the value. + */ +template class exclusive_bound +{ +public: + exclusive_bound() = delete; + explicit exclusive_bound(TYPE const &value) : m_value{value} + { + if (is_null(value)) + throw argument_error{"Got null value as an exclusive range bound."}; + } + + [[nodiscard]] constexpr TYPE const &get() const &noexcept { return m_value; } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as a lower bound, include value? + [[nodiscard]] bool extends_down_to(TYPE const &value) const + { + return m_value < value; + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Would this bound, as an upper bound, include value? + [[nodiscard]] bool extends_up_to(TYPE const &value) const + { + return value < m_value; + } + +private: + TYPE m_value; +}; + + +/// A range boundary value. +/** A range bound is either no bound at all; or an inclusive bound; or an + * exclusive bound. Pass one of the three to the constructor. + */ +template class range_bound +{ +public: + range_bound() = delete; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(no_bound) : m_bound{} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(inclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(exclusive_bound const &bound) : m_bound{bound} {} + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound const &) = default; + // TODO: constexpr and/or noexcept if underlying constructor supports it. + range_bound(range_bound &&) = default; + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range_bound const &rhs) const + { + if (this->is_limited()) + return ( + rhs.is_limited() and (this->is_inclusive() == rhs.is_inclusive()) and + (*this->value() == *rhs.value())); + else + return not rhs.is_limited(); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range_bound const &rhs) const { return not(*this == rhs); } + range_bound &operator=(range_bound const &) = default; + range_bound &operator=(range_bound &&) = default; + + /// Is this a finite bound? + constexpr bool is_limited() const noexcept + { + return not std::holds_alternative(m_bound); + } + + /// Is this boundary an inclusive one? + constexpr bool is_inclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + /// Is this boundary an exclusive one? + constexpr bool is_exclusive() const noexcept + { + return std::holds_alternative>(m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as a lower bound, include `value`? + bool extends_down_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_down_to(value); }, + m_bound); + } + + // TODO: constexpr/noexcept if underlying function supports it. + /// Would this bound, as an upper bound, include `value`? + bool extends_up_to(TYPE const &value) const + { + return std::visit( + [&value](auto const &bound) { return bound.extends_up_to(value); }, + m_bound); + } + + /// Return bound value, or `nullptr` if it's not limited. + [[nodiscard]] constexpr TYPE const *value() const &noexcept + { + return std::visit( + [](auto const &bound) noexcept { + using bound_t = std::decay_t; + if constexpr (std::is_same_v) + return static_cast(nullptr); + else + return &bound.get(); + }, + m_bound); + } + +private: + std::variant, exclusive_bound> m_bound; +}; + + +// C++20: Concepts for comparisons, construction, etc. +/// A C++ equivalent to PostgreSQL's range types. +/** You can use this as a client-side representation of a "range" in SQL. + * + * PostgreSQL defines several range types, differing in the data type over + * which they range. You can also define your own range types. + * + * Usually you'll want the server to deal with ranges. But on occasions where + * you need to work with them client-side, you may want to use @ref + * pqxx::range. (In cases where all you do is pass them along to the server + * though, it's not worth the complexity. In that case you might as well treat + * ranges as just strings.) + * + * For documentation on PostgreSQL's range types, see: + * https://www.postgresql.org/docs/current/rangetypes.html + * + * The value type must be copyable and default-constructible, and support the + * less-than (`<`) and equals (`==`) comparisons. Value initialisation must + * produce a consistent value. + */ +template class range +{ +public: + /// Create a range. + /** For each of the two bounds, pass a @ref no_bound, @ref inclusive_bound, + * or + * @ref exclusive_bound. + */ + range(range_bound lower, range_bound upper) : + m_lower{lower}, m_upper{upper} + { + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + throw range_error{internal::concat( + "Range's lower bound (", *lower.value(), + ") is greater than its upper bound (", *upper.value(), ").")}; + } + + // TODO: constexpr and/or noexcept if underlying constructor supports it. + /// Create an empty range. + /** SQL has a separate literal to denote an empty range, but any range which + * encompasses no values is an empty range. + */ + range() : + m_lower{exclusive_bound{TYPE{}}}, + m_upper{exclusive_bound{TYPE{}}} + {} + + // TODO: constexpr and/or noexcept if underlying operators support it. + bool operator==(range const &rhs) const + { + return (this->lower_bound() == rhs.lower_bound() and + this->upper_bound() == rhs.upper_bound()) or + (this->empty() and rhs.empty()); + } + + // TODO: constexpr and/or noexcept if underlying operator supports it. + bool operator!=(range const &rhs) const { return !(*this == rhs); } + + range(range const &) = default; + range(range &&) = default; + range &operator=(range const &) = default; + range &operator=(range &&) = default; + + // TODO: constexpr and/or noexcept if underlying operator supports it. + /// Is this range clearly empty? + /** An empty range encompasses no values. + * + * It is possible to "fool" this. For example, if your range is of an + * integer type and has exclusive bounds of 0 and 1, it encompasses no values + * but its `empty()` will return false. The PostgreSQL implementation, by + * contrast, will notice that it is empty. Similar things can happen for + * floating-point types, but with more subtleties and edge cases. + */ + bool empty() const + { + return (m_lower.is_exclusive() or m_upper.is_exclusive()) and + m_lower.is_limited() and m_upper.is_limited() and + not(*m_lower.value() < *m_upper.value()); + } + + // TODO: constexpr and/or noexcept if underlying functions support it. + /// Does this range encompass `value`? + bool contains(TYPE value) const + { + return m_lower.extends_down_to(value) and m_upper.extends_up_to(value); + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Does this range encompass all of `other`? + /** This function is not particularly smart. It does not know, for example, + * that integer ranges `[0,9]` and `[0,10)` contain the same values. + */ + bool contains(range const &other) const + { + return (*this & other) == other; + } + + [[nodiscard]] constexpr range_bound const & + lower_bound() const &noexcept + { + return m_lower; + } + [[nodiscard]] constexpr range_bound const & + upper_bound() const &noexcept + { + return m_upper; + } + + // TODO: constexpr and/or noexcept if underlying operators support it. + /// Intersection of two ranges. + /** Returns a range describing those values which are in both ranges. + */ + range operator&(range const &other) const + { + range_bound lower{no_bound{}}; + if (not this->lower_bound().is_limited()) + lower = other.lower_bound(); + else if (not other.lower_bound().is_limited()) + lower = this->lower_bound(); + else if (*this->lower_bound().value() < *other.lower_bound().value()) + lower = other.lower_bound(); + else if (*other.lower_bound().value() < *this->lower_bound().value()) + lower = this->lower_bound(); + else if (this->lower_bound().is_exclusive()) + lower = this->lower_bound(); + else + lower = other.lower_bound(); + + range_bound upper{no_bound{}}; + if (not this->upper_bound().is_limited()) + upper = other.upper_bound(); + else if (not other.upper_bound().is_limited()) + upper = this->upper_bound(); + else if (*other.upper_bound().value() < *this->upper_bound().value()) + upper = other.upper_bound(); + else if (*this->upper_bound().value() < *other.upper_bound().value()) + upper = this->upper_bound(); + else if (this->upper_bound().is_exclusive()) + upper = this->upper_bound(); + else + upper = other.upper_bound(); + + if ( + lower.is_limited() and upper.is_limited() and + (*upper.value() < *lower.value())) + return {}; + else + return {lower, upper}; + } + + /// Convert to another base type. + template operator range() const + { + range_bound lower{no_bound{}}, upper{no_bound{}}; + if (lower_bound().is_inclusive()) + lower = inclusive_bound{*lower_bound().value()}; + else if (lower_bound().is_exclusive()) + lower = exclusive_bound{*lower_bound().value()}; + + if (upper_bound().is_inclusive()) + upper = inclusive_bound{*upper_bound().value()}; + else if (upper_bound().is_exclusive()) + upper = exclusive_bound{*upper_bound().value()}; + + return {lower, upper}; + } + +private: + range_bound m_lower, m_upper; +}; + + +/// String conversions for a @ref range type. +/** Conversion assumes that either your client encoding is UTF-8, or the values + * are pure ASCII. + */ +template struct string_traits> +{ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, range const &value) + { + return generic_to_buf(begin, end, value); + } + + static inline char * + into_buf(char *begin, char *end, range const &value) + { + if (value.empty()) + { + if ((end - begin) <= internal::ssize(s_empty)) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin + s_empty.copy(begin, std::size(s_empty)); + *here++ = '\0'; + return here; + } + else + { + if (end - begin < 4) + throw conversion_overrun{s_overrun.c_str()}; + char *here = begin; + *here++ = + (static_cast(value.lower_bound().is_inclusive() ? '[' : '(')); + TYPE const *lower{value.lower_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (lower != nullptr) + here = string_traits::into_buf(here, end, *lower) - 1; + *here++ = ','; + TYPE const *upper{value.upper_bound().value()}; + // Convert bound (but go back to overwrite that trailing zero). + if (upper != nullptr) + here = string_traits::into_buf(here, end, *upper) - 1; + if ((end - here) < 2) + throw conversion_overrun{s_overrun.c_str()}; + *here++ = + static_cast(value.upper_bound().is_inclusive() ? ']' : ')'); + *here++ = '\0'; + return here; + } + } + + [[nodiscard]] static inline range from_string(std::string_view text) + { + if (std::size(text) < 3) + throw pqxx::conversion_error{err_bad_input(text)}; + bool left_inc{false}; + switch (text[0]) + { + case '[': left_inc = true; break; + + case '(': break; + + case 'e': + case 'E': + if ( + (std::size(text) != std::size(s_empty)) or + (text[1] != 'm' and text[1] != 'M') or + (text[2] != 'p' and text[2] != 'P') or + (text[3] != 't' and text[3] != 'T') or + (text[4] != 'y' and text[4] != 'Y')) + throw pqxx::conversion_error{err_bad_input(text)}; + return {}; + break; + + default: throw pqxx::conversion_error{err_bad_input(text)}; + } + + auto scan{internal::get_glyph_scanner(internal::encoding_group::UTF8)}; + // The field parser uses this to track which field it's parsing, and + // when not to expect a field separator. + std::size_t index{0}; + // The last field we expect to see. + static constexpr std::size_t last{1}; + // Current parsing position. We skip the opening parenthesis or bracket. + std::size_t pos{1}; + // The string may leave out either bound to indicate that it's unlimited. + std::optional lower, upper; + // We reuse the same field parser we use for composite values and arrays. + internal::parse_composite_field(index, text, pos, lower, scan, last); + internal::parse_composite_field(index, text, pos, upper, scan, last); + + // We need one more character: the closing parenthesis or bracket. + if (pos != std::size(text)) + throw pqxx::conversion_error{err_bad_input(text)}; + char const closing{text[pos - 1]}; + if (closing != ')' and closing != ']') + throw pqxx::conversion_error{err_bad_input(text)}; + bool const right_inc{closing == ']'}; + + range_bound lower_bound{no_bound{}}, upper_bound{no_bound{}}; + if (lower) + { + if (left_inc) + lower_bound = inclusive_bound{*lower}; + else + lower_bound = exclusive_bound{*lower}; + } + if (upper) + { + if (right_inc) + upper_bound = inclusive_bound{*upper}; + else + upper_bound = exclusive_bound{*upper}; + } + + return {lower_bound, upper_bound}; + } + + [[nodiscard]] static inline constexpr std::size_t + size_buffer(range const &value) noexcept + { + TYPE const *lower{value.lower_bound().value()}, + *upper{value.upper_bound().value()}; + std::size_t const lsz{ + lower == nullptr ? 0 : string_traits::size_buffer(*lower) - 1}, + usz{upper == nullptr ? 0 : string_traits::size_buffer(*upper) - 1}; + + if (value.empty()) + return std::size(s_empty) + 1; + else + return 1 + lsz + 1 + usz + 2; + } + +private: + static constexpr zview s_empty{"empty"_zv}; + static constexpr auto s_overrun{"Not enough space in buffer for range."_zv}; + + /// Compose error message for invalid range input. + static std::string err_bad_input(std::string_view text) + { + return internal::concat("Invalid range input: '", text, "'"); + } +}; + + +/// A range type does not have an innate null value. +template struct nullness> : no_null> +{}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result new file mode 100644 index 0000000..523394b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result @@ -0,0 +1,16 @@ +/** pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" + +// Now include some types which depend on result, but which the user will +// expect to see defined after including this header. +#include "pqxx/internal/result_iterator.hxx" +#include "pqxx/field.hxx" +#include "pqxx/internal/result_iter.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result.hxx new file mode 100644 index 0000000..6c41cc0 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/result.hxx @@ -0,0 +1,335 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_RESULT +#define PQXX_H_RESULT + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include + +#include "pqxx/except.hxx" +#include "pqxx/types.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + +#include "pqxx/internal/encodings.hxx" + + +namespace pqxx::internal +{ +// TODO: Make noexcept (but breaks ABI). +PQXX_LIBEXPORT void clear_result(pq::PGresult const *); +} // namespace pqxx::internal + + +namespace pqxx::internal::gate +{ +class result_connection; +class result_creation; +class result_pipeline; +class result_row; +class result_sql_cursor; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +/// Result set containing data returned by a query or command. +/** This behaves as a container (as defined by the C++ standard library) and + * provides random access const iterators to iterate over its rows. You can + * also access a row by indexing a `result R` by the row's zero-based + * number: + * + * + * for (result::size_type i=0; i < std::size(R); ++i) Process(R[i]); + * + * + * Result sets in libpqxx are lightweight, reference-counted wrapper objects + * which are relatively small and cheap to copy. Think of a result object as + * a "smart pointer" to an underlying result set. + * + * @warning The result set that a result object points to is not thread-safe. + * If you copy a result object, it still refers to the same underlying result + * set. So never copy, destroy, query, or otherwise access a result while + * another thread may be copying, destroying, querying, or otherwise accessing + * the same result set--even if it is doing so through a different result + * object! + */ +class PQXX_LIBEXPORT result +{ +public: + using size_type = result_size_type; + using difference_type = result_difference_type; + using reference = row; + using const_iterator = const_result_iterator; + using pointer = const_iterator; + using iterator = const_iterator; + using const_reverse_iterator = const_reverse_result_iterator; + using reverse_iterator = const_reverse_iterator; + + result() noexcept : + m_data{make_data_pointer()}, + m_query{}, + m_encoding{internal::encoding_group::MONOBYTE} + {} + + result(result const &rhs) noexcept = default; + result(result &&rhs) noexcept = default; + + /// Assign one result to another. + /** Copying results is cheap: it copies only smart pointers, but the actual + * data stays in the same place. + */ + result &operator=(result const &rhs) noexcept = default; + + /// Assign one result to another, invaliding the old one. + result &operator=(result &&rhs) noexcept = default; + + /** + * @name Comparisons + * + * You can compare results for equality. Beware: this is a very strict, + * dumb comparison. The smallest difference between two results (such as a + * string "Foo" versus a string "foo") will make them unequal. + */ + //@{ + /// Compare two results for equality. + [[nodiscard]] bool operator==(result const &) const noexcept; + /// Compare two results for inequality. + [[nodiscard]] bool operator!=(result const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + /// Iterate rows, reading them directly into a tuple of "TYPE...". + /** Converts the fields to values of the given respective types. + * + * Use this only with a ranged "for" loop. The iteration produces + * std::tuple which you can "unpack" to a series of `auto` + * variables. + */ + template auto iter() const; + + [[nodiscard]] const_reverse_iterator rbegin() const; + [[nodiscard]] const_reverse_iterator crbegin() const; + [[nodiscard]] const_reverse_iterator rend() const; + [[nodiscard]] const_reverse_iterator crend() const; + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] inline const_iterator end() const noexcept; + [[nodiscard]] inline const_iterator cend() const noexcept; + + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + [[nodiscard]] PQXX_PURE size_type size() const noexcept; + [[nodiscard]] PQXX_PURE bool empty() const noexcept; + [[nodiscard]] size_type capacity() const noexcept { return size(); } + + /// Exchange two `result` values in an exception-safe manner. + /** If the swap fails, the two values will be exactly as they were before. + * + * The swap is not necessarily thread-safe. + */ + void swap(result &) noexcept; + + /// Index a row by number. + /** This returns a @ref row object. Generally you should not keep the row + * around as a variable, but if you do, make sure that your variable is a + * `row`, not a `row&`. + */ + [[nodiscard]] row operator[](size_type i) const noexcept; + +#if defined(PQXX_HAVE_MULTIDIMENSIONAL_SUBSCRIPT) + // TODO: If C++23 will let us, also accept string for the column. + [[nodiscard]] field + operator[](size_type row_num, row_size_type col_num) const noexcept; +#endif + + /// Index a row by number, but check that the row number is valid. + row at(size_type) const; + + /// Index a field by row number and column number. + field at(size_type, row_size_type) const; + + /// Let go of the result's data. + /** Use this if you need to deallocate the result data earlier than you can + * destroy the `result` object itself. + * + * Multiple `result` objects can refer to the same set of underlying data. + * The underlying data will be deallocated once all `result` objects that + * refer to it are cleared or destroyed. + */ + void clear() noexcept + { + m_data.reset(); + m_query = nullptr; + } + + /** + * @name Column information + */ + //@{ + /// Number of columns in result. + [[nodiscard]] PQXX_PURE row_size_type columns() const noexcept; + + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] row_size_type column_number(zview name) const; + + /// Name of column with this number (throws exception if it doesn't exist) + [[nodiscard]] char const *column_name(row_size_type number) const &; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(row_size_type col_num) const; + + /// Return column's type, as an OID from the system catalogue. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(row_size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(row_size_type col_num) const; + + /// What column in its table did this column come from? + [[nodiscard]] row_size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + /// Query that produced this result, if available (empty string otherwise) + [[nodiscard]] PQXX_PURE std::string const &query() const &noexcept; + + /// If command was an `INSERT` of 1 row, return oid of the inserted row. + /** @return Identifier of inserted row if exactly one row was inserted, or + * @ref oid_none otherwise. + */ + [[nodiscard]] PQXX_PURE oid inserted_oid() const; + + /// If command was `INSERT`, `UPDATE`, or `DELETE`: number of affected rows. + /** @return Number of affected rows if last command was `INSERT`, `UPDATE`, + * or `DELETE`; zero for all other commands. + */ + [[nodiscard]] PQXX_PURE size_type affected_rows() const; + + // C++20: Concept like std::invocable, but without specifying param types. + /// Run `func` on each row, passing the row's fields as parameters. + /** Goes through the rows from first to last. You provide a callable `func`. + * + * For each row in the `result`, `for_each` will call `func`. It converts + * the row's fields to the types of `func`'s parameters, and pass them to + * `func`. + * + * (Therefore `func` must have a _single_ signature. It can't be a generic + * lambda, or an object of a class with multiple overloaded function call + * operators. Otherwise, `for_each` will have no way to detect a parameter + * list without ambiguity.) + * + * If any of your parameter types is `std::string_view`, it refers to the + * underlying storage of this `result`. + * + * If any of your parameter types is a reference type, its argument will + * refer to a temporary value which only lives for the duration of that + * single invocation to `func`. If the reference is an lvalue reference, it + * must be `const`. + * + * For example, this queries employee names and salaries from the database + * and prints how much each would like to earn instead: + * ```cxx + * tx.exec("SELECT name, salary FROM employee").for_each( + * [](std::string_view name, float salary){ + * std::cout << name << " would like " << salary * 2 << ".\n"; + * }) + * ``` + * + * If `func` throws an exception, processing stops at that point and + * propagates the exception. + * + * @throws usage_error if `func`'s number of parameters does not match the + * number of columns in this result. + */ + template inline void for_each(CALLABLE &&func) const; + +private: + using data_pointer = std::shared_ptr; + + /// Underlying libpq result set. + data_pointer m_data; + + /// Factory for data_pointer. + static data_pointer + make_data_pointer(internal::pq::PGresult const *res = nullptr) noexcept + { + return {res, internal::clear_result}; + } + + friend class pqxx::internal::gate::result_pipeline; + PQXX_PURE std::shared_ptr query_ptr() const noexcept + { + return m_query; + } + + /// Query string. + std::shared_ptr m_query; + + internal::encoding_group m_encoding; + + static std::string const s_empty_string; + + friend class pqxx::field; + // TODO: noexcept. Breaks ABI. + PQXX_PURE char const *get_value(size_type row, row_size_type col) const; + // TODO: noexcept. Breaks ABI. + PQXX_PURE bool get_is_null(size_type row, row_size_type col) const; + PQXX_PURE + field_size_type get_length(size_type, row_size_type) const noexcept; + + friend class pqxx::internal::gate::result_creation; + result( + internal::pq::PGresult *rhs, std::shared_ptr query, + internal::encoding_group enc); + + PQXX_PRIVATE void check_status(std::string_view desc = ""sv) const; + + friend class pqxx::internal::gate::result_connection; + friend class pqxx::internal::gate::result_row; + bool operator!() const noexcept { return m_data.get() == nullptr; } + operator bool() const noexcept { return m_data.get() != nullptr; } + + [[noreturn]] PQXX_PRIVATE void + throw_sql_error(std::string const &Err, std::string const &Query) const; + PQXX_PRIVATE PQXX_PURE int errorposition() const; + PQXX_PRIVATE std::string status_error() const; + + friend class pqxx::internal::gate::result_sql_cursor; + PQXX_PURE char const *cmd_status() const noexcept; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction new file mode 100644 index 0000000..04b71d7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction @@ -0,0 +1,8 @@ +/** pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/robusttransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction.hxx new file mode 100644 index 0000000..faf6dbf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/robusttransaction.hxx @@ -0,0 +1,120 @@ +/* Definition of the pqxx::robusttransaction class. + * + * pqxx::robusttransaction is a slower but safer transaction class. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/robusttransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROBUSTTRANSACTION +#define PQXX_H_ROBUSTTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref robusttransaction class template. +class PQXX_LIBEXPORT PQXX_NOVTABLE basic_robusttransaction + : public dbtransaction +{ +public: + virtual ~basic_robusttransaction() override = 0; + +protected: + basic_robusttransaction( + connection &c, zview begin_command, std::string_view tname); + basic_robusttransaction(connection &c, zview begin_command); + +private: + using IDType = unsigned long; + + std::string m_conn_string; + std::string m_xid; + int m_backendpid = -1; + + void init(zview begin_command); + + // @warning This function will become `final`. + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + * + * @{ + */ + +/// Slightly slower, better-fortified version of transaction. +/** Requires PostgreSQL 10 or better. + * + * robusttransaction is similar to transaction, but spends more time and effort + * to deal with the hopefully rare case that the connection to the backend is + * lost just while it's trying to commit. In such cases, the client does not + * know whether the backend (on the other side of the broken connection) + * managed to commit the transaction. + * + * When this happens, robusttransaction tries to reconnect to the database and + * figure out what happened. + * + * This service level was made optional since you may not want to pay the + * overhead where it is not necessary. Certainly the use of this class makes + * no sense for local connections, or for transactions that read the database + * but never modify it, or for noncritical database manipulations. + * + * Besides being slower, it's also more complex. Which means that in practice + * a robusttransaction could actually fail more instead of less often than a + * normal transaction. What robusttransaction tries to achieve is to give you + * certainty, not just be more successful per se. + */ +template +class robusttransaction final : public internal::basic_robusttransaction +{ +public: + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string_view tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + tname} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + * @param tname optional human-readable name for this transaction. + */ + robusttransaction(connection &c, std::string &&tname) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd, + std::move(tname)} + {} + + /** Create robusttransaction of given name. + * @param c Connection inside which this robusttransaction should live. + */ + explicit robusttransaction(connection &c) : + internal::basic_robusttransaction{ + c, pqxx::internal::begin_cmd} + {} + + virtual ~robusttransaction() noexcept override { close(); } +}; + +/** + * @} + */ +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row new file mode 100644 index 0000000..62a950a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row @@ -0,0 +1,11 @@ +/** pqxx::row class. + * + * pqxx::row refers to a row in a result. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" + +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" + +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row.hxx new file mode 100644 index 0000000..5be5132 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/row.hxx @@ -0,0 +1,561 @@ +/* Definitions for the pqxx::result class and support classes. + * + * pqxx::result represents the set of result rows from a database query. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ROW +#define PQXX_H_ROW + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/except.hxx" +#include "pqxx/field.hxx" +#include "pqxx/result.hxx" + +#include "pqxx/internal/concat.hxx" + +namespace pqxx::internal +{ +template class result_iter; +} // namespace pqxx::internal + + +namespace pqxx +{ +/// Reference to one row in a result. +/** A row represents one row (also called a row) in a query result set. + * It also acts as a container mapping column numbers or names to field + * values (see below): + * + * ```cxx + * cout << row["date"].c_str() << ": " << row["name"].c_str() << endl; + * ``` + * + * The row itself acts like a (non-modifyable) container, complete with its + * own const_iterator and const_reverse_iterator. + */ +class PQXX_LIBEXPORT row +{ +public: + using size_type = row_size_type; + using difference_type = row_difference_type; + using const_iterator = const_row_iterator; + using iterator = const_iterator; + using reference = field; + using pointer = const_row_iterator; + using const_reverse_iterator = const_reverse_row_iterator; + using reverse_iterator = const_reverse_iterator; + + row() noexcept = default; + row(row &&) noexcept = default; + row(row const &) noexcept = default; + row &operator=(row const &) noexcept = default; + row &operator=(row &&) noexcept = default; + + /** + * @name Comparison + */ + //@{ + [[nodiscard]] PQXX_PURE bool operator==(row const &) const noexcept; + [[nodiscard]] bool operator!=(row const &rhs) const noexcept + { + return not operator==(rhs); + } + //@} + + [[nodiscard]] const_iterator begin() const noexcept; + [[nodiscard]] const_iterator cbegin() const noexcept; + [[nodiscard]] const_iterator end() const noexcept; + [[nodiscard]] const_iterator cend() const noexcept; + + /** + * @name Field access + */ + //@{ + [[nodiscard]] reference front() const noexcept; + [[nodiscard]] reference back() const noexcept; + + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crbegin() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator rend() const; + // TODO: noexcept. Breaks ABI. + [[nodiscard]] const_reverse_row_iterator crend() const; + + [[nodiscard]] reference operator[](size_type) const noexcept; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + [[nodiscard]] reference operator[](zview col_name) const; + + reference at(size_type) const; + /** Address field by name. + * @warning This is much slower than indexing by number, or iterating. + */ + reference at(zview col_name) const; + + [[nodiscard]] constexpr size_type size() const noexcept + { + return m_end - m_begin; + } + + [[deprecated("Swap iterators, not rows.")]] void swap(row &) noexcept; + + /// Row number, assuming this is a real row and not end()/rend(). + [[nodiscard]] constexpr result::size_type rownumber() const noexcept + { + return m_index; + } + + /** + * @name Column information + */ + //@{ + /// Number of given column (throws exception if it doesn't exist). + [[nodiscard]] size_type column_number(zview col_name) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(size_type) const; + + /// Return a column's type. + [[nodiscard]] oid column_type(zview col_name) const + { + return column_type(column_number(col_name)); + } + + /// What table did this column come from? + [[nodiscard]] oid column_table(size_type col_num) const; + + /// What table did this column come from? + [[nodiscard]] oid column_table(zview col_name) const + { + return column_table(column_number(col_name)); + } + + /// What column number in its table did this result column come from? + /** A meaningful answer can be given only if the column in question comes + * directly from a column in a table. If the column is computed in any + * other way, a logic_error will be thrown. + * + * @param col_num a zero-based column number in this result set + * @return a zero-based column number in originating table + */ + [[nodiscard]] size_type table_column(size_type) const; + + /// What column number in its table did this result column come from? + [[nodiscard]] size_type table_column(zview col_name) const + { + return table_column(column_number(col_name)); + } + //@} + + [[nodiscard]] constexpr result::size_type num() const noexcept + { + return rownumber(); + } + + /** Produce a slice of this row, containing the given range of columns. + * + * @deprecated I haven't heard of anyone caring about row slicing at all in + * at least the last 15 years. Yet it adds complexity, so unless anyone + * files a bug explaining why they really need this feature, I'm going to + * remove it. Even if they do, the feature may need an update. + * + * The slice runs from the range's starting column to the range's end + * column, exclusive. It looks just like a normal result row, except + * slices can be empty. + */ + [[deprecated("Row slicing is going away. File a bug if you need it.")]] row + slice(size_type sbegin, size_type send) const; + + /// Is this a row without fields? Can only happen to a slice. + [[nodiscard, deprecated("Row slicing is going away.")]] PQXX_PURE bool + empty() const noexcept; + + /// Extract entire row's values into a tuple. + /** Converts to the types of the tuple's respective fields. + */ + template void to(Tuple &t) const + { + check_size(std::tuple_size_v); + convert(t); + } + + template std::tuple as() const + { + check_size(sizeof...(TYPE)); + using seq = std::make_index_sequence; + return get_tuple>(seq{}); + } + +protected: + friend class const_row_iterator; + friend class result; + row(result const &r, result_size_type index, size_type cols) noexcept; + + /// Throw @ref usage_error if row size is not `expected`. + void check_size(size_type expected) const + { + if (size() != expected) + throw usage_error{internal::concat( + "Tried to extract ", expected, " field(s) from a row of ", size(), + ".")}; + } + + /// Convert to a given tuple of values, don't check sizes. + /** We need this for cases where we have a full tuple of field types, but + * not a parameter pack. + */ + template TUPLE as_tuple() const + { + using seq = std::make_index_sequence>; + return get_tuple(seq{}); + } + + template friend class pqxx::internal::result_iter; + /// Convert entire row to tuple fields, without checking row size. + template void convert(Tuple &t) const + { + extract_fields(t, std::make_index_sequence>{}); + } + + friend class field; + + /// Result set of which this is one row. + result m_result; + + /// Row number. + /** + * You'd expect this to be unsigned, but due to the way reverse iterators + * are related to regular iterators, it must be allowed to underflow to -1. + */ + result::size_type m_index = 0; + + // TODO: Remove m_begin and (if possible) m_end when we remove slice(). + /// First column in slice. This row ignores lower-numbered columns. + size_type m_begin = 0; + /// End column in slice. This row only sees lower-numbered columns. + size_type m_end = 0; + +private: + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + template + void extract_value(Tuple &t) const; + + /// Convert row's values as a new tuple. + template + auto get_tuple(std::index_sequence) const + { + return std::make_tuple(get_field()...); + } + + /// Extract and convert a field. + template auto get_field() const + { + return (*this)[index].as>(); + } +}; + + +/// Iterator for fields in a row. Use as row::const_iterator. +class PQXX_LIBEXPORT const_row_iterator : public field +{ +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = field const; + using pointer = field const *; + using size_type = row_size_type; + using difference_type = row_difference_type; + using reference = field; + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + const_row_iterator() = default; +#include "pqxx/internal/ignore-deprecated-post.hxx" + const_row_iterator(row const &t, row_size_type c) noexcept : + field{t.m_result, t.m_index, c} + {} + const_row_iterator(field const &F) noexcept : field{F} {} + const_row_iterator(const_row_iterator const &) noexcept = default; + const_row_iterator(const_row_iterator &&) noexcept = default; + + /** + * @name Dereferencing operators + */ + //@{ + [[nodiscard]] constexpr pointer operator->() const noexcept { return this; } + [[nodiscard]] reference operator*() const noexcept { return {*this}; } + //@} + + /** + * @name Manipulations + */ + //@{ + const_row_iterator &operator=(const_row_iterator const &) noexcept = default; + const_row_iterator &operator=(const_row_iterator &&) noexcept = default; + + // TODO: noexcept. Breaks ABI. + const_row_iterator operator++(int); + const_row_iterator &operator++() noexcept + { + ++m_col; + return *this; + } + // TODO: noexcept. Breaks ABI. + const_row_iterator operator--(int); + const_row_iterator &operator--() noexcept + { + --m_col; + return *this; + } + + const_row_iterator &operator+=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) + i); + return *this; + } + const_row_iterator &operator-=(difference_type i) noexcept + { + m_col = size_type(difference_type(m_col) - i); + return *this; + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] constexpr bool + operator==(const_row_iterator const &i) const noexcept + { + return col() == i.col(); + } + [[nodiscard]] constexpr bool + operator!=(const_row_iterator const &i) const noexcept + { + return col() != i.col(); + } + [[nodiscard]] constexpr bool + operator<(const_row_iterator const &i) const noexcept + { + return col() < i.col(); + } + [[nodiscard]] constexpr bool + operator<=(const_row_iterator const &i) const noexcept + { + return col() <= i.col(); + } + [[nodiscard]] constexpr bool + operator>(const_row_iterator const &i) const noexcept + { + return col() > i.col(); + } + [[nodiscard]] constexpr bool + operator>=(const_row_iterator const &i) const noexcept + { + return col() >= i.col(); + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] inline const_row_iterator + operator+(difference_type) const noexcept; + + friend const_row_iterator + operator+(difference_type, const_row_iterator const &) noexcept; + + [[nodiscard]] inline const_row_iterator + operator-(difference_type) const noexcept; + [[nodiscard]] inline difference_type + operator-(const_row_iterator const &) const noexcept; + //@} +}; + + +/// Reverse iterator for a row. Use as row::const_reverse_iterator. +class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator +{ +public: + using super = const_row_iterator; + using iterator_type = const_row_iterator; + using iterator_type::difference_type; + using iterator_type::iterator_category; + using iterator_type::pointer; + using value_type = iterator_type::value_type; + using reference = iterator_type::reference; + + const_reverse_row_iterator() noexcept = default; + const_reverse_row_iterator(const_reverse_row_iterator const &) noexcept = + default; + const_reverse_row_iterator(const_reverse_row_iterator &&) noexcept = default; + + explicit const_reverse_row_iterator(super const &rhs) noexcept : + const_row_iterator{rhs} + { + super::operator--(); + } + + [[nodiscard]] PQXX_PURE iterator_type base() const noexcept; + + /** + * @name Dereferencing operators + */ + //@{ + using iterator_type::operator->; + using iterator_type::operator*; + //@} + + /** + * @name Manipulations + */ + //@{ + const_reverse_row_iterator & + operator=(const_reverse_row_iterator const &r) noexcept + { + iterator_type::operator=(r); + return *this; + } + const_reverse_row_iterator operator++() noexcept + { + iterator_type::operator--(); + return *this; + } + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator operator++(int); + const_reverse_row_iterator &operator--() noexcept + { + iterator_type::operator++(); + return *this; + } + const_reverse_row_iterator operator--(int); + // TODO: noexcept. Breaks ABI. + const_reverse_row_iterator &operator+=(difference_type i) noexcept + { + iterator_type::operator-=(i); + return *this; + } + const_reverse_row_iterator &operator-=(difference_type i) noexcept + { + iterator_type::operator+=(i); + return *this; + } + //@} + + /** + * @name Arithmetic operators + */ + //@{ + [[nodiscard]] const_reverse_row_iterator + operator+(difference_type i) const noexcept + { + return const_reverse_row_iterator{base() - i}; + } + [[nodiscard]] const_reverse_row_iterator + operator-(difference_type i) noexcept + { + return const_reverse_row_iterator{base() + i}; + } + [[nodiscard]] difference_type + operator-(const_reverse_row_iterator const &rhs) const noexcept + { + return rhs.const_row_iterator::operator-(*this); + } + //@} + + /** + * @name Comparisons + */ + //@{ + [[nodiscard]] bool + operator==(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator==(rhs); + } + [[nodiscard]] bool + operator!=(const_reverse_row_iterator const &rhs) const noexcept + { + return !operator==(rhs); + } + + [[nodiscard]] constexpr bool + operator<(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>(rhs); + } + [[nodiscard]] constexpr bool + operator<=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator>=(rhs); + } + [[nodiscard]] constexpr bool + operator>(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<(rhs); + } + [[nodiscard]] constexpr bool + operator>=(const_reverse_row_iterator const &rhs) const noexcept + { + return iterator_type::operator<=(rhs); + } + //@} +}; + + +const_row_iterator +const_row_iterator::operator+(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) + o)}; +} + +inline const_row_iterator operator+( + const_row_iterator::difference_type o, const_row_iterator const &i) noexcept +{ + return i + o; +} + +inline const_row_iterator +const_row_iterator::operator-(difference_type o) const noexcept +{ + // TODO:: More direct route to home().columns()? + return { + row{home(), idx(), home().columns()}, + size_type(difference_type(col()) - o)}; +} + +inline const_row_iterator::difference_type +const_row_iterator::operator-(const_row_iterator const &i) const noexcept +{ + return difference_type(num() - i.num()); +} + + +template +inline void row::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + field const f{m_result, m_index, index}; + std::get(t) = from_string(f); +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list new file mode 100644 index 0000000..1bdf51c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list @@ -0,0 +1,6 @@ +/** Helper similar to Python's @c str.join(). + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list.hxx new file mode 100644 index 0000000..d4230ea --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/separated_list.hxx @@ -0,0 +1,142 @@ +/* Helper similar to Python's `str.join()`. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/separated_list instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SEPARATED_LIST +#define PQXX_H_SEPARATED_LIST + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/strconv.hxx" + +// C++20: Simplify using std::ranges::range. +// C++20: Optimise buffer allocation using random_access_range/iterator. +namespace pqxx +{ +/** + * @defgroup utility Utility functions + */ +//@{ + +/// Represent sequence of values as a string, joined by a given separator. +/** + * Use this to turn e.g. the numbers 1, 2, and 3 into a string "1, 2, 3". + * + * @param sep separator string (to be placed between items) + * @param begin beginning of items sequence + * @param end end of items sequence + * @param access functor defining how to dereference sequence elements + */ +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access) +{ + if (end == begin) + return {}; + auto next{begin}; + ++next; + if (next == end) + return to_string(access(begin)); + + // From here on, we've got at least 2 elements -- meaning that we need sep. + using elt_type = strip_t; + using traits = string_traits; + + std::size_t budget{0}; + for (ITER cnt{begin}; cnt != end; ++cnt) + budget += traits::size_buffer(access(cnt)); + budget += + static_cast(std::distance(begin, end)) * std::size(sep); + + std::string result; + result.resize(budget); + + char *const data{result.data()}; + char *here{data}; + char *stop{data + budget}; + here = traits::into_buf(here, stop, access(begin)) - 1; + for (++begin; begin != end; ++begin) + { + here += sep.copy(here, std::size(sep)); + here = traits::into_buf(here, stop, access(begin)) - 1; + } + result.resize(static_cast(here - data)); + return result; +} + + +/// Render sequence as a string, using given separator between items. +template +[[nodiscard]] inline std::string +separated_list(std::string_view sep, ITER begin, ITER end) +{ + return separated_list(sep, begin, end, [](ITER i) { return *i; }); +} + + +/// Render items in a container as a string, using given separator. +template +[[nodiscard]] inline auto +separated_list(std::string_view sep, CONTAINER const &c) + /* + Always std::string; necessary because SFINAE doesn't work with the + contents of function bodies, so the check for iterability has to be in + the signature. + */ + -> typename std::enable_if< + (not std::is_void::value and + not std::is_void::value), + std::string>::type +{ + return separated_list(sep, std::begin(c), std::end(c)); +} + + +/// Render items in a tuple as a string, using given separator. +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX == std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string separated_list( + std::string_view /* sep */, TUPLE const &t, ACCESS const &access) +{ + return to_string(access(&std::get(t))); +} + +template< + typename TUPLE, std::size_t INDEX = 0, typename ACCESS, + typename std::enable_if< + (INDEX < std::tuple_size::value - 1), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t, ACCESS const &access) +{ + std::string out{to_string(access(&std::get(t)))}; + out.append(sep); + out.append(separated_list(sep, t, access)); + return out; +} + +template< + typename TUPLE, std::size_t INDEX = 0, + typename std::enable_if< + (INDEX <= std::tuple_size::value), int>::type = 0> +[[nodiscard]] inline std::string +separated_list(std::string_view sep, TUPLE const &t) +{ + // TODO: Optimise allocation. + return separated_list(sep, t, [](TUPLE const &tup) { return *tup; }); +} +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv new file mode 100644 index 0000000..aa2c40e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv @@ -0,0 +1,6 @@ +/** String conversion definitions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/strconv.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv.hxx new file mode 100644 index 0000000..8637112 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/strconv.hxx @@ -0,0 +1,468 @@ +/* String conversion definitions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STRCONV +#define PQXX_H_STRCONV + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#if defined(PQXX_HAVE_RANGES) && __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/util.hxx" +#include "pqxx/zview.hxx" + + +namespace pqxx::internal +{ +/// Attempt to demangle @c std::type_info::name() to something human-readable. +PQXX_LIBEXPORT std::string demangle_type_name(char const[]); +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @defgroup stringconversion String conversion + * + * The PostgreSQL server accepts and represents data in string form. It has + * its own formats for various data types. The string conversions define how + * various C++ types translate to and from their respective PostgreSQL text + * representations. + * + * Each conversion is defined by a specialisations of @c string_traits. It + * gets complicated if you want top performance, but until you do, all you + * really need to care about when converting values between C++ in-memory + * representations such as @c int and the postgres string representations is + * the @c pqxx::to_string and @c pqxx::from_string functions. + * + * If you need to convert a type which is not supported out of the box, you'll + * need to define your own specialisations for these templates, similar to the + * ones defined here and in `pqxx/conversions.hxx`. Any conversion code which + * "sees" your specialisation will now support your conversion. In particular, + * you'll be able to read result fields into a variable of the new type. + * + * There is a macro to help you define conversions for individual enumeration + * types. The conversion will represent enumeration values as numeric strings. + */ +//@{ + +/// A human-readable name for a type, used in error messages and such. +/** Actually this may not always be very user-friendly. It uses + * @c std::type_info::name(). On gcc-like compilers we try to demangle its + * output. Visual Studio produces human-friendly names out of the box. + * + * This variable is not inline. Inlining it gives rise to "memory leak" + * warnings from asan, the address sanitizer, possibly from use of + * @c std::type_info::name. + */ +template +std::string const type_name{internal::demangle_type_name(typeid(TYPE).name())}; + + +/// Traits describing a type's "null value," if any. +/** Some C++ types have a special value or state which correspond directly to + * SQL's NULL. + * + * The @c nullness traits describe whether it exists, and whether a particular + * value is null. + */ +template struct nullness +{ + /// Does this type have a null value? + static bool has_null; + + /// Is this type always null? + static bool always_null; + + /// Is @c value a null? + static bool is_null(TYPE const &value); + + /// Return a null value. + /** Don't use this in generic code to compare a value and see whether it is + * null. Some types may have multiple null values which do not compare as + * equal, or may define a null value which is not equal to anything including + * itself, like in SQL. + */ + [[nodiscard]] static TYPE null(); +}; + + +/// Nullness traits describing a type which does not have a null value. +template struct no_null +{ + /// Does @c TYPE have a "built-in null value"? + /** For example, a pointer can equal @c nullptr, which makes a very natural + * representation of an SQL null value. For such types, the code sometimes + * needs to make special allowances. + * + * for most types, such as @c int or @c std::string, there is no built-in + * null. If you want to represent an SQL null value for such a type, you + * would have to wrap it in something that does have a null value. For + * example, you could use @c std::optional for "either an @c int or a + * null value." + */ + static constexpr bool has_null = false; + + /// Are all values of this type null? + /** There are a few special C++ types which are always null - mainly + * @c std::nullptr_t. + */ + static constexpr bool always_null = false; + + /// Does a given value correspond to an SQL null value? + /** Most C++ types, such as @c int or @c std::string, have no inherent null + * value. But some types such as C-style string pointers do have a natural + * equivalent to an SQL null. + */ + [[nodiscard]] static constexpr bool is_null(TYPE const &) noexcept + { + return false; + } +}; + + +/// Traits class for use in string conversions. +/** Specialize this template for a type for which you wish to add to_string + * and from_string support. + * + * String conversions are not meant to work for nulls. Check for null before + * converting a value of @c TYPE to a string, or vice versa. + */ +template struct string_traits +{ + /// Return a @c string_view representing value, plus terminating zero. + /** Produces a @c string_view containing the PostgreSQL string representation + * for @c value. + * + * Uses the space from @c begin to @c end as a buffer, if needed. The + * returned string may lie somewhere in that buffer, or it may be a + * compile-time constant, or it may be null if value was a null value. Even + * if the string is stored in the buffer, its @c begin() may or may not be + * the same as @c begin. + * + * The @c string_view is guaranteed to be valid as long as the buffer from + * @c begin to @c end remains accessible and unmodified. + * + * @throws pqxx::conversion_overrun if the provided buffer space may not be + * enough. For maximum performance, this is a conservative estimate. It may + * complain about a buffer which is actually large enough for your value, if + * an exact check gets too expensive. + */ + [[nodiscard]] static inline zview + to_buf(char *begin, char *end, TYPE const &value); + + /// Write value's string representation into buffer at @c begin. + /** Assumes that value is non-null. + * + * Writes value's string representation into the buffer, starting exactly at + * @c begin, and ensuring a trailing zero. Returns the address just beyond + * the trailing zero, so the caller could use it as the @c begin for another + * call to @c into_buf writing a next value. + */ + static inline char *into_buf(char *begin, char *end, TYPE const &value); + + /// Parse a string representation of a @c TYPE value. + /** Throws @c conversion_error if @c value does not meet the expected format + * for a value of this type. + */ + [[nodiscard]] static inline TYPE from_string(std::string_view text); + + // C++20: Can we make these all constexpr? + /// Estimate how much buffer space is needed to represent value. + /** The estimate may be a little pessimistic, if it saves time. + * + * The estimate includes the terminating zero. + */ + [[nodiscard]] static inline std::size_t + size_buffer(TYPE const &value) noexcept; +}; + + +/// Nullness: Enums do not have an inherent null value. +template +struct nullness>> : no_null +{}; +} // namespace pqxx + + +namespace pqxx::internal +{ +/// Helper class for defining enum conversions. +/** The conversion will convert enum values to numeric strings, and vice versa. + * + * To define a string conversion for an enum type, derive a @c string_traits + * specialisation for the enum from this struct. + * + * There's usually an easier way though: the @c PQXX_DECLARE_ENUM_CONVERSION + * macro. Use @c enum_traits manually only if you need to customise your + * traits type in more detail. + */ +template struct enum_traits +{ + using impl_type = std::underlying_type_t; + using impl_traits = string_traits; + + [[nodiscard]] static constexpr zview + to_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::to_buf(begin, end, to_underlying(value)); + } + + static constexpr char *into_buf(char *begin, char *end, ENUM const &value) + { + return impl_traits::into_buf(begin, end, to_underlying(value)); + } + + [[nodiscard]] static ENUM from_string(std::string_view text) + { + return static_cast(impl_traits::from_string(text)); + } + + [[nodiscard]] static std::size_t size_buffer(ENUM const &value) noexcept + { + return impl_traits::size_buffer(to_underlying(value)); + } + +private: + // C++23: Replace with std::to_underlying. + static constexpr impl_type to_underlying(ENUM const &value) noexcept + { + return static_cast(value); + } +}; +} // namespace pqxx::internal + + +/// Macro: Define a string conversion for an enum type. +/** This specialises the @c pqxx::string_traits template, so use it in the + * @c ::pqxx namespace. + * + * For example: + * + * #include + * #include + * enum X { xa, xb }; + * namespace pqxx { PQXX_DECLARE_ENUM_CONVERSION(x); } + * int main() { std::cout << pqxx::to_string(xa) << std::endl; } + */ +#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \ + template<> struct string_traits : pqxx::internal::enum_traits \ + {}; \ + template<> inline std::string const type_name { #ENUM } + + +namespace pqxx +{ +/// Parse a value in postgres' text format as a TYPE. +/** If the form of the value found in the string does not match the expected + * type, e.g. if a decimal point is found when converting to an integer type, + * the conversion fails. Overflows (e.g. converting "9999999999" to a 16-bit + * C++ type) are also treated as errors. If in some cases this behaviour + * should be inappropriate, convert to something bigger such as @c long @c int + * first and then truncate the resulting value. + * + * Only the simplest possible conversions are supported. Fancy features like + * hexadecimal or octal, spurious signs, or exponent notation won't work. + * Whitespace is not stripped away. Only the kinds of strings that come out of + * PostgreSQL and out of to_string() can be converted. + */ +template +[[nodiscard]] inline TYPE from_string(std::string_view text) +{ + return string_traits::from_string(text); +} + + +/// "Convert" a std::string_view to a std::string_view. +/** Just returns its input. + * + * @warning Of course the result is only valid for as long as the original + * string remains valid! Never access the string referenced by the return + * value after the original has been destroyed. + */ +template<> +[[nodiscard]] inline std::string_view from_string(std::string_view text) +{ + return text; +} + + +/// Attempt to convert postgres-generated string to given built-in object. +/** This is like the single-argument form of the function, except instead of + * returning the value, it sets @c value. + * + * You may find this more convenient in that it infers the type you want from + * the argument you pass. But there are disadvantages: it requires an + * assignment operator, and it may be less efficient. + */ +template inline void from_string(std::string_view text, T &value) +{ + value = from_string(text); +} + + +/// Convert a value to a readable string that PostgreSQL will understand. +/** The conversion does no special formatting, and ignores any locale settings. + * The resulting string will be human-readable and in a format suitable for use + * in SQL queries. It won't have niceties such as "thousands separators" + * though. + */ +template inline std::string to_string(TYPE const &value); + + +/// Convert multiple values to strings inside a single buffer. +/** There must be enough room for all values, or this will throw + * @c conversion_overrun. You can obtain a conservative estimate of the buffer + * space required by calling @c size_buffer() on the values. + * + * The @c std::string_view results may point into the buffer, so don't assume + * that they will remain valid after you destruct or move the buffer. + */ +template +[[nodiscard]] inline std::vector +to_buf(char *here, char const *end, TYPE... value) +{ + return {[&here, end](auto v) { + auto begin = here; + here = string_traits::into_buf(begin, end, v); + // Exclude the trailing zero out of the string_view. + auto len{static_cast(here - begin) - 1}; + return std::string_view{begin, len}; + }(value)...}; +} + +/// Convert a value to a readable string that PostgreSQL will understand. +/** This variant of to_string can sometimes save a bit of time in loops, by + * re-using a std::string for multiple conversions. + */ +template +inline void into_string(TYPE const &value, std::string &out); + + +/// Is @c value null? +template +[[nodiscard]] inline constexpr bool is_null(TYPE const &value) noexcept +{ + return nullness>::is_null(value); +} + + +/// Estimate how much buffer space is needed to represent values as a string. +/** The estimate may be a little pessimistic, if it saves time. It also + * includes room for a terminating zero after each value. + */ +template +[[nodiscard]] inline std::size_t size_buffer(TYPE const &...value) noexcept +{ + return (string_traits>::size_buffer(value) + ...); +} + + +/// Does this type translate to an SQL array? +/** Specialisations may override this to be true for container types. + * + * This may not always be a black-and-white choice. For instance, a + * @c std::string is a container, but normally it translates to an SQL string, + * not an SQL array. + */ +template inline constexpr bool is_sql_array{false}; + + +/// Can we use this type in arrays and composite types without quoting them? +/** Define this as @c true only if values of @c TYPE can never contain any + * special characters that might need escaping or confuse the parsing of array + * or composite * types, such as commas, quotes, parentheses, braces, newlines, + * and so on. + * + * When converting a value of such a type to a string in an array or a field in + * a composite type, we do not need to add quotes, nor escape any special + * characters. + * + * This is just an optimisation, so it defaults to @c false to err on the side + * of slow correctness. + */ +template inline constexpr bool is_unquoted_safe{false}; + + +/// Element separator between SQL array elements of this type. +template inline constexpr char array_separator{','}; + + +/// What's the preferred format for passing non-null parameters of this type? +/** This affects how we pass parameters of @c TYPE when calling parameterised + * statements or prepared statements. + * + * Generally we pass parameters in text format, but binary strings are the + * exception. We also pass nulls in binary format, so this function need not + * handle null values. + */ +template inline constexpr format param_format(TYPE const &) +{ + return format::text; +} + + +/// Implement @c string_traits::to_buf by calling @c into_buf. +/** When you specialise @c string_traits for a new type, most of the time its + * @c to_buf implementation has no special optimisation tricks and just writes + * its text into the buffer it receives from the caller, starting at the + * beginning. + * + * In that common situation, you can implement @c to_buf as just a call to + * @c generic_to_buf. It will call @c into_buf and return the right result for + * @c to_buf. + */ +template +inline zview generic_to_buf(char *begin, char *end, TYPE const &value) +{ + using traits = string_traits; + // The trailing zero does not count towards the zview's size, so subtract 1 + // from the result we get from into_buf(). + if (is_null(value)) + return {}; + else + return {begin, traits::into_buf(begin, end, value) - begin - 1}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Binary string, akin to @c std::string for binary data. +/** Any type that satisfies this concept can represent an SQL BYTEA value. + * + * A @c binary has a @c begin(), @c end(), @c size(), and @data(). Each byte + * is a @c std::byte, and they must all be laid out contiguously in memory so + * we can reference them by a pointer. + */ +template +concept binary = std::ranges::contiguous_range and + std::is_same_v>, std::byte>; +#endif +//@} +} // namespace pqxx + + +#include "pqxx/internal/conversions.hxx" +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from new file mode 100644 index 0000000..9727624 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from @@ -0,0 +1,8 @@ +/** pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from.hxx new file mode 100644 index 0000000..ff4a93d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_from.hxx @@ -0,0 +1,361 @@ +/* Definition of the pqxx::stream_from class. + * + * pqxx::stream_from enables optimized batch reads from a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_from instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_FROM +#define PQXX_H_STREAM_FROM + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/except.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/internal/stream_iterator.hxx" +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_focus.hxx" + + +namespace pqxx +{ +class transaction_base; + + +/// Pass this to a `stream_from` constructor to stream table contents. +/** @deprecated Use @ref stream_from::table() instead. + */ +constexpr from_table_t from_table; +/// Pass this to a `stream_from` constructor to stream query results. +/** @deprecated Use stream_from::query() instead. + */ +constexpr from_query_t from_query; + + +/// Stream data from the database. +/** For larger data sets, retrieving data this way is likely to be faster than + * executing a query and then iterating and converting the rows fields. You + * will also be able to start processing before all of the data has come in. + * + * There are also downsides. Not all kinds of query will work in a stream. + * But straightforward `SELECT` and `UPDATE ... RETURNING` queries should work. + * This function makes use of @ref pqxx::stream_from, which in turn uses + * PostgreSQL's `COPY` command, so see the documentation for those to get the + * full details. + * + * There are other downsides. If there stream encounters an error, it may + * leave the entire connection in an unusable state, so you'll have to give the + * whole thing up. Finally, opening a stream puts the connection in a special + * state, so you won't be able to do many other things with the connection or + * the transaction while the stream is open. + * + * There are two ways of starting a stream: you stream either all rows in a + * table (using one of the factories, `table()` or `raw_table()`), or the + * results of a query (using the `query()` factory). + * + * Usually you'll want the `stream` convenience wrapper in + * @ref transaction_base, * so you don't need to deal with this class directly. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_from : transaction_focus +{ +public: + using raw_line = + std::pair>, std::size_t>; + + /// Factory: Execute query, and stream the results. + /** The query can be a SELECT query or a VALUES query; or it can be an + * UPDATE, INSERT, or DELETE with a RETURNING clause. + * + * The query is executed as part of a COPY statement, so there are additional + * restrictions on what kind of query you can use here. See the PostgreSQL + * documentation for the COPY command: + * + * https://www.postgresql.org/docs/current/sql-copy.html + */ + static stream_from query(transaction_base &tx, std::string_view q) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return {tx, from_query, q}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /** + * @name Streaming data from tables + * + * You can use `stream_from` to read a table's contents. This is a quick + * and easy way to read a table, but it comes with limitations. It cannot + * stream from a view, only from a table. It does not support conditions. + * And there are no guarantees about ordering. If you need any of those + * things, consider streaming from a query instead. + */ + //@{ + + /// Factory: Stream data from a pre-quoted table and columns. + /** Use this factory if you need to create multiple streams using the same + * table path and/or columns list, and you want to save a bit of work on + * composing the internal SQL statement for starting the stream. It lets you + * compose the string representations for the table path and the columns + * list, so you can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns which the stream will read. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will read all columns in the table, in schema order. + */ + static stream_from raw_table( + transaction_base &tx, std::string_view path, + std::string_view columns = ""sv); + + /// Factory: Stream data from a given table. + /** This is the convenient way to stream from a table. + */ + static stream_from table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}); + //@} + + /// Execute query, and stream over the results. + /** @deprecated Use factory function @ref query instead. + */ + [[deprecated("Use query() factory instead.")]] stream_from( + transaction_base &, from_query_t, std::string_view query); + + /// Stream all rows in table, all columns. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table); + + /// Stream given columns from all rows in table. + /** @deprecated Use factories @ref table or @ref raw_table instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end); + + /// Stream given columns from all rows in table. + /** @deprecated Use factory function @ref query instead. + */ + template + [[deprecated("Use table() or raw_table() factory instead.")]] stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Columns const &columns); + +#include "pqxx/internal/ignore-deprecated-pre.hxx" + /// @deprecated Use factories @ref table or @ref raw_table instead. + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table) : + stream_from{tx, from_table, table} + {} +#include "pqxx/internal/ignore-deprecated-post.hxx" + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &tx, std::string_view table, Columns const &columns) : + stream_from{tx, from_table, table, columns} + {} + + /// @deprecated Use factories @ref table or @ref raw_table instead. + template + [[deprecated("Use the from_table_t overload instead.")]] stream_from( + transaction_base &, std::string_view table, Iter columns_begin, + Iter columns_end); + + ~stream_from() noexcept; + + /// May this stream still produce more data? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream produced all the data it is going to produce? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Finish this stream. Call this before continuing to use the connection. + /** Consumes all remaining lines, and closes the stream. + * + * This may take a while if you're abandoning the stream before it's done, so + * skip it in error scenarios where you're not planning to use the connection + * again afterwards. + */ + void complete(); + + /// Read one row into a tuple. + /** Converts the row's fields into the fields making up the tuple. + * + * For a column which can contain nulls, be sure to give the corresponding + * tuple field a type which can be null. For example, to read a field as + * `int` when it may contain nulls, read it as `std::optional`. + * Using `std::shared_ptr` or `std::unique_ptr` will also work. + */ + template stream_from &operator>>(Tuple &); + + /// Doing this with a `std::variant` is going to be horrifically borked. + template + stream_from &operator>>(std::variant &) = delete; + + /// Iterate over this stream. Supports range-based "for" loops. + /** Produces an input iterator over the stream. + * + * Do not call this yourself. Use it like "for (auto data : stream.iter())". + */ + template [[nodiscard]] auto iter() & + { + return pqxx::internal::stream_input_iteration{*this}; + } + + /// Read a row. Return fields as views, valid until you read the next row. + /** Returns `nullptr` when there are no more rows to read. Do not attempt + * to read any further rows after that. + * + * Do not access the vector, or the storage referenced by the views, after + * closing or completing the stream, or after attempting to read a next row. + * + * A @ref pqxx::zview is like a `std::string_view`, but with the added + * guarantee that if its data pointer is non-null, the string is followed by + * a terminating zero (which falls just outside the view itself). + * + * If any of the views' data pointer is null, that means that the + * corresponding SQL field is null. + * + * @warning The return type may change in the future, to support C++20 + * coroutine-based usage. + */ + std::vector const *read_row() &; + + /// Read a raw line of text from the COPY command. + /** @warning Do not use this unless you really know what you're doing. */ + raw_line get_raw_line(); + +private: + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &tx, std::string_view table, std::string_view columns, + from_table_t); + + // TODO: Clean up this signature once we cull the deprecated constructors. + /// @deprecated + stream_from( + transaction_base &, std::string_view unquoted_table, + std::string_view columns, from_table_t, int); + + template + void extract_fields(Tuple &t, std::index_sequence) const + { + (extract_value(t), ...); + } + + pqxx::internal::glyph_scanner_func *m_glyph_scanner; + + /// Current row's fields' text, combined into one reusable string. + std::string m_row; + + /// The current row's fields. + std::vector m_fields; + + bool m_finished = false; + + void close(); + + template + void extract_value(Tuple &) const; + + /// Read a line of COPY data, write `m_row` and `m_fields`. + void parse_line(); +}; + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table_name, + Columns const &columns) : + stream_from{ + tx, from_table, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_from::stream_from( + transaction_base &tx, from_table_t, std::string_view table, + Iter columns_begin, Iter columns_end) : + stream_from{ + tx, table, separated_list(",", columns_begin, columns_end), + from_table, 1} +{} + + +template inline stream_from &stream_from::operator>>(Tuple &t) +{ + if (m_finished) + return *this; + static constexpr auto tup_size{std::tuple_size_v}; + m_fields.reserve(tup_size); + parse_line(); + if (m_finished) + return *this; + + if (std::size(m_fields) != tup_size) + throw usage_error{internal::concat( + "Tried to extract ", tup_size, " field(s) from a stream of ", + std::size(m_fields), ".")}; + + extract_fields(t, std::make_index_sequence{}); + return *this; +} + + +template +inline void stream_from::extract_value(Tuple &t) const +{ + using field_type = strip_t(t))>; + using nullity = nullness; + assert(index < std::size(m_fields)); + if constexpr (nullity::always_null) + { + if (std::data(m_fields[index]) != nullptr) + throw conversion_error{"Streaming non-null value into null field."}; + } + else if (std::data(m_fields[index]) == nullptr) + { + if constexpr (nullity::has_null) + std::get(t) = nullity::null(); + else + internal::throw_null_conversion(type_name); + } + else + { + // Don't ever try to convert a non-null value to nullptr_t! + std::get(t) = from_string(m_fields[index]); + } +} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to new file mode 100644 index 0000000..8760cf1 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to @@ -0,0 +1,8 @@ +/** pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/stream_to.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to.hxx new file mode 100644 index 0000000..2a49d8f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/stream_to.hxx @@ -0,0 +1,455 @@ +/* Definition of the pqxx::stream_to class. + * + * pqxx::stream_to enables optimized batch updates to a database table. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_to.hxx instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_STREAM_TO +#define PQXX_H_STREAM_TO + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/separated_list.hxx" +#include "pqxx/transaction_base.hxx" + + +namespace pqxx +{ +/// Efficiently write data directly to a database table. +/** If you wish to insert rows of data into a table, you can compose INSERT + * statements and execute them. But it's slow and tedious, and you need to + * worry about quoting and escaping the data. + * + * If you're just inserting a single row, it probably won't matter much. You + * can use prepared or parameterised statements to take care of the escaping + * for you. But if you're inserting large numbers of rows you will want + * something better. + * + * Inserting rows one by one using INSERT statements involves a lot of + * pointless overhead, especially when you are working with a remote database + * server over the network. You may end up sending each row over the network + * as a separate query, and waiting for a reply. Do it "in bulk" using + * `stream_to`, and you may find that it goes many times faster. Sometimes + * you gain orders of magnitude in speed. + * + * Here's how it works: you create a `stream_to` stream to start writing to + * your table. You will probably want to specify the columns. Then, you + * feed your data into the stream one row at a time. And finally, you call the + * stream's @ref complete function to tell it to finalise the operation, wait + * for completion, and check for errors. + * + * (You _must_ complete the stream before committing or aborting the + * transaction. The connection is in a special state while the stream is + * active, where it can't process commands, and can't commit or abort a + * transaction.) + * + * So how do you feed a row of data into the stream? There's several ways, but + * the preferred one is to call its @ref write_values. Pass the field values + * as arguments. Doesn't matter what type they are, as long as libpqxx knows + * how to convert them to PostgreSQL's text format: `int`, `std::string` or + * `std:string_view`, `float` and `double`, `bool`... lots of basic types + * are supported. If some of the values are null, feel free to use + * `std::optional`, `std::shared_ptr`, or `std::unique_ptr`. + * + * The arguments' types don't even have to match the fields' SQL types. If you + * want to insert an `int` into a `DECIMAL` column, that's your choice -- it + * will produce a `DECIMAL` value which happens to be integral. Insert a + * `float` into a `VARCHAR` column? That's fine, you'll get a string whose + * contents happen to read like a number. And so on. You can even insert + * different types of value in the same column on different rows. If you have + * a code path where a particular field is always null, just insert `nullptr`. + * + * There is another way to insert rows: the `<<` ("shift-left") operator. + * It's not as fast and it doesn't support variable arguments: each row must be + * either a `std::tuple` or something iterable, such as a `std::vector`, or + * anything else with a `begin()` and `end()`. + * + * @warning While a stream is active, you cannot execute queries, open a + * pipeline, etc. on the same transaction. A transaction can have at most one + * object of a type derived from @ref pqxx::transaction_focus active on it at a + * time. + */ +class PQXX_LIBEXPORT stream_to : transaction_focus +{ +public: + /// Stream data to a pre-quoted table and columns. + /** This factory can be useful when it's not convenient to provide the + * columns list in the form of a `std::initializer_list`, or when the list + * of columns is simply not known at compile time. + * + * Also use this if you need to create multiple streams using the same table + * path and/or columns list, and you want to save a bit of work on composing + * the internal SQL statement for starting the stream. It lets you compose + * the string representations for the table path and the columns list, so you + * can compute these once and then re-use them later. + * + * @param tx The transaction within which the stream will operate. + * @param path Name or path for the table upon which the stream will + * operate. If any part of the table path may contain special + * characters or be case-sensitive, quote the path using + * pqxx::connection::quote_table(). + * @param columns Columns to which the stream will write. They should be + * comma-separated and, if needed, quoted. You can produce the string + * using pqxx::connection::quote_columns(). If you omit this argument, + * the stream will write all columns in the table, in schema order. + */ + static stream_to raw_table( + transaction_base &tx, std::string_view path, std::string_view columns = "") + { + return {tx, path, columns}; + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this to stream data to a table, where the list of columns is known at + * compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns Optionally, the columns to which the stream should write. + * If you do not pass this, the stream will write to all columns in the + * table, in schema order. + */ + static stream_to table( + transaction_base &tx, table_path path, + std::initializer_list columns = {}) + { + auto const &conn{tx.conn()}; + return raw_table(tx, conn.quote_table(path), conn.quote_columns(columns)); + } + +#if defined(PQXX_HAVE_CONCEPTS) + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, table_path path, COLUMNS const &columns) + { + auto const &conn{tx.conn()}; + return stream_to::raw_table( + tx, conn.quote_table(path), tx.conn().quote_columns(columns)); + } + + /// Create a `stream_to` writing to a named table and columns. + /** Use this version to stream data to a table, when the list of columns is + * not known at compile time. + * + * @param tx The transaction within which the stream will operate. + * @param path A @ref table_path designating the target table. + * @param columns The columns to which the stream should write. + */ + template + static stream_to + table(transaction_base &tx, std::string_view path, COLUMNS const &columns) + { + return stream_to::raw_table(tx, path, tx.conn().quote_columns(columns)); + } +#endif // PQXX_HAVE_CONCEPTS + + /// Create a stream, without specifying columns. + /** @deprecated Use @ref table or @ref raw_table as a factory. + * + * Fields will be inserted in whatever order the columns have in the + * database. + * + * You'll probably want to specify the columns, so that the mapping between + * your data fields and the table is explicit in your code, and not hidden + * in an "implicit contract" between your code and your schema. + */ + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &tx, std::string_view table_name) : + stream_to{tx, table_name, ""sv} + {} + + /// Create a stream, specifying column names as a container of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Columns const &columns); + + /// Create a stream, specifying column names as a sequence of strings. + /** @deprecated Use @ref table or @ref raw_table as a factory. + */ + template + [[deprecated("Use table() or raw_table() factory.")]] stream_to( + transaction_base &, std::string_view table_name, Iter columns_begin, + Iter columns_end); + + ~stream_to() noexcept; + + /// Does this stream still need to @ref complete()? + [[nodiscard]] constexpr operator bool() const noexcept + { + return not m_finished; + } + /// Has this stream been through its concluding @c complete()? + [[nodiscard]] constexpr bool operator!() const noexcept + { + return m_finished; + } + + /// Complete the operation, and check for errors. + /** Always call this to close the stream in an orderly fashion, even after + * an error. (In the case of an error, abort the transaction afterwards.) + * + * The only circumstance where it's safe to skip this is after an error, if + * you're discarding the entire connection. + */ + void complete(); + + /// Insert a row of data. + /** Returns a reference to the stream, so you can chain the calls. + * + * The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * If you don't already happen to have your fields in the form of a tuple or + * container, prefer @c write_values. It's faster and more convenient. + */ + template stream_to &operator<<(Row const &row) + { + write_row(row); + return *this; + } + + /// Stream a `stream_from` straight into a `stream_to`. + /** This can be useful when copying between different databases. If the + * source and the destination are on the same database, you'll get better + * performance doing it all in a regular query. + */ + stream_to &operator<<(stream_from &); + + /// Insert a row of data, given in the form of a @c std::tuple or container. + /** The @c row can be a tuple, or any type that can be iterated. Each + * item becomes a field in the row, in the same order as the columns you + * specified when creating the stream. + * + * The preferred way to insert a row is @c write_values. + */ + template void write_row(Row const &row) + { + fill_buffer(row); + write_buffer(); + } + + /// Insert values as a row. + /** This is the recommended way of inserting data. Pass your field values, + * of any convertible type. + */ + template void write_values(Ts const &...fields) + { + fill_buffer(fields...); + write_buffer(); + } + +private: + /// Stream a pre-quoted table name and columns list. + stream_to( + transaction_base &tx, std::string_view path, std::string_view columns); + + bool m_finished = false; + + /// Reusable buffer for a row. Saves doing an allocation for each row. + std::string m_buffer; + + /// Reusable buffer for converting/escaping a field. + std::string m_field_buf; + + /// Glyph scanner, for parsing the client encoding. + internal::glyph_scanner_func *m_scanner; + + /// Write a row of raw text-format data into the destination table. + void write_raw_line(std::string_view); + + /// Write a row of data from @c m_buffer into the destination table. + /** Resets the buffer for the next row. + */ + void write_buffer(); + + /// COPY encoding for a null field, plus subsequent separator. + static constexpr std::string_view null_field{"\\N\t"}; + + /// Estimate buffer space needed for a field which is always null. + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &) + { + return std::size(null_field); + } + + /// Estimate buffer space needed for field f. + /** The estimate is not very precise. We don't actually know how much space + * we'll need once the escaping comes in. + */ + template + static std::enable_if_t::always_null, std::size_t> + estimate_buffer(T const &field) + { + return is_null(field) ? std::size(null_field) : size_buffer(field); + } + + /// Append escaped version of @c data to @c m_buffer, plus a tab. + void escape_field_to_buffer(std::string_view data); + + /// Append string representation for @c f to @c m_buffer. + /** This is for the general case, where the field may contain a value. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &f) + { + // We append each field, terminated by a tab. That will leave us with + // one tab too many, assuming we write any fields at all; we remove that + // at the end. + if (is_null(f)) + { + // Easy. Append null and tab in one go. + m_buffer.append(null_field); + } + else + { + // Convert f into m_buffer. + + using traits = string_traits; + auto const budget{estimate_buffer(f)}; + auto const offset{std::size(m_buffer)}; + + if constexpr (std::is_arithmetic_v) + { + // Specially optimised for "safe" types, which never need any + // escaping. Convert straight into m_buffer. + + // The budget we get from size_buffer() includes room for the trailing + // zero, which we must remove. But we're also inserting tabs between + // fields, so we re-purpose the extra byte for that. + auto const total{offset + budget}; + m_buffer.resize(total); + auto const data{m_buffer.data()}; + char *const end{traits::into_buf(data + offset, data + total, f)}; + *(end - 1) = '\t'; + // Shrink to fit. Keep the tab though. + m_buffer.resize(static_cast(end - data)); + } + else if constexpr ( + std::is_same_v or + std::is_same_v or + std::is_same_v) + { + // This string may need escaping. + m_field_buf.resize(budget); + escape_field_to_buffer(f); + } + else + { + // This field needs to be converted to a string, and after that, + // escaped as well. + m_field_buf.resize(budget); + auto const data{m_field_buf.data()}; + escape_field_to_buffer( + traits::to_buf(data, data + std::size(m_field_buf), f)); + } + } + } + + /// Append string representation for a null field to @c m_buffer. + /** This special case is for types which are always null. + * + * Also appends a tab. The tab is meant to be a separator, not a terminator, + * so if you write any fields at all, you'll end up with one tab too many + * at the end of the buffer. + */ + template + std::enable_if_t::always_null> + append_to_buffer(Field const &) + { + m_buffer.append(null_field); + } + + /// Write raw COPY line into @c m_buffer, based on a container of fields. + template + std::enable_if_t> + fill_buffer(Container const &c) + { + // To avoid unnecessary allocations and deallocations, we run through c + // twice: once to determine how much buffer space we may need, and once to + // actually write it into the buffer. + std::size_t budget{0}; + for (auto const &f : c) budget += estimate_buffer(f); + m_buffer.reserve(budget); + for (auto const &f : c) append_to_buffer(f); + } + + /// Estimate how many buffer bytes we need to write tuple. + template + static std::size_t + budget_tuple(Tuple const &t, std::index_sequence) + { + return (estimate_buffer(std::get(t)) + ...); + } + + /// Write tuple of fields to @c m_buffer. + template + void append_tuple(Tuple const &t, std::index_sequence) + { + (append_to_buffer(std::get(t)), ...); + } + + /// Write raw COPY line into @c m_buffer, based on a tuple of fields. + template void fill_buffer(std::tuple const &t) + { + using indexes = std::make_index_sequence; + + m_buffer.reserve(budget_tuple(t, indexes{})); + append_tuple(t, indexes{}); + } + + /// Write raw COPY line into @c m_buffer, based on varargs fields. + template void fill_buffer(const Ts &...fields) + { + (..., append_to_buffer(fields)); + } + + constexpr static std::string_view s_classname{"stream_to"}; +}; + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Columns const &columns) : + stream_to{tx, table_name, std::begin(columns), std::end(columns)} +{} + + +template +inline stream_to::stream_to( + transaction_base &tx, std::string_view table_name, Iter columns_begin, + Iter columns_end) : + stream_to{ + tx, + tx.quote_name( + table_name, + separated_list(",", columns_begin, columns_end, [&tx](auto col) { + return tx.quote_name(*col); + }))} +{} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction new file mode 100644 index 0000000..e0d1549 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction @@ -0,0 +1,8 @@ +/** pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one inside a transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/subtransaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction.hxx new file mode 100644 index 0000000..e66b7a7 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/subtransaction.hxx @@ -0,0 +1,96 @@ +/* Definition of the pqxx::subtransaction class. + * + * pqxx::subtransaction is a nested transaction, i.e. one within a transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/subtransaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_SUBTRANSACTION +#define PQXX_H_SUBTRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx +{ +/** + * @ingroup transactions + */ +/// "Transaction" nested within another transaction +/** A subtransaction can be executed inside a backend transaction, or inside + * another subtransaction. This can be useful when, for example, statements in + * a transaction may harmlessly fail and you don't want them to abort the + * entire transaction. Here's an example of how a temporary table may be + * dropped before re-creating it, without failing if the table did not exist: + * + * ```cxx + * void do_job(connection &C) + * { + * string const temptable = "fleetingtable"; + * + * work W(C, "do_job"); + * do_firstpart(W); + * + * // Attempt to delete our temporary table if it already existed. + * try + * { + * subtransaction S(W, "droptemp"); + * S.exec0("DROP TABLE " + temptable); + * S.commit(); + * } + * catch (undefined_table const &) + * { + * // Table did not exist. Which is what we were hoping to achieve anyway. + * // Carry on without regrets. + * } + * + * // S may have gone into a failed state and been destroyed, but the + * // upper-level transaction W is still fine. We can continue to use it. + * W.exec0("CREATE TEMP TABLE " + temptable + "(bar integer, splat + * varchar)"); + * + * do_lastpart(W); + * } + * ``` + * + * (This is just an example. If you really wanted to do drop a table without + * an error if it doesn't exist, you'd use DROP TABLE IF EXISTS.) + * + * There are no isolation levels inside a transaction. They are not needed + * because all actions within the same backend transaction are always performed + * sequentially anyway. + * + * @warning While the subtransaction is "live," you cannot execute queries or + * open streams etc. on its parent transaction. A transaction can have at most + * one object of a type derived from @ref pqxx::transaction_focus active on it + * at a time. + */ +class PQXX_LIBEXPORT subtransaction : public transaction_focus, + public dbtransaction +{ +public: + /// Nest a subtransaction nested in another transaction. + explicit subtransaction(dbtransaction &t, std::string_view tname = ""sv); + + /// Nest a subtransaction in another subtransaction. + explicit subtransaction(subtransaction &t, std::string_view name = ""sv); + + virtual ~subtransaction() noexcept override; + +private: + std::string quoted_name() const + { + return quote_name(transaction_focus::name()); + } + virtual void do_commit() override; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time new file mode 100644 index 0000000..85df057 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time @@ -0,0 +1,6 @@ +/** Date/time string conversions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/time.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time.hxx new file mode 100644 index 0000000..effed05 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/time.hxx @@ -0,0 +1,88 @@ +/** Support for date/time values. + * + * At the moment this supports dates, but not times. + */ +#ifndef PQXX_H_TIME +#define PQXX_H_TIME + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/internal/concat.hxx" +#include "pqxx/strconv.hxx" + + +#if defined(PQXX_HAVE_YEAR_MONTH_DAY) + +namespace pqxx +{ +using namespace std::literals; + +template<> +struct nullness + : no_null +{}; + + +/// String representation for a Gregorian date in ISO-8601 format. +/** @warning Experimental. There may still be design problems, particularly + * when it comes to BC years. + * + * PostgreSQL supports a choice of date formats, but libpqxx does not. The + * other formats in turn support a choice of "month before day" versus "day + * before month," meaning that it's not necessarily known which format a given + * date is supposed to be. So I repeat: ISO-8601-style format only! + * + * Invalid dates will not convert. This includes February 29 on non-leap + * years, which is why it matters that `year_month_day` represents a + * _Gregorian_ date. + * + * The range of years is limited. At the time of writing, PostgreSQL 14 + * supports years from 4713 BC to 294276 AD inclusive, and C++20 supports + * a range of 32767 BC to 32767 AD inclusive. So in practice, years must fall + * between 4713 BC and 32767 AD, inclusive. + * + * @warning Support for BC (or BCE) years is still experimental. I still need + * confirmation on this issue: it looks as if C++ years are astronomical years, + * which means they have a Year Zero. Regular BC/AD years do not have a year + * zero, so the year 1 AD follows directly after 1 BC. + * + * So, what to our calendars (and to PostgreSQL) is the year "0001 BC" seems to + * count as year "0" in a `std::chrono::year_month_day`. The year 0001 AD is + * still equal to 1 as you'd expect, and all AD years work normally, but all + * years before then are shifted by one. For instance, the year 543 BC would + * be -542 in C++. + */ +template<> struct PQXX_LIBEXPORT string_traits +{ + [[nodiscard]] static zview + to_buf(char *begin, char *end, std::chrono::year_month_day const &value) + { + return generic_to_buf(begin, end, value); + } + + static char * + into_buf(char *begin, char *end, std::chrono::year_month_day const &value); + + [[nodiscard]] static std::chrono::year_month_day + from_string(std::string_view text); + + [[nodiscard]] static std::size_t + size_buffer(std::chrono::year_month_day const &) noexcept + { + static_assert(int{(std::chrono::year::min)()} >= -99999); + static_assert(int{(std::chrono::year::max)()} <= 99999); + return 5 + 1 + 2 + 1 + 2 + std::size(s_bc) + 1; + } + +private: + /// The "BC" suffix for years before 1 AD. + static constexpr std::string_view s_bc{" BC"sv}; +}; +} // namespace pqxx +#endif // PQXX_HAVE_YEAR_MONTH_DAY +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction new file mode 100644 index 0000000..a7ae39d --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction @@ -0,0 +1,8 @@ +/** pqxx::transaction class. + * + * pqxx::transaction represents a standard database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction.hxx new file mode 100644 index 0000000..e90917e --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction.hxx @@ -0,0 +1,108 @@ +/* Definition of the pqxx::transaction class. + * pqxx::transaction represents a standard database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION +#define PQXX_H_TRANSACTION + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/dbtransaction.hxx" + +namespace pqxx::internal +{ +/// Helper base class for the @ref transaction class template. +class PQXX_LIBEXPORT basic_transaction : public dbtransaction +{ +protected: + basic_transaction( + connection &c, zview begin_command, std::string_view tname); + basic_transaction(connection &c, zview begin_command, std::string &&tname); + basic_transaction(connection &c, zview begin_command); + + virtual ~basic_transaction() noexcept override = 0; + +private: + virtual void do_commit() override; +}; +} // namespace pqxx::internal + + +namespace pqxx +{ +/** + * @ingroup transactions + */ +//@{ + +/// Standard back-end transaction, templatised on isolation level. +/** This is the type you'll normally want to use to represent a transaction on + * the database. + * + * Usage example: double all wages. + * + * ```cxx + * extern connection C; + * work T(C); + * try + * { + * T.exec0("UPDATE employees SET wage=wage*2"); + * T.commit(); // NOTE: do this inside try block + * } + * catch (exception const &e) + * { + * cerr << e.what() << endl; + * T.abort(); // Usually not needed; same happens when T's life ends. + * } + * ``` + */ +template< + isolation_level ISOLATION = isolation_level::read_committed, + write_policy READWRITE = write_policy::read_write> +class transaction final : public internal::basic_transaction +{ +public: + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * @param tname Optional name for transaction. Must begin with a letter and + * may contain letters and digits only. + */ + transaction(connection &c, std::string_view tname) : + internal::basic_transaction{ + c, internal::begin_cmd, tname} + {} + + /// Begin a transaction. + /** + * @param c Connection for this transaction to operate on. + * may contain letters and digits only. + */ + explicit transaction(connection &c) : + internal::basic_transaction{ + c, internal::begin_cmd} + {} + + virtual ~transaction() noexcept override { close(); } +}; + + +/// The default transaction type. +using work = transaction<>; + +/// Read-only transaction. +using read_transaction = + transaction; + +//@} +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base new file mode 100644 index 0000000..c39219a --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base @@ -0,0 +1,9 @@ +/** Base for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transaction_base.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base.hxx new file mode 100644 index 0000000..4363cc5 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_base.hxx @@ -0,0 +1,810 @@ +/* Common code and definitions for the transaction classes. + * + * pqxx::transaction_base defines the interface for any abstract class that + * represents a database transaction. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_BASE +#define PQXX_H_TRANSACTION_BASE + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +/* End-user programs need not include this file, unless they define their own + * transaction classes. This is not something the typical program should want + * to do. + * + * However, reading this file is worthwhile because it defines the public + * interface for the available transaction classes such as transaction and + * nontransaction. + */ + +#include "pqxx/connection.hxx" +#include "pqxx/internal/concat.hxx" +#include "pqxx/internal/encoding_group.hxx" +#include "pqxx/isolation.hxx" +#include "pqxx/result.hxx" +#include "pqxx/row.hxx" +#include "pqxx/stream_from.hxx" +#include "pqxx/util.hxx" + +namespace pqxx::internal::gate +{ +class transaction_subtransaction; +class transaction_sql_cursor; +class transaction_stream_to; +class transaction_transaction_focus; +} // namespace pqxx::internal::gate + + +namespace pqxx +{ +using namespace std::literals; + + +class transaction_focus; + + +/** + * @defgroup transactions Transaction classes + * + * All database access goes through instances of these classes. + * However, not all implementations of this interface need to provide full + * transactional integrity. + * + * Several implementations of this interface are shipped with libpqxx, + * including the plain transaction class, the entirely unprotected + * nontransaction, and the more cautious robusttransaction. + */ + +/// Interface definition (and common code) for "transaction" classes. +/** + * @ingroup transactions + * + * Abstract base class for all transaction types. + */ +class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base +{ +public: + transaction_base() = delete; + transaction_base(transaction_base const &) = delete; + transaction_base(transaction_base &&) = delete; + transaction_base &operator=(transaction_base const &) = delete; + transaction_base &operator=(transaction_base &&) = delete; + + virtual ~transaction_base() = 0; + + /// Commit the transaction. + /** Make the effects of this transaction definite. If you destroy a + * transaction without invoking its @ref commit() first, that will implicitly + * abort it. (For the @ref nontransaction class though, "commit" and "abort" + * really don't do anything, hence its name.) + * + * There is, however, a minute risk that you might lose your connection to + * the database at just the wrong moment here. In that case, libpqxx may be + * unable to determine whether the database was able to complete the + * transaction, or had to roll it back. In that scenario, @ref commit() will + * throw an in_doubt_error. There is a different transaction class called + * @ref robusttransaction which takes some special precautions to reduce this + * risk. + */ + void commit(); + + /// Abort the transaction. + /** No special effort is required to call this function; it will be called + * implicitly when the transaction is destructed. + */ + void abort(); + + /** + * @ingroup escaping-functions + * + * Use these when writing SQL queries that incorporate C++ values as SQL + * constants. + * + * The functions you see here are just convenience shortcuts to the same + * functions on the connection object. + */ + //@{ + /// Escape string for use as SQL string literal in this transaction. + template [[nodiscard]] auto esc(ARGS &&...args) const + { + return conn().esc(std::forward(args)...); + } + + /// Escape binary data for use as SQL string literal in this transaction. + /** Raw, binary data is treated differently from regular strings. Binary + * strings are never interpreted as text, so they may safely include byte + * values or byte sequences that don't happen to represent valid characters + * in the character encoding being used. + * + * The binary string does not stop at the first zero byte, as is the case + * with textual strings. Instead, it may contain zero bytes anywhere. If + * it happens to contain bytes that look like quote characters, or other + * things that can disrupt their use in SQL queries, they will be replaced + * with special escape sequences. + */ + template [[nodiscard]] auto esc_raw(ARGS &&...args) const + { + return conn().esc_raw(std::forward(args)...); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(zview text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(zview text) + { + return conn().unesc_bin(text); + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string + unesc_raw(char const *text) const + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return conn().unesc_raw(text); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Unescape binary data, e.g. from a table field or notification payload. + /** Takes a binary string as escaped by PostgreSQL, and returns a restored + * copy of the original binary data. + */ + [[nodiscard]] std::basic_string unesc_bin(char const text[]) + { + return conn().unesc_bin(text); + } + + /// Represent object as SQL string, including quoting & escaping. + /** Nulls are recognized and represented as SQL nulls. */ + template [[nodiscard]] std::string quote(T const &t) const + { + return conn().quote(t); + } + + [[deprecated( + "Use std::basic_string instead of binarystring.")]] std::string + quote(binarystring const &t) const + { + return conn().quote(t.bytes_view()); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(unsigned char const bin[], std::size_t len) const + { + return quote(binary_cast(bin, len)); + } + + /// Binary-escape and quote a binary string for use as an SQL constant. + [[deprecated("Use quote(std::basic_string_view).")]] std::string + quote_raw(zview bin) const; + +#if defined(PQXX_HAVE_CONCEPTS) + /// Binary-escape and quote a binary string for use as an SQL constant. + /** For binary data you can also just use @ref quote(data). */ + template + [[nodiscard]] std::string quote_raw(DATA const &data) const + { + return conn().quote_raw(data); + } +#endif + + /// Escape an SQL identifier for use in a query. + [[nodiscard]] std::string quote_name(std::string_view identifier) const + { + return conn().quote_name(identifier); + } + + /// Escape string for literal LIKE match. + [[nodiscard]] std::string + esc_like(std::string_view bin, char escape_char = '\\') const + { + return conn().esc_like(bin, escape_char); + } + //@} + + /** + * @name Command execution + * + * There are many functions for executing (or "performing") a command (or + * "query"). This is the most fundamental thing you can do with the library, + * and you always do it from a transaction class. + * + * Command execution can throw many types of exception, including sql_error, + * broken_connection, and many sql_error subtypes such as + * feature_not_supported or insufficient_privilege. But any exception thrown + * by the C++ standard library may also occur here. All exceptions you will + * see libpqxx throw are derived from std::exception. + * + * One unusual feature in libpqxx is that you can give your query a name or + * description. This does not mean anything to the database, but sometimes + * it can help libpqxx produce more helpful error messages, making problems + * in your code easier to debug. + * + * Many of the execution functions used to accept a `desc` argument, a + * human-readable description of the statement for use in error messages. + * This could make failures easier to debug. Future versions will use + * C++20's `std::source_location` to identify the failing statement. + */ + //@{ + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated("The desc parameter is going away.")]] result + exec(std::string_view query, std::string_view desc); + + /// Execute a command. + /** + * @param query Query or command to execute. + * @return A result set describing the query's or command's result. + */ + result exec(std::string_view query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute a command. + /** + * @param query Query or command to execute. + * @param desc Optional identifier for query, to help pinpoint SQL errors. + * @return A result set describing the query's or command's result. + */ + [[deprecated( + "Pass your query as a std::string_view, not stringstream.")]] result + exec(std::stringstream const &query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec(query.str(), desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec0(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(0, query, desc); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command, which should return zero rows of data. + /** Works like @ref exec, but fails if the result contains data. It still + * returns a result, however, which may contain useful metadata. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec0(zview query) { return exec_n(0, query); } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] row + exec1(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(1, query, desc).front(); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Execute command returning a single row of data. + /** Works like @ref exec, but requires the result to contain exactly one row. + * The row can be addressed directly, without the need to find the first row + * in a result set. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + row exec1(zview query) { return exec_n(1, query).front(); } + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + [[deprecated("The desc parameter is going away.")]] result + exec_n(result::size_type rows, zview query, std::string_view desc); + + /// Execute command, expect given number of rows. + /** Works like @ref exec, but checks that the result has exactly the expected + * number of rows. + * + * @throw unexpected_rows If the query returned the wrong number of rows. + */ + result exec_n(result::size_type rows, zview query) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + return exec_n(rows, query, std::string_view{}); +#include "pqxx/internal/ignore-deprecated-post.hxx" + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template + [[deprecated("The desc parameter is going away.")]] TYPE + query_value(zview query, std::string_view desc) + { +#include "pqxx/internal/ignore-deprecated-pre.hxx" + row const r{exec1(query, desc)}; +#include "pqxx/internal/ignore-deprecated-post.hxx" + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Perform query, expecting exactly 1 row with 1 field, and convert it. + /** This is convenience shorthand for querying exactly one value from the + * database. It returns that value, converted to the type you specify. + */ + template TYPE query_value(zview query) + { + row const r{exec1(query)}; + if (std::size(r) != 1) + throw usage_error{internal::concat( + "Queried single value from result with ", std::size(r), " columns.")}; + return r[0].as(); + } + + /// Execute a query, and loop over the results row by row. + /** Converts the rows to `std::tuple`, of the column types you specify. + * + * Use this with a range-based "for" loop. It executes the query, and + * directly maps the resulting rows onto a `std::tuple` of the types you + * specify. It starts before all the data from the server is in, so if your + * network connection to the server breaks while you're iterating, you'll get + * an exception partway through. + * + * The stream lives entirely within the lifetime of the transaction. Make + * sure you destroy the stream before you destroy the transaction. Either + * iterate the stream all the way to the end, or destroy first the stream + * and then the transaction without touching either in any other way. Until + * the stream has finished, the transaction is in a special state where it + * cannot execute queries. + * + * As a special case, tuple may contain `std::string_view` fields, but the + * strings to which they point will only remain valid until you extract the + * next row. After that, the memory holding the string may be overwritten or + * deallocated. + * + * If any of the columns can be null, and the C++ type to which it translates + * does not have a null value, wrap the type in `std::optional` (or if + * you prefer, `std::shared_ptr` or `std::unique_ptr)`. These templates + * do recognise null values, and libpqxx will know how to convert to them. + * + * The connection is in a special state until the iteration finishes. So if + * it does not finish due to a `break` or a `return` or an exception, then + * the entire connection becomes effectively unusable. + * + * Querying in this way is faster than the `exec()` methods for larger + * results (but slower for small ones). You can start processing rows before + * the full result is in. Also, `stream()` scales better in terms of memory + * usage. Where @ref exec() reads the entire result into memory at once, + * `stream()` will read and process one row at at a time. + * + * Your query executes as part of a COPY command, not as a stand-alone query, + * so there are limitations to what you can do in the query. It can be + * either a SELECT or VALUES query; or an INSERT, UPDATE, or DELETE with a + * RETURNING clause. See the documentation for PostgreSQL's COPY command for + * the details: + * + * https://www.postgresql.org/docs/current/sql-copy.html + * + * Iterating in this way does require each of the field types you pass to be + * default-constructible, copy-constructible, and assignable. These + * requirements may be loosened once libpqxx moves on to C++20. + */ + template + [[nodiscard]] auto stream(std::string_view query) & + { + // Tricky: std::make_unique() supports constructors but not RVO functions. + return pqxx::internal::owning_stream_input_iteration{ + std::unique_ptr{ + new stream_from{stream_from::query(*this, query)}}}; + } + + // C++20: Concept like std::invocable, but without specifying param types. + /// Perform a streaming query, and for each result row, call `func`. + /** Here, `func` can be a function, a `std::function`, a lambda, or an + * object that supports the function call operator. Of course `func` must + * have an unambiguous signature; it can't be overloaded or generic. + * + * The `for_each` function executes `query` in a stream using + * @ref pqxx::stream_from. Every time a row of data comes in from the + * server, it converts the row's fields to the types of `func`'s respective + * parameters, and calls `func` with those values. + * + * This will not work for all queries, but straightforward `SELECT` and + * `UPDATE ... RETURNING` queries should work. Consult the documentation for + * @ref pqxx::stream_from and PostgreSQL's underlying `COPY` command for the + * full details. + * + * Streaming a query like this is likely to be slower than the @ref exec() + * functions for small result sets, but faster for large result sets. So if + * performance matters, you'll want to use `for_each` if you query large + * amounts of data, but not if you do lots of queries with small outputs. + */ + template + inline auto for_each(std::string_view query, CALLABLE &&func) + { + using param_types = + pqxx::internal::strip_types_t>; + param_types const *const sample{nullptr}; + auto data_stream{stream_like(query, sample)}; + for (auto const &fields : data_stream) std::apply(func, fields); + } + + /** + * @name Parameterized statements + * + * You'll often need parameters in the queries you execute: "select the + * car with this licence plate." If the parameter is a string, you need to + * quote it and escape any special characters inside it, or it may become a + * target for an SQL injection attack. If it's an integer (for example), + * you need to convert it to a string, but in the database's format, without + * locale-specific niceties like "," separators between the thousands. + * + * Parameterised statements are an easier and safer way to do this. They're + * like prepared statements, but for a single use. You don't need to name + * them, and you don't need to prepare them first. + * + * Your query will include placeholders like `$1` and `$2` etc. in the places + * where you want the arguments to go. Then, you pass the argument values + * and the actual query is constructed for you. + * + * Pass the exact right number of parameters, and in the right order. The + * parameters in the query don't have to be neatly ordered from `$1` to + * `$2` to `$3` - but you must pass the argument for `$1` first, the one + * for `$2` second, etc. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. + */ + //@{ + /// Execute an SQL statement with parameters. + template result exec_params(zview query, Args &&...args) + { + params pp(args...); + return internal_exec_params(query, pp.make_c_params()); + } + + // Execute parameterised statement, expect a single-row result. + /** @throw unexpected_rows if the result does not consist of exactly one row. + */ + template row exec_params1(zview query, Args &&...args) + { + return exec_params_n(1, query, std::forward(args)...).front(); + } + + // Execute parameterised statement, expect a result with zero rows. + /** @throw unexpected_rows if the result contains rows. + */ + template result exec_params0(zview query, Args &&...args) + { + return exec_params_n(0, query, std::forward(args)...); + } + + // Execute parameterised statement, expect exactly a given number of rows. + /** @throw unexpected_rows if the result contains the wrong number of rows. + */ + template + result exec_params_n(std::size_t rows, zview query, Args &&...args) + { + auto const r{exec_params(query, std::forward(args)...)}; + check_rowcount_params(rows, std::size(r)); + return r; + } + //@} + + /** + * @name Prepared statements + * + * These are very similar to parameterised statements. The difference is + * that you prepare them in advance, giving them identifying names. You can + * then call them by these names, passing in the argument values appropriate + * for that call. + * + * You prepare a statement on the connection, using + * @ref pqxx::connection::prepare(). But you then call the statement in a + * transaction, using the functions you see here. + * + * Never try to prepare, execute, or unprepare a prepared statement manually + * using direct SQL queries when you also use the libpqxx equivalents. For + * any given statement, either prepare, manage, and execute it through the + * dedicated libpqxx functions; or do it all directly in SQL. Don't mix the + * two, or the code may get confused. + * + * See \ref prepared for a full discussion. + * + * @warning Beware of "nul" bytes. Any string you pass as a parameter will + * end at the first char with value zero. If you pass a string that contains + * a zero byte, the last byte in the value will be the one just before the + * zero. If you need a zero byte, you're dealing with binary strings, not + * regular strings. Represent binary strings on the SQL side as `BYTEA` + * (or as large objects). On the C++ side, use types like + * `std::basic_string` or `std::basic_string_view` + * or (in C++20) `std::vector`. Also, consider large objects on + * the SQL side and @ref blob on the C++ side. + */ + //@{ + + /// Execute a prepared statement, with optional arguments. + template + result exec_prepared(zview statement, Args &&...args) + { + params pp(args...); + return internal_exec_prepared(statement, pp.make_c_params()); + } + + /// Execute a prepared statement, and expect a single-row result. + /** @throw pqxx::unexpected_rows if the result was not exactly 1 row. + */ + template + row exec_prepared1(zview statement, Args &&...args) + { + return exec_prepared_n(1, statement, std::forward(args)...).front(); + } + + /// Execute a prepared statement, and expect a result with zero rows. + /** @throw pqxx::unexpected_rows if the result contained rows. + */ + template + result exec_prepared0(zview statement, Args &&...args) + { + return exec_prepared_n(0, statement, std::forward(args)...); + } + + /// Execute a prepared statement, expect a result with given number of rows. + /** @throw pqxx::unexpected_rows if the result did not contain exactly the + * given number of rows. + */ + template + result + exec_prepared_n(result::size_type rows, zview statement, Args &&...args) + { + auto const r{exec_prepared(statement, std::forward(args)...)}; + check_rowcount_prepared(statement, rows, std::size(r)); + return r; + } + + //@} + + /** + * @name Error/warning output + */ + //@{ + /// Have connection process a warning message. + void process_notice(char const msg[]) const { m_conn.process_notice(msg); } + /// Have connection process a warning message. + void process_notice(zview msg) const { m_conn.process_notice(msg); } + //@} + + /// The connection in which this transaction lives. + [[nodiscard]] constexpr connection &conn() const noexcept { return m_conn; } + + /// Set session variable using SQL "SET" command. + /** @deprecated To set a transaction-local variable, execute an SQL `SET` + * command. To set a session variable, use the connection's + * @ref set_session_var function. + * + * @warning When setting a string value, you must make sure that the string + * is "safe." If you call @ref quote() on the string, it will return a + * safely escaped and quoted version for use as an SQL literal. + * + * @warning This function executes SQL. Do not try to set or get variables + * while a pipeline or table stream is active. + * + * @param var The variable to set. + * @param value The new value to store in the variable. This can be any SQL + * expression. + */ + [[deprecated( + "Set transaction-local variables using SQL SET statements.")]] void + set_variable(std::string_view var, std::string_view value); + + /// Read session variable using SQL "SHOW" command. + /** @warning This executes SQL. Do not try to set or get variables while a + * pipeline or table stream is active. + */ + [[deprecated("Read variables using SQL SHOW statements.")]] std::string + get_variable(std::string_view); + + // C++20: constexpr. + /// Transaction name, if you passed one to the constructor; or empty string. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + +protected: + /// Create a transaction (to be called by implementation classes only). + /** The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base( + connection &c, std::string_view tname, + std::shared_ptr rollback_cmd) : + m_conn{c}, m_name{tname}, m_rollback_cmd{rollback_cmd} + {} + + /// Create a transaction (to be called by implementation classes only). + /** Its rollback command will be "ROLLBACK". + * + * The name, if nonempty, must begin with a letter and may contain letters + * and digits only. + */ + transaction_base(connection &c, std::string_view tname); + + /// Create a transaction (to be called by implementation classes only). + explicit transaction_base(connection &c); + + /// Register this transaction with the connection. + void register_transaction(); + + /// End transaction. To be called by implementing class' destructor. + void close() noexcept; + + /// To be implemented by derived implementation class: commit transaction. + virtual void do_commit() = 0; + + /// Transaction type-specific way of aborting a transaction. + /** @warning This will become "final", since this function can be called + * from the implementing class destructor. + */ + virtual void do_abort(); + + /// Set the rollback command. + void set_rollback_cmd(std::shared_ptr cmd) + { + m_rollback_cmd = cmd; + } + + /// Execute query on connection directly. + result direct_exec(std::string_view, std::string_view desc = ""sv); + result + direct_exec(std::shared_ptr, std::string_view desc = ""sv); + +private: + enum class status + { + active, + aborted, + committed, + in_doubt + }; + + PQXX_PRIVATE void check_pending_error(); + + result + internal_exec_prepared(zview statement, internal::c_params const &args); + + result internal_exec_params(zview query, internal::c_params const &args); + + /// Throw unexpected_rows if prepared statement returned wrong no. of rows. + void check_rowcount_prepared( + zview statement, result::size_type expected_rows, + result::size_type actual_rows); + + /// Throw unexpected_rows if wrong row count from parameterised statement. + void + check_rowcount_params(std::size_t expected_rows, std::size_t actual_rows); + + /// Describe this transaction to humans, e.g. "transaction 'foo'". + [[nodiscard]] std::string description() const; + + friend class pqxx::internal::gate::transaction_transaction_focus; + PQXX_PRIVATE void register_focus(transaction_focus *); + PQXX_PRIVATE void unregister_focus(transaction_focus *) noexcept; + PQXX_PRIVATE void register_pending_error(zview) noexcept; + PQXX_PRIVATE void register_pending_error(std::string &&) noexcept; + + /// Like @ref stream(), but takes a tuple rather than a parameter pack. + template + auto stream_like(std::string_view query, std::tuple const *) + { + return stream(query); + } + + connection &m_conn; + + /// Current "focus": a pipeline, a nested transaction, a stream... + /** This pointer is used for only one purpose: sanity checks against mistakes + * such as opening one while another is still active. + */ + transaction_focus const *m_focus = nullptr; + + status m_status = status::active; + bool m_registered = false; + std::string m_name; + std::string m_pending_error; + + /// SQL command for aborting this type of transaction. + std::shared_ptr m_rollback_cmd; + + static constexpr std::string_view s_type_name{"transaction"sv}; +}; + + +// C++20: Can borrowed_range help? +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +std::string_view transaction_base::query_value( + zview query, std::string_view desc) = delete; +/// Forbidden specialisation: underlying buffer immediately goes out of scope. +template<> +zview transaction_base::query_value( + zview query, std::string_view desc) = delete; + +} // namespace pqxx + + +namespace pqxx::internal +{ +/// The SQL command for starting a given type of transaction. +template +extern const zview begin_cmd; + +// These are not static members, so "constexpr" does not imply "inline". +template<> +inline constexpr zview begin_cmd{ + "BEGIN"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE"_zv}; +template<> +inline constexpr zview begin_cmd{ + "BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY"_zv}; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus new file mode 100644 index 0000000..fe78a9b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus @@ -0,0 +1,7 @@ +/** + * Transaction focus: types which monopolise a transaction's attention. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus.hxx new file mode 100644 index 0000000..0707e3c --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transaction_focus.hxx @@ -0,0 +1,89 @@ +/** Transaction focus: types which monopolise a transaction's attention. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTION_FOCUS +#define PQXX_H_TRANSACTION_FOCUS + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include "pqxx/util.hxx" + +namespace pqxx +{ +/// Base class for things that monopolise a transaction's attention. +/** You probably won't need to use this class. But it can be useful to _know_ + * that a given libpqxx class is derived from it. + * + * Pipelines, SQL statements, and data streams are examples of classes derived + * from `transaction_focus`. For any given transaction, only one object of + * such a class can be active at any given time. + */ +class PQXX_LIBEXPORT transaction_focus +{ +public: + transaction_focus( + transaction_base &t, std::string_view cname, std::string_view oname) : + m_trans{t}, m_classname{cname}, m_name{oname} + {} + + transaction_focus( + transaction_base &t, std::string_view cname, std::string &&oname) : + m_trans{t}, m_classname{cname}, m_name{std::move(oname)} + {} + + transaction_focus(transaction_base &t, std::string_view cname) : + m_trans{t}, m_classname{cname} + {} + + transaction_focus() = delete; + transaction_focus(transaction_focus const &) = delete; + transaction_focus &operator=(transaction_focus const &) = delete; + + /// Class name, for human consumption. + [[nodiscard]] constexpr std::string_view classname() const noexcept + { + return m_classname; + } + + /// Name for this object, if the caller passed one; empty string otherwise. + [[nodiscard]] std::string_view name() const &noexcept { return m_name; } + + [[nodiscard]] std::string description() const + { + return pqxx::internal::describe_object(m_classname, m_name); + } + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus(transaction_focus &&) = delete; + + /// Can't move a transaction_focus. + /** Moving the transaction_focus would break the transaction's reference back + * to the object. + */ + transaction_focus &operator=(transaction_focus &&) = delete; + +protected: + void register_me(); + void unregister_me() noexcept; + void reg_pending_error(std::string const &) noexcept; + bool registered() const noexcept { return m_registered; } + + transaction_base &m_trans; + +private: + bool m_registered = false; + std::string_view m_classname; + std::string m_name; +}; +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor new file mode 100644 index 0000000..29d1b96 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor @@ -0,0 +1,8 @@ +/** pqxx::transactor class. + * + * pqxx::transactor is a framework-style wrapper for safe transactions. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/transactor.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor.hxx new file mode 100644 index 0000000..eefd04b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/transactor.hxx @@ -0,0 +1,147 @@ +/* Transactor framework, a wrapper for safely retryable transactions. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TRANSACTOR +#define PQXX_H_TRANSACTOR + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include + +#include "pqxx/connection.hxx" +#include "pqxx/transaction.hxx" + +namespace pqxx +{ +/** + * @defgroup transactor Transactor framework + * + * Sometimes a transaction can fail for completely transient reasons, such as a + * conflict with another transaction in SERIALIZABLE isolation. The right way + * to handle those failures is often just to re-run the transaction from + * scratch. + * + * For example, your REST API might be handling each HTTP request in its own + * database transaction, and if this kind of transient failure happens, you + * simply want to "replay" the whole request, in a fresh transaction. + * + * You won't necessarily want to execute the exact same SQL commands with the + * exact same data. Some of your SQL statements may depend on state that can + * vary between retries. Data in the database may already have changed, for + * instance. So instead of dumbly replaying the SQL, you re-run the same + * application code that produced those SQL commands, from the start. + * + * The transactor framework makes it a little easier for you to do this safely, + * and avoid typical pitfalls. You encapsulate the work that you want to do + * into a callable that you pass to the @ref perform function. + * + * Here's how it works. You write your transaction code as a lambda or + * function, which creates its own transaction object, does its work, and + * commits at the end. You pass that callback to @ref pqxx::perform, which + * runs it for you. + * + * If there's a failure inside your callback, there will be an exception. Your + * transaction object goes out of scope and gets destroyed, so that it aborts + * implicitly. Seeing this, @ref perform tries running your callback again. It + * stops doing that when the callback succeeds, or when it has failed too many + * times, or when there's an error that leaves the database in an unknown + * state, such as a lost connection just while we're waiting for the database + * to confirm a commit. It all depends on the type of exception. + * + * The callback takes no arguments. If you're using lambdas, the easy way to + * pass arguments is for the lambda to "capture" them from your variables. Or, + * if you're using functions, you may want to use `std::bind`. + * + * Once your callback succeeds, it can return a result, and @ref perform will + * return that result back to you. + */ +//@{ + +/// Simple way to execute a transaction with automatic retry. +/** + * Executes your transaction code as a callback. Repeats it until it completes + * normally, or it throws an error other than the few libpqxx-generated + * exceptions that the framework understands, or after a given number of failed + * attempts, or if the transaction ends in an "in-doubt" state. + * + * (An in-doubt state is one where libpqxx cannot determine whether the server + * finally committed a transaction or not. This can happen if the network + * connection to the server is lost just while we're waiting for its reply to + * a "commit" statement. The server may have completed the commit, or not, but + * it can't tell you because there's no longer a connection. + * + * Using this still takes a bit of care. If your callback makes use of data + * from the database, you'll probably have to query that data within your + * callback. If the attempt to perform your callback fails, and the framework + * tries again, you'll be in a new transaction and the data in the database may + * have changed under your feet. + * + * Also be careful about changing variables or data structures from within + * your callback. The run may still fail, and perhaps get run again. The + * ideal way to do it (in most cases) is to return your result from your + * callback, and change your program's data state only after @ref perform + * completes successfully. + * + * @param callback Transaction code that can be called with no arguments. + * @param attempts Maximum number of times to attempt performing callback. + * Must be greater than zero. + * @return Whatever your callback returns. + */ +template +inline auto perform(TRANSACTION_CALLBACK &&callback, int attempts = 3) + -> std::invoke_result_t +{ + if (attempts <= 0) + throw std::invalid_argument{ + "Zero or negative number of attempts passed to pqxx::perform()."}; + + for (; attempts > 0; --attempts) + { + try + { + return std::invoke(callback); + } + catch (in_doubt_error const &) + { + // Not sure whether transaction went through or not. The last thing in + // the world that we should do now is try again! + throw; + } + catch (statement_completion_unknown const &) + { + // Not sure whether our last statement succeeded. Don't risk running it + // again. + throw; + } + catch (broken_connection const &) + { + // Connection failed. May be worth retrying, if the transactor opens its + // own connection. + if (attempts <= 1) + throw; + continue; + } + catch (transaction_rollback const &) + { + // Some error that may well be transient, such as serialization failure + // or deadlock. Worth retrying. + if (attempts <= 1) + throw; + continue; + } + } + throw pqxx::internal_error{"No outcome reached on perform()."}; +} +} // namespace pqxx +//@} +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types new file mode 100644 index 0000000..23a5caa --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types @@ -0,0 +1,7 @@ +/** + * Basic typedefs and forward declarations. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/types.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types.hxx new file mode 100644 index 0000000..f95b598 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/types.hxx @@ -0,0 +1,173 @@ +/* Basic type aliases and forward declarations. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_TYPES +#define PQXX_H_TYPES + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include + +#if defined(PQXX_HAVE_CONCEPTS) && __has_include() +# include +#endif + + +namespace pqxx +{ +/// Number of rows in a result set. +using result_size_type = int; + +/// Difference between result sizes. +using result_difference_type = int; + +/// Number of fields in a row of database data. +using row_size_type = int; + +/// Difference between row sizes. +using row_difference_type = int; + +/// Number of bytes in a field of database data. +using field_size_type = std::size_t; + +/// Number of bytes in a large object. +using large_object_size_type = int64_t; + + +// Forward declarations, to help break compilation dependencies. +// These won't necessarily include all classes in libpqxx. +class binarystring; +class connection; +class const_result_iterator; +class const_reverse_result_iterator; +class const_reverse_row_iterator; +class const_row_iterator; +class dbtransaction; +class field; +class largeobjectaccess; +class notification_receiver; +struct range_error; +class result; +class row; +class stream_from; +class transaction_base; + +/// Marker for @ref stream_from constructors: "stream from table." +/** @deprecated Use @ref stream_from::table() instead. + */ +struct from_table_t +{}; + +/// Marker for @ref stream_from constructors: "stream from query." +/** @deprecated Use @ref stream_from::query() instead. + */ +struct from_query_t +{}; + + +/// Format code: is data text or binary? +/** Binary-compatible with libpq's format codes. + */ +enum class format : int +{ + text = 0, + binary = 1, +}; + + +/// Remove any constness, volatile, and reference-ness from a type. +/** @deprecated In C++20 we'll replace this with std::remove_cvref. + */ +template +using strip_t = std::remove_cv_t>; + + +#if defined(PQXX_HAVE_CONCEPTS) +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#else // PQXX_HAVE_CONCEPTS +/// The type of a container's elements. +/** At the time of writing there's a similar thing in `std::experimental`, + * which we may or may not end up using for this. + */ +template +using value_type = strip_t()))>; +#endif // PQXX_HAVE_CONCEPTS + + +#if defined(PQXX_HAVE_CONCEPTS) +/// Concept: Any type that we can read as a string of `char`. +template +concept char_string = std::ranges::contiguous_range and + std::same_as < strip_t>, +char > ; + +/// Concept: Anything we can iterate to get things we can read as strings. +template +concept char_strings = + std::ranges::range and char_string>>; + +/// Concept: Anything we might want to treat as binary data. +template +concept potential_binary = std::ranges::contiguous_range and + (sizeof(value_type) == 1); +#endif // PQXX_HAVE_CONCEPTS + + +// C++20: Retire these compatibility definitions. +#if defined(PQXX_HAVE_CONCEPTS) + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG std::ranges::range + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG pqxx::char_string + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG pqxx::char_strings + +#else // PQXX_HAVE_CONCEPTS + +/// Template argument type for a range. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_RANGE_ARG typename + +/// Template argument type for @ref char_string. +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRING_ARG typename + +/// Template argument type for @ref char_strings +/** This is a concept, so only available in C++20 or better. In pre-C++20 + * environments it's just an alias for @ref typename. + */ +# define PQXX_CHAR_STRINGS_ARG typename + +#endif // PQXX_HAVE_CONCEPTS +} // namespace pqxx +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util new file mode 100644 index 0000000..6d85ab6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util @@ -0,0 +1,6 @@ +/** Various utility definitions for libpqxx. + */ +// Actual definitions in .hxx file so editors and such recognize file type +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/util.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util.hxx new file mode 100644 index 0000000..4aa5ecf --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/util.hxx @@ -0,0 +1,521 @@ +/* Various utility definitions for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_UTIL +#define PQXX_H_UTIL + +#if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __has_include() +# include +#endif + +#include "pqxx/except.hxx" +#include "pqxx/internal/encodings.hxx" +#include "pqxx/types.hxx" +#include "pqxx/version.hxx" + + +/// The home of all libpqxx classes, functions, templates, etc. +namespace pqxx +{} + +#include + + +/// Internal items for libpqxx' own use. Do not use these yourself. +namespace pqxx::internal +{ + +// C++20: Retire wrapper. +/// Same as `std::cmp_less`, or a workaround where that's not available. +template +inline constexpr bool cmp_less(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less(lhs, rhs); +#else + // We need a variable just because lgtm.com gives off a false positive + // warning when we compare the values directly. It considers that a + // "self-comparison." + constexpr bool left_signed{std::is_signed_v}; + if constexpr (left_signed == std::is_signed_v) + return lhs < rhs; + else if constexpr (std::is_signed_v) + return (lhs <= 0) ? true : (std::make_unsigned_t(lhs) < rhs); + else + return (rhs <= 0) ? false : (lhs < std::make_unsigned_t(rhs)); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater, or workaround if not available. +template +inline constexpr bool cmp_greater(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater(lhs, rhs); +#else + return cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_less_equal, or workaround if not available. +template +inline constexpr bool cmp_less_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_less_equal(lhs, rhs); +#else + return not cmp_less(rhs, lhs); +#endif +} + + +// C++20: Retire wrapper. +/// C++20 std::cmp_greater_equal, or workaround if not available. +template +inline constexpr bool cmp_greater_equal(LEFT lhs, RIGHT rhs) noexcept +{ +#if defined(PQXX_HAVE_CMP) + return std::cmp_greater_equal(lhs, rhs); +#else + return not cmp_less(lhs, rhs); +#endif +} + + +/// Efficiently concatenate two strings. +/** This is a special case of concatenate(), needed because dependency + * management does not let us use that function here. + */ +[[nodiscard]] inline std::string cat2(std::string_view x, std::string_view y) +{ + std::string buf; + auto const xs{std::size(x)}, ys{std::size(y)}; + buf.resize(xs + ys); + x.copy(std::data(buf), xs); + y.copy(std::data(buf) + xs, ys); + return buf; +} +} // namespace pqxx::internal + + +namespace pqxx +{ +using namespace std::literals; + +/// Suppress compiler warning about an unused item. +template inline constexpr void ignore_unused(T &&...) noexcept +{} + + +/// Cast a numeric value to another type, or throw if it underflows/overflows. +/** Both types must be arithmetic types, and they must either be both integral + * or both floating-point types. + */ +template +inline TO check_cast(FROM value, std::string_view description) +{ + static_assert(std::is_arithmetic_v); + static_assert(std::is_arithmetic_v); + static_assert(std::is_integral_v == std::is_integral_v); + + // The rest of this code won't quite work for bool, but bool is trivially + // convertible to other arithmetic types as far as I can see. + if constexpr (std::is_same_v) + return static_cast(value); + + // Depending on our "if constexpr" conditions, this parameter may not be + // needed. Some compilers will warn. + ignore_unused(description); + + using from_limits = std::numeric_limits; + using to_limits = std::numeric_limits; + if constexpr (std::is_signed_v) + { + if constexpr (std::is_signed_v) + { + if (value < to_limits::lowest()) + throw range_error{internal::cat2("Cast underflow: "sv, description)}; + } + else + { + // FROM is signed, but TO is not. Treat this as a special case, because + // there may not be a good broader type in which the compiler can even + // perform our check. + if (value < 0) + throw range_error{internal::cat2( + "Casting negative value to unsigned type: "sv, description)}; + } + } + else + { + // No need to check: the value is unsigned so can't fall below the range + // of the TO type. + } + + if constexpr (std::is_integral_v) + { + using unsigned_from = std::make_unsigned_t; + using unsigned_to = std::make_unsigned_t; + constexpr auto from_max{static_cast((from_limits::max)())}; + constexpr auto to_max{static_cast((to_limits::max)())}; + if constexpr (from_max > to_max) + { + if (internal::cmp_greater(value, to_max)) + throw range_error{internal::cat2("Cast overflow: "sv, description)}; + } + } + else if constexpr ((from_limits::max)() > (to_limits::max)()) + { + if (value > (to_limits::max)()) + throw range_error{internal::cat2("Cast overflow: ", description)}; + } + + return static_cast(value); +} + + +/** Check library version at link time. + * + * Ensures a failure when linking an application against a radically + * different libpqxx version than the one against which it was compiled. + * + * Sometimes application builds fail in unclear ways because they compile + * using headers from libpqxx version X, but then link against libpqxx + * binary version Y. A typical scenario would be one where you're building + * against a libpqxx which you have built yourself, but a different version + * is installed on the system. + * + * The check_library_version template is declared for any library version, + * but only actually defined for the version of the libpqxx binary against + * which the code is linked. + * + * If the library binary is a different version than the one declared in + * these headers, then this call will fail to link: there will be no + * definition for the function with these exact template parameter values. + * There will be a definition, but the version in the parameter values will + * be different. + */ +inline PQXX_PRIVATE void check_version() noexcept +{ + // There is no particular reason to do this here in @ref connection, except + // to ensure that every meaningful libpqxx client will execute it. The call + // must be in the execution path somewhere or the compiler won't try to link + // it. We can't use it to initialise a global or class-static variable, + // because a smart compiler might resolve it at compile time. + // + // On the other hand, we don't want to make a useless function call too + // often for performance reasons. A local static variable is initialised + // only on the definition's first execution. Compilers will be well + // optimised for this behaviour, so there's a minimal one-time cost. + static auto const version_ok{internal::PQXX_VERSION_CHECK()}; + ignore_unused(version_ok); +} + + +/// Descriptor of library's thread-safety model. +/** This describes what the library knows about various risks to thread-safety. + */ +struct PQXX_LIBEXPORT thread_safety_model +{ + /// Is the underlying libpq build thread-safe? + bool safe_libpq = false; + + /// Is Kerberos thread-safe? + /** @warning Is currently always `false`. + * + * If your application uses Kerberos, all accesses to libpqxx or Kerberos + * must be serialized. Confine their use to a single thread, or protect it + * with a global lock. + */ + bool safe_kerberos = false; + + /// A human-readable description of any thread-safety issues. + std::string description; +}; + + +/// Describe thread safety available in this build. +[[nodiscard]] PQXX_LIBEXPORT thread_safety_model describe_thread_safety(); + + +#if defined(PQXX_HAVE_CONCEPTS) +# define PQXX_POTENTIAL_BINARY_ARG pqxx::potential_binary +#else +# define PQXX_POTENTIAL_BINARY_ARG typename +#endif + + +/// Cast binary data to a type that libpqxx will recognise as binary. +/** There are many different formats for storing binary data in memory. You + * may have yours as a `std::string`, or a `std::vector`, or one of + * many other types. + * + * But for libpqxx to recognise your data as binary, it needs to be a + * `std::basic_string`, or a `std::basic_string_view`; + * or in C++20 or better, any contiguous block of `std::byte`. + * + * Use `binary_cast` as a convenience helper to cast your data as a + * `std::basic_string_view`. + * + * @warning There are two things you should be aware of! First, the data must + * be contiguous in memory. In C++20 the compiler will enforce this, but in + * C++17 it's your own problem. Second, you must keep the object where you + * store the actual data alive for as long as you might use this function's + * return value. + */ +template +std::basic_string_view binary_cast(TYPE const &data) +{ + static_assert(sizeof(value_type) == 1); + return { + reinterpret_cast( + const_cast const *>( + std::data(data))), + std::size(data)}; +} + + +#if defined(PQXX_HAVE_CONCEPTS) +template +concept char_sized = (sizeof(CHAR) == 1); +# define PQXX_CHAR_SIZED_ARG char_sized +#else +# define PQXX_CHAR_SIZED_ARG typename +#endif + +/// Construct a type that libpqxx will recognise as binary. +/** Takes a data pointer and a size, without being too strict about their + * types, and constructs a `std::basic_string_view` pointing to + * the same data. + * + * This makes it a little easier to turn binary data, in whatever form you + * happen to have it, into binary data as libpqxx understands it. + */ +template +std::basic_string_view binary_cast(CHAR const *data, SIZE size) +{ + static_assert(sizeof(CHAR) == 1); + return { + reinterpret_cast(data), + check_cast(size, "binary data size")}; +} + + +/// The "null" oid. +constexpr oid oid_none{0}; +} // namespace pqxx + + +/// Private namespace for libpqxx's internal use; do not access. +/** This namespace hides definitions internal to libpqxx. These are not + * supposed to be used by client programs, and they may change at any time + * without notice. + * + * Conversely, if you find something in this namespace tremendously useful, by + * all means do lodge a request for its publication. + * + * @warning Here be dragons! + */ +namespace pqxx::internal +{ +using namespace std::literals; + + +/// A safer and more generic replacement for `std::isdigit`. +/** Turns out `std::isdigit` isn't as easy to use as it sounds. It takes an + * `int`, but requires it to be nonnegative. Which means it's an outright + * liability on systems where `char` is signed. + */ +template inline constexpr bool is_digit(CHAR c) noexcept +{ + return (c >= '0') and (c <= '9'); +} + + +/// Describe an object for humans, based on class name and optional name. +/** Interprets an empty name as "no name given." + */ +[[nodiscard]] std::string +describe_object(std::string_view class_name, std::string_view name); + + +/// Check validity of registering a new "guest" in a "host." +/** The host might be e.g. a connection, and the guest a transaction. The + * host can only have one guest at a time, so it is an error to register a new + * guest while the host already has a guest. + * + * If the new registration is an error, this function throws a descriptive + * exception. + * + * Pass the old guest (if any) and the new guest (if any), for both, a type + * name (at least if the guest is not null), and optionally an object name + * (but which may be omitted if the caller did not assign one). + */ +void check_unique_register( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Like @ref check_unique_register, but for un-registering a guest. +/** Pass the guest which was registered, as well as the guest which is being + * unregistered, so that the function can check that they are the same one. + */ +void check_unique_unregister( + void const *old_guest, std::string_view old_class, std::string_view old_name, + void const *new_guest, std::string_view new_class, + std::string_view new_name); + + +/// Compute buffer size needed to escape binary data for use as a BYTEA. +/** This uses the hex-escaping format. The return value includes room for the + * "\x" prefix. + */ +inline constexpr std::size_t size_esc_bin(std::size_t binary_bytes) noexcept +{ + return 2 + (2 * binary_bytes) + 1; +} + + +/// Compute binary size from the size of its escaped version. +/** Do not include a terminating zero in `escaped_bytes`. + */ +inline constexpr std::size_t size_unesc_bin(std::size_t escaped_bytes) noexcept +{ + return (escaped_bytes - 2) / 2; +} + + +// TODO: Use actual binary type for "data". +/// Hex-escape binary data into a buffer. +/** The buffer must be able to accommodate + * `size_esc_bin(std::size(binary_data))` bytes, and the function will write + * exactly that number of bytes into the buffer. This includes a trailing + * zero. + */ +void PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data, char buffer[]) noexcept; + + +/// Hex-escape binary data into a std::string. +std::string PQXX_LIBEXPORT +esc_bin(std::basic_string_view binary_data); + + +/// Reconstitute binary data from its escaped version. +void PQXX_LIBEXPORT +unesc_bin(std::string_view escaped_data, std::byte buffer[]); + + +/// Reconstitute binary data from its escaped version. +std::basic_string + PQXX_LIBEXPORT unesc_bin(std::string_view escaped_data); + + +/// Transitional: std::ssize(), or custom implementation if not available. +template auto ssize(T const &c) +{ +#if defined(__cpp_lib_ssize) && __cplusplus >= __cpp_lib_ssize + return std::ssize(c); +#else + using signed_t = std::make_signed_t; + return static_cast(std::size(c)); +#endif // __cpp_lib_ssize +} + + +/// Helper for determining a function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(RETURN (&func)(ARGS...)); + + +/// Helper for determining a `std::function`'s parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple args_f(std::function const &); + + +/// Helper for determining a member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...)); + + +/// Helper for determining a const member function's parameter types. +/** This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +std::tuple member_args_f(RETURN (CLASS::*)(ARGS...) const); + + +/// Helper for determining a callable type's parameter types. +/** This specialisation should work for lambdas. + * + * This function has no definition. It's not meant to be actually called. + * It's just there for pattern-matching in the compiler, so we can use its + * hypothetical return value. + */ +template +auto args_f(CALLABLE const &f) + -> decltype(member_args_f(&CALLABLE::operator())); + + +/// A callable's parameter types, as a tuple. +template +using args_t = decltype(args_f(std::declval())); + + +/// Helper: Apply `strip_t` to each of a tuple type's component types. +/** This function has no definition. It is not meant to be called, only to be + * used to deduce the right types. + */ +template +std::tuple...> strip_types(std::tuple const &); + + +/// Take a tuple type and apply @ref strip_t to its component types. +template +using strip_types_t = decltype(strip_types(std::declval())); +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version new file mode 100644 index 0000000..8dd5e48 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version @@ -0,0 +1,7 @@ +/** libpqxx version info. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/version.hxx" +#include "pqxx/internal/header-post.hxx" + diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version.hxx new file mode 100644 index 0000000..a159f1b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/version.hxx @@ -0,0 +1,55 @@ +/* Version info for libpqxx. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_VERSION + +# if !defined(PQXX_HEADER_PRE) +# error "Include libpqxx headers as , not ." +# endif + +/// Full libpqxx version string. +# define PQXX_VERSION "7.7.3" +/// Library ABI version. +# define PQXX_ABI "7.7" + +/// Major version number. +# define PQXX_VERSION_MAJOR 7 +/// Minor version number. +# define PQXX_VERSION_MINOR 7 + +# define PQXX_VERSION_CHECK check_pqxx_version_7_7 + +namespace pqxx::internal +{ +/// Library version check stub. +/** Helps detect version mismatches between libpqxx headers and the libpqxx + * library binary. + * + * Sometimes users run into trouble linking their code against libpqxx because + * they build their own libpqxx, but the system also has a different version + * installed. The declarations in the headers against which they compile their + * code will differ from the ones used to build the libpqxx version they're + * using, leading to confusing link errors. The solution is to generate a link + * error when the libpqxx binary is not the same version as the libpqxx headers + * used to compile the code. + * + * This function's definition is in the libpqxx binary, so it's based on the + * version as found in the binary. The headers contain a call to the function, + * whose name contains the libpqxx version as found in the headers. (The + * library build process will use its own local headers even if another version + * of the headers is installed on the system.) + * + * If the libpqxx binary was compiled for a different version than the user's + * code, linking will fail with an error: `check_pqxx_version_*_*` will not + * exist for the given version number. + */ +PQXX_LIBEXPORT int PQXX_VERSION_CHECK() noexcept; +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview new file mode 100644 index 0000000..66ea2a6 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview @@ -0,0 +1,6 @@ +/** Zero-terminated string view class. + */ +// Actual definitions in .hxx file so editors and such recognize file type. +#include "pqxx/internal/header-pre.hxx" +#include "pqxx/zview.hxx" +#include "pqxx/internal/header-post.hxx" diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview.hxx b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview.hxx new file mode 100644 index 0000000..36a779f --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/include/pqxx/zview.hxx @@ -0,0 +1,163 @@ +/* Zero-terminated string view. + * + * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/zview instead. + * + * Copyright (c) 2000-2022, Jeroen T. Vermeulen. + * + * See COPYING for copyright license. If you did not receive a file called + * COPYING with this source code, please notify the distributor of this + * mistake, or contact the author. + */ +#ifndef PQXX_H_ZVIEW +#define PQXX_H_ZVIEW + +#include +#include +#include + +#include "pqxx/types.hxx" + + +namespace pqxx +{ +/// Marker-type wrapper: zero-terminated `std::string_view`. +/** @warning Use this only if the underlying string is zero-terminated. + * + * When you construct a zview, you are promising that if the data pointer is + * non-null, the underlying string is zero-terminated. It otherwise behaves + * exactly like a std::string_view. + * + * The terminating zero is not "in" the string, so it does not count as part of + * the view's length. + * + * The added guarantee lets the view be used as a C-style string, which often + * matters since libpqxx builds on top of a C library. For this reason, zview + * also adds a @ref c_str method. + */ +class zview : public std::string_view +{ +public: + constexpr zview() noexcept = default; + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char const text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Convenience overload: construct using pointer and signed length. + constexpr zview(char text[], std::ptrdiff_t len) : + std::string_view{text, static_cast(len)} + {} + + /// Explicitly promote a `string_view` to a `zview`. + explicit constexpr zview(std::string_view other) noexcept : + std::string_view{other} + {} + + /// Construct from any initialiser you might use for `std::string_view`. + /** @warning Only do this if you are sure that the string is zero-terminated. + */ + template + explicit constexpr zview(Args &&...args) : + std::string_view(std::forward(args)...) + {} + + // C++20: constexpr. + /// @warning There's an implicit conversion from `std::string`. + zview(std::string const &str) noexcept : + std::string_view{str.c_str(), str.size()} + {} + + /// Construct a `zview` from a C-style string. + /** @warning This scans the string to discover its length. So if you need to + * do it many times, it's probably better to create the `zview` once and + * re-use it. + */ + constexpr zview(char const str[]) : std::string_view{str} {} + + /// Construct a `zview` from a string literal. + /** A C++ string literal ("foo") normally looks a lot like a pointer to + * char const, but that's not really true. It's actually an array of char, + * which _devolves_ to a pointer when you pass it. + * + * For the purpose of creating a `zview` there is one big difference: if we + * know the array's size, we don't need to scan through the string in order + * to find out its length. + */ + template + constexpr zview(char const (&literal)[size]) : zview(literal, size - 1) + {} + + /// Either a null pointer, or a zero-terminated text buffer. + [[nodiscard]] constexpr char const *c_str() const &noexcept + { + return data(); + } +}; + + +/// Support @ref zview literals. +/** You can "import" this selectively into your namespace, without pulling in + * all of the @ref pqxx namespace: + * + * ```cxx + * using pqxx::operator"" _zv; + * ``` + */ +constexpr zview operator"" _zv(char const str[], std::size_t len) noexcept +{ + return zview{str, len}; +} +} // namespace pqxx + + +#if defined(PQXX_HAVE_CONCEPTS) +/// A zview is a view. +template<> inline constexpr bool std::ranges::enable_view{true}; + + +/// A zview is a borrowed range. +template<> +inline constexpr bool std::ranges::enable_borrowed_range{true}; + +namespace pqxx::internal +{ +/// Concept: T is a known zero-terminated string type. +/** There's no unified API for these string types. It's just a check for some + * known types. Any code that makes use of the concept will still have to + * support each of these individually. + */ +template +concept ZString = std::is_convertible_v < strip_t, +char const * > or std::is_convertible_v, zview> or + std::is_convertible_v; +} // namespace pqxx::internal +#endif // PQXX_HAVE_CONCEPTS + + +namespace pqxx::internal +{ +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(char const str[]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +template +inline constexpr char const *as_c_string(char (&str)[N]) noexcept +{ + return str; +} +/// Get a raw C string pointer. +inline constexpr char const *as_c_string(pqxx::zview str) noexcept +{ + return str.c_str(); +} +// C++20: Make this constexpr. +/// Get a raw C string pointer. +inline char const *as_c_string(std::string const &str) noexcept +{ + return str.c_str(); +} +} // namespace pqxx::internal +#endif diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config-version.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config-version.cmake new file mode 100644 index 0000000..c47d695 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config-version.cmake @@ -0,0 +1,70 @@ +# This is a basic version file for the Config-mode of find_package(). +# It is used by write_basic_package_version_file() as input file for configure_file() +# to create a version-file which can be installed along a config.cmake file. +# +# The created file sets PACKAGE_VERSION_EXACT if the current version string and +# the requested version string are exactly the same and it sets +# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, +# but only if the requested major version is the same as the current one. +# The variable CVF_VERSION must be set before calling configure_file(). + + +set(PACKAGE_VERSION "7.7.3") + +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + + if("7.7.3" MATCHES "^([0-9]+)\\.") + set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}") + if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0) + string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}") + endif() + else() + set(CVF_VERSION_MAJOR "7.7.3") + endif() + + if(PACKAGE_FIND_VERSION_RANGE) + # both endpoints of the range must have the expected major version + math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") + if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT))) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + else() + if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() + endif() +endif() + + +# if the installed project requested no architecture check, don't perform the check +if("FALSE") + return() +endif() + +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") + return() +endif() + +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") + math(EXPR installedBits "8 * 8") + set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif() diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config.cmake new file mode 100644 index 0000000..cb25a05 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-config.cmake @@ -0,0 +1,4 @@ +include(CMakeFindDependencyMacro) +find_dependency(PostgreSQL) + +include("${CMAKE_CURRENT_LIST_DIR}/libpqxx-targets.cmake") diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake new file mode 100644 index 0000000..980f460 --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets-noconfig.cmake @@ -0,0 +1,19 @@ +#---------------------------------------------------------------- +# Generated CMake target import file. +#---------------------------------------------------------------- + +# Commands may need to know the format version. +set(CMAKE_IMPORT_FILE_VERSION 1) + +# Import target "libpqxx::pqxx" for configuration "" +set_property(TARGET libpqxx::pqxx APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) +set_target_properties(libpqxx::pqxx PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_NOCONFIG "CXX" + IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libpqxx-7.7.a" + ) + +list(APPEND _IMPORT_CHECK_TARGETS libpqxx::pqxx ) +list(APPEND _IMPORT_CHECK_FILES_FOR_libpqxx::pqxx "${_IMPORT_PREFIX}/lib/libpqxx-7.7.a" ) + +# Commands beyond this point should not need to know the version. +set(CMAKE_IMPORT_FILE_VERSION) diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets.cmake b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets.cmake new file mode 100644 index 0000000..c7b525b --- /dev/null +++ b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/cmake/libpqxx/libpqxx-targets.cmake @@ -0,0 +1,99 @@ +# Generated by CMake + +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6) + message(FATAL_ERROR "CMake >= 2.6.0 required") +endif() +cmake_policy(PUSH) +cmake_policy(VERSION 2.6...3.20) +#---------------------------------------------------------------- +# Generated CMake target import file. +#---------------------------------------------------------------- + +# Commands may need to know the format version. +set(CMAKE_IMPORT_FILE_VERSION 1) + +# Protect against multiple inclusion, which would fail when already imported targets are added once more. +set(_targetsDefined) +set(_targetsNotDefined) +set(_expectedTargets) +foreach(_expectedTarget libpqxx::pqxx) + list(APPEND _expectedTargets ${_expectedTarget}) + if(NOT TARGET ${_expectedTarget}) + list(APPEND _targetsNotDefined ${_expectedTarget}) + endif() + if(TARGET ${_expectedTarget}) + list(APPEND _targetsDefined ${_expectedTarget}) + endif() +endforeach() +if("${_targetsDefined}" STREQUAL "${_expectedTargets}") + unset(_targetsDefined) + unset(_targetsNotDefined) + unset(_expectedTargets) + set(CMAKE_IMPORT_FILE_VERSION) + cmake_policy(POP) + return() +endif() +if(NOT "${_targetsDefined}" STREQUAL "") + message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n") +endif() +unset(_targetsDefined) +unset(_targetsNotDefined) +unset(_expectedTargets) + + +# Compute the installation prefix relative to this file. +get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +if(_IMPORT_PREFIX STREQUAL "/") + set(_IMPORT_PREFIX "") +endif() + +# Create imported target libpqxx::pqxx +add_library(libpqxx::pqxx STATIC IMPORTED) + +set_target_properties(libpqxx::pqxx PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include" + INTERFACE_LINK_LIBRARIES "/usr/lib/aarch64-linux-gnu/libpq.so" +) + +if(CMAKE_VERSION VERSION_LESS 2.8.12) + message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.") +endif() + +# Load information for each installed configuration. +get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +file(GLOB CONFIG_FILES "${_DIR}/libpqxx-targets-*.cmake") +foreach(f ${CONFIG_FILES}) + include(${f}) +endforeach() + +# Cleanup temporary variables. +set(_IMPORT_PREFIX) + +# Loop over all imported files and verify that they actually exist +foreach(target ${_IMPORT_CHECK_TARGETS} ) + foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} ) + if(NOT EXISTS "${file}" ) + message(FATAL_ERROR "The imported target \"${target}\" references the file + \"${file}\" +but this file does not exist. Possible reasons include: +* The file was deleted, renamed, or moved to another location. +* An install or uninstall procedure did not complete successfully. +* The installation package was faulty and contained + \"${CMAKE_CURRENT_LIST_FILE}\" +but not all the files it references. +") + endif() + endforeach() + unset(_IMPORT_CHECK_FILES_FOR_${target}) +endforeach() +unset(_IMPORT_CHECK_TARGETS) + +# This file does not depend on other imported targets which have +# been exported from the same project but in a separate export set. + +# Commands beyond this point should not need to know the version. +set(CMAKE_IMPORT_FILE_VERSION) +cmake_policy(POP) diff --git a/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/libpqxx-7.7.a b/ext/libpqxx-7.7.3/install/ubuntu22.04/arm64/lib/libpqxx-7.7.a new file mode 100644 index 0000000000000000000000000000000000000000..2cb705a34c561d8f7fdf049f81c34e0d61b351e7 GIT binary patch literal 4997126 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

    GHxEt7eC|`>T;TzHry*?zQ!rsq0 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

    )<=8B7BHJG6hcC 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≥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

    FvN`Rfv+f3HZdHlRkiTKo zp|F)0VpQT8Zb{|Dbui{&*Xwd9`5?8Tae=uW@}W!Ecx(>c-9(SV9RRSxHPt z;}bCC>#s5TQp1#HtbQzHG?ojVoiE@N)-(s_Jh zQpLjn`VcII0b~~c3`}W(;#*|L4N)xpxVo+$Q47|P!ZX483mQh>k!MK!E|=BC-55SC=CVOx1pAKbkfRo9M|cughE_~C6uvbN;EWa0n#zaO(6m^K;o5+M z0UyprAM#{+InMIXGyx;bK2?>Wy!b10%}C>CDHxE&14uQZ8%NOl&f0B|E6cx^21*tz zJR80PVYPDah%5INSI8Q5g$yhXeme}~%-l~{54G6>W72|K)TWDm*4IP47qglsKuoVg z^nO6fuNv0jIVooe?1iF5OmX8#`C+J=qgwNP$YIeaS5Ux61aWJ&M4!{?(?fFz#~--)edh);4-4vclMj zY+AWrRiYMcq@7BinLZ2Bb+-8?&cJNzPrdbUCdf2?4?D~+z&Zmr=bB#s0oPaVANT*q z`HcJ6{_mWd-6!^cS?@ly|5IH?saeKn-{UR?+@rvL@i)){VfKr8T~`lVx;YJ3wDr_{ zdpO6R9qot56}eG|J^tL*hdupIdi+0o`u}3@_4q&A(G>NI=f0+5uq~(XwWhm{;_>aK z`(WjhQ@FS3E;wfSKXd#4j;lQ`9WPB`O0SP{tFoY|<51G^rVgN0`2?Oqy`lDDU{hD` z=ms`qVxd;hU;g){c?8FO897J zHI@8PLjuJ=JJzN8ICgamyraCpS%&4B*ELAWjt+9YJ&mxV0f(0R7P%1iUf}jm90_KQ z8UY{YSxt>i%`keL&*Vm(TmYUv+4LZQKj_6pt}^x1B~Xp$7J7eoHE3g9RR{dq5&U|F z3*M&!gJ-zF)?QXqM=&kR|7KGv%u9dJL~w($F<|1h(uMyg6BmGuU}BXr(F=B-1?~SG z`1I$dmv999k^UGk4%BsB1Rhay9XF@hHH~KurvJcq9lfOseUQJK)%5AN|5rP<`xgBn zC!rlBU4tr+L^7Fl@}Wxle) zvJ#iKqN1!~fNNoy&(){WRZ!`w@RpaXboo}6dtLKa`e6Q0K{-glF=Jd)v$JxhGid@B|KJP+rg=<+sNfpNDSCuSw!7G==r3+md#yR%LNoB6es`B!( z3ZH91S%s_ATj}!_xt3Iw_=&^{Lc>N^8kPl%#VUX&vFAC$4Sa zEf`$USa5^dG92v@jKlR0-fa1xOBxH4b7A0ofckm}&2Q~CKEVHUI-a+RZ5{gx9HX@M7>bz}CG#b`+klg^@ zQtJ@Q)(3|^MC(JWJ|yXbOCQqpLBD=&!*(@PSA9mS&sYm~uPp0>nAF&g@N_8&BQZl_ z(($Mx!`q;tu{ttBMUr%6q>6Oaku()?>BuM*(SOnqbDoN%=#W?bsh+I&eM@`9fv?XnGpW~RAGgVOl*%$UacdO zoR>o6Djk^|n+DoybYzM%2O{fqWLCn{AhupdF6lBIQf||c+1>IXvPnngD03drk-2Re zAq^B3pE1p0ce`N9MuE{G?+bs;rDl zZxDCr%_5rauaqzgi4v%_9KY6td3~LDmd+= zKClDp?^kafn*g+REEc1LP^}h92O&tgnp3b0oia(MY~mCwP^EzQb8z1IBLt0F>P-qq1<0ce=xdKBbblr&c* z!B(#7C#XU7sWmVqgViXh;;~T2eSs?FNBzL(@m)JCg#uMo43ES2^`mt6Y2_H%=ca&$w8Ynf8b+yzLu)usY0wULj8+<2X$@^0WBa@t&~Sd@ z`#}xqDiWOi}8g~2=<+e;el`W3KTdSPdTXf!vUr&HDHf_!}~5AV30wu(;W$?frzWw zNa~3xz2a0S#Z!oMF(N&t7!gwQm7TO99@G>XNm@;*L3&+gM%EdTvu=V&)D4ZRdu=jk z??)lh;~Uj&wISd|2=--m;!AL0cUi{!&#r@poG!bqk=(1Z5$WxMNS{v(Vr#`;v~e9W zsO#TGMC**gcYP`JavBk2JsJ!fNaZbdLIUgTa0gI%bHwel{ZK zP|iScy*e2A&gImPH0);<8#EO+p)uIY>^7Iep7Q@%Hs?Q8*)56=*7y!xvSruV3E%vI zqB;K`D0&?ieTAJc5698}=yA?}s-g!_8P*W!(<`8mf%X&!%+|@wuT^Y@1O6st5VL`{ zibKy{V6-&#?7eook_0gJ3M0u?X+%_iJV_?=&$>mOG_Fp$$B=N?eVu-8)wOET~@HyQc36*XW=xqb-sg6n^|ImMz zPi60*{!{2~wc3hpMk7Y#w<$) zePJj49WJ`A-A0lw_XC6U`o@eLFe4|7$XT&4U16j5>SWAoy?Pmu9_I8*^ZIbR%~-et z>5Fsl|2FpqCrq!MP=z{v--KzlOmHgLgieBBXV?k&x2V6fnF2H5CY2kmo2O{97PC;G zOIi(-)gEmpEXMZueLW;lH0M86(SZSiQ-L1}!M<|&YB?eNMWx^bfaz--;iiQYqea!S z&$2(alP-h14_Ahfq&w0?gY>%Cj4U)Fy(=Kn;;K(`M4X-YB&@amKfLP0wGe{+MVmj+ z;=1wflX2ZZKcjRmrM+{NTL}dw)U&Xlk)q2(&E=^~RM$Z(K11#{DyTDl+G` z>1Je#BlZ|fcR>VY{x6vi%FIL7P?HryTc3r0*o@1!7M)r*8`kbJ{D5FP?M~^~H~z;? z&G~8QAGZ0YJAn@%T7;6Sr=uA}`-T(>`AB^qObOYL}n(c00=yuavLnnF`Ywqye9=XW*`$d4#jgj#?c1v z@i+{_lO(w12=>PwF2ioBWRfHKZFue1m1-pEN}gws;j4@Y+!d%W5AyZ8%t)|?k2hk} zcdfN3mTM$f!!I&oEcO_R%`p;Lh^$ z^`ZJi8pNEiO$z;EB%E6I3B9F?=Q;QR!M^iSNXDLd!amFFnE|uVVAQ0-3Dx^&MEzpV zfNxDjWPfibn)yn!ASlMW@PZ)OTyNaJAh`Yp%@t3f*zu9i`8 zDUP6rTDS{Mu|}g(`&qkfIv$6^%4rN}f7b4U+Q-6U4a{3VHr#8}TdB>|Q+(C!~BDcLM(P_U#FUDDV}%TBS?W{_5$ zY8E=!?tt~u77WoAP@&OOC|*^u&}g&JR%W5CgN4RWp{f$GT3`CuWtN>_pN>_9r^EOG z*J67Q=*5YEM)=2}9WSa#S9u%_g8eq=RYEapCjlmrDlnGGyhIVG23sjzsYJU+=F=)0)o1>960UUC7 z*LNtU4y|L+p}N}3b+z$gn*nw$cf9~f8LC>#&p~@Kafj1hp>*bAc6+7Puk)Aa{5UaU zla#2zqTN<9tWf2L{;k|b4Y(-5#`{*3UNi)qOgulq#(PlY`J;o*&(C@VM0CmX;ywOIGnrh>;o1w0P zkk7zxII#!ip#OE=6rET3z_GA177(=#^TYn>!v4p=GG(!2k=j0-h}W;o%0-r=Gy$co ziFl<_pd#Tq1@L;Qz_Ns!5u~fgs)Rpd1iBV(!nTgZeb?5pxOdt*7WY4O`7?F-uYf3) zKeKPJ{0mk2)}*8jiTpAM{(0z1Yci_E;P|xlq){72{;y9C@y&~|t`XLxo*R0|r-uB( z1it40uS!hnx}mdt(1;Hg7X^)IJNc|UZ4M0A`F7h$y*7kA+vIl~@YMvRw%dj-@_8uq z+ZK8gG7~0s+|VAy%*UwSV9AajTL)e7ajW3@=dA)3B@S^U1S8$yshr);?vvOdJ}U9_ z#CCT3m?W5P9G$JG#8L6*#izyRK&OuCZNFzs{V!3SfGTGP zJ1Q|gJ}3f@9fOvR1c`P*)8QFa2S~;8I)GR#R|v&AcC!0+({^@hrR?sE1WWCr%4iiV zqic&Yz?^O^v;jB`3Js`-2Mkzq{BczK{BB%xEDhb8-u2cDRZRC*I*;;-qsucH;P*3u zq2Eo`qr08jVXD0)qt%Qq7sbzNbzwXj>1t)AcA#86=s)dYd*xjJRkqa*RKk82oB~Z%-C*D~ zz#Uz0z`ONioq!b>q)%b*Dxg-`0!lGCl~urZ^8^IQ9ugT6uk1(Zp=J*wuM9($(_v^g zeDpLNWidNSkKhO_|5`Q?N(34xO`C8_MmMa}sFsr4n19lZc^(vo9l&h3(aF$PHN(bt zsd|kuTOF1;W{|q&5IvY2aEQzvicwjY0*dR1-dWd;SG}OT9Y~Y8mXuzQ4IC7GpR>?8`YB43s zk?HCRjqk}|=^T3$?(>F?b;)du{)jqEr_0`(_ex} ziw8exa0EfX^X%*uG;TUsSFDe|IXc$WJJxk}Y`-(FuzH>KfF0w$Jx~FB8YLXY&^A?(Hr>GVGhV4)FrrU#9CF>3aeM@86mwPn9@Wo`U4$XL!NT0 z*G7&X4a}!`e99gSD&cBgMD_<$n6LxltSi>pt+i2HYkuw*%*D0iWAHf$6Mf{)ZOk%Z zCW|#RS!@WMELw+77M})Dn3;iR%rG-U!6|13o(2X4$2?C1{|KV5{`<_((gS9Ue;y?0 zjk)ZNW9_t{ZOvtGTnw9+7y$9<-Gq{?HP+zXYph;FdedyelWTWau~H^JWfz8KdW}38 z^yu7BkIoJC=vKqFmj_Ub z400&7NR)%BMIt+wk1(G){!Z6S9!RaN11g!F&8^6s^YSsA4p?0`6jadhkwrNhEF zG-pV+aX6$9&g4Fr$qn7=6s?nG#9CL}hSTyHfeyvmf+@d8k6|k-03>rpsl^Olx!8^m zsLt5XztQ<&I!0OL_C}8IZ*Rcp!rNC2o#?3KIKoXAW)wme$6Fyjp33&}(YB^4^~MKU ztOF17wZTgY4-cO8pmll8$O8b7?5Kdad-C)Yrd!zfg^9oCKUlYw=ATw@cZMOtl7o}S zkXU{= zTat<3D^AV`s0y`;(GlJw-R=G~83f z5U&4m+PZ*DXvgBTHv%%D4&^jwpeuyx;j~EsnNU5Pc1u7e)SI04PCzEKEKb8m+L7wc zX)^;dp?WxNPC#a9NEhccqnE6a<27N*3uQSEM4Q^=l?Qy z^V79VcxH?t!WiS^%SbGoshn1GYE_*4&w#3m5D#d#q$*t%fA)Hm5mOwHQD#*!M z0ac+^aoWUFtK#IEfU3}@=d}7$tK#HW0;)o-;jHqJ|u?ruu_v9iPPGVOaxzX za!x>1XazZK%BfXx@-+cfp%vt`n@+8YlXnGFg<2(V^TIiSSN(if7fwdI@b`V5q?rW2 z;}b);PReO(12Um*;IzE~nb7)iTDw#97f$1!1_@^mr(JgnJ)HJVKqj<9aazYyv6$XR@wA7#ak z2&0Sd{Q0^Y*)}N|-Zm)}*0wa-f8#SBRGV9n(wWnY7o z91s7^#5tiR&IvU!@C=6ceZgg+Ce8^pG4NO>Xky3)N~?g4>_OfPcUU7gO8byW1CdE5 zBICzu>@sB1LHNZ+I>^$&o3d~~vTQ)IXh5=LKwJzTVbd^BG&A$a=2TL*inid7Fg9|G zU1VD`*~nL^lW9SY1-sr%HvI%`@@hej#ZZ?6jeOdjkQU@v-=H9$4s9XGv9UoxK80_+ zP(f?tSa2-NWMAIaLXcy@?l+S?Jd1{f*2pn#aj1;xQ#_|_qyT0=vqy11i(UF9xfB_D z&q0%9AvT-WU`oWb2ryrmUHUqC|H-@ zGaYf=+~iZPi)~GjRRJVx0!UT_5bNY4)q|@8m>=fyQ(LGJkKC!jC+#z66N8@!fD}Iz zFdnP(qkzG|$71{d;JYB=_GryZ7i$i0dKwSR`SNEx9p_4jqfwcAXnQwUnYp2rnHyS} zxuKPr8(NvUp_Q2%TA8__m6;n_nUGo8sD-MZtO|}uu1j&8b^$UzznmCsVsrggQKO+4 zp9dQ-PgW4cr0vM0@yJ9IsJTsA44e6EFn;SdhA{j4fj3691blL)gER;7vk8s|yJbGt zG+3+r(3Z@X6}7GW(3Z>(ZOMG;4ag{+0VrU&d15qYE2@0Z?%APs&knVFcBtL6L+zd& zYWM6=yJv^mJ=-)F&*^d>z_LBD-MMYJ*CFF`?tu;~bt6}hyB*5$IX4!{$tt3pv>ur> zA6dXqI)Sn8kTx5AkWCNM2USN4)~UVr$*4=0d2vYQ#l78!#y?n zJr8a`<~Hh6pV6_s6?*H(o|vp#N9ixyM&kTz!9^Z1*8CAp{ccAmJ*4 zgoK+xBXSW0MDEleN(jjTA|Z*%Nw`P>1752>V7*opygj`r6|Fv1w3W8@d9X^gH?{R? z#lBR1tZl8AR&CXHt(o=PXR`J=N`2cu-p@0TvuD1uX3d&4vu9t-p+Jn5BP$sGedAEczQ9mQ^j!-752YJ5;WuksY-mgNLs2=3?mD7N9x0{eRAe4#f zK_2G6bbi+Ra;EgHGTwh1j{9iakXIb`ebkT0s|sbJdXRTlC==~hqt@lWswT~0iACfIe z;qkO5Q%IX0O%ImG22+h$9&OC>Xk(V+fyz{4mPZ@2JldG$(Z(!~HfDLWF_E)&dnct? z{ERJ~5*!xvTG$)&=gaAM%G$_7Uv%Ce?uj~J$!<~gbf|I(qR)hAF?=#kYNOMgs85#Y zPM~{2S-KlA{NZ@i4}L5R3ZbG&k(0ee5P!DuQ|2{i3I}bOmB@u*Sc~@q(=TiZ8uHiY3yDKd$EmqOLfT@ z*{%Pv%qaSi7l#_zraKVqGa7d>oUuH_onCaTCrQETG93V-lIhQjw7xWz#=Lt}rCHvTJrVn3_z?+y znZWlHK3ghHgx4Ayt~& z0I50~Beg6*Es3y}1&E^JEU$TMwB`lTnj<%esph!*Ma6tMA=w<>r(1%kc}oPz)17)m zzb8Mw;9ra_*@M(Cg_0nmFLe+^ieLZ6fdmod7fV^R1ksyA6!|*9%Gys@emJyzF`^#| z%JSBGi1!e!_Q!5Wq0X4M7|~rK$b}JyNw%ywIFKMuF7;) zEr{$Eu4RFA$E>iY=A-joOd&+kiN4ozMGOh_VVt{u@D(wnVKbc*YrE3iIb)-)lio2e zTc zQeqdU5kodwMcUR!#Bd|ItMtQ!RDYn0o=&09?{(K7h^A5Jiu(7>3-JQ(}l>pJg$tH}#nnhnq38 z(Ug?Rwz1-1TqYxb~$hH8f`6)p}YXte;rmcIB_@54?ks6V*4bck)*=ms5 zk`hETT*b#bPjnx{292TP9inInSGaf&Qn!jS5=0b6TS27w3k?n=h-e?D35)k2g$9x! zqG+Afh*YX!i>>O^XO^kSsOQS~^@9kgoYH6+bsm~CQN#!#x->-RA&SnTo{R0dP4XX- zt?zA&?Lp$lVd15S!XZWuiGt8OOAv)W=x7j2pc%qxYabys!n~<1RaZIQC&RyN`M>rE{OIcGwnz|H`ncEIW!mzV+PY<95d95Eluf8 zr!q}v5iDa3h@&4}i_+B&m!zxRS|M%>Z@z31<6>Urmn6DBg$_s*ULYy-dN0vrzQ`*d zl3hM5yR@IZe%pgQIEv1jU@iKaG{IFcnvhf%Zce6{?Y``gaRgT)9Uvw2`BbqSMc2qy z%j*Hbm|ia;k8n(Nwzrjr6g_aUoHQhwA;QPh899n4_@w+ zE2m=l1{u%RY!G+zixxTH$F{xX9_`HDmg7Bpi}09x1^yW|{h3w-5DilX3Wu){p1qP@mSX zpT5gvFZAefs`X+2#J6eiQhmU49 zwWWDg1^Ux`x&bqsvFvHPqC%)+Rh7Dv8l6>*&>d zF6odk*`xUlbuFGJ?*ODm(tCnR)^KB6lC`yoRTL)^j1)!bgs8Qlj&dkY=NGFJ$;PH+ zRZU}a!e-K9nyod-su{E9Oea7`+Ek1R)iv5;rZUt)i#LvHrH=-yp@yrnV%04ziRPq@ zQ)zO5jeEhFUXDFABQyQou~-lkQYfNV!cjDSK5Z*#dzYmB<12&il#^W%6!;D8LCl{} z8RW$MMLP?F|n^8Ah(v#q#!Sz|29P`DH5aY zb-_SK18e?8UWWgQozO6-OzOa_G<&nBbe7laMnX&Oqc ztO&BX31m;9*qY;ak5N1Qm9d~}MbO1Rp`s+nVHMt%3Hr--k~!4AilFO#{298H;GDSs zjjRLItwj{=666dH<}3+v&M=?L$gJ(s;$_BDLA=$d>asM*yO(lX3nlx4pff28;(LNv zyl^L1x`}#=x-VxGb!-9U4U4a%T8#Lxb4l_X8WA*7lEDewpvs^RZ<4`C+GJH4_hi{o z5sZF}l%5_00}cdJ?zGJhj=wO-E+IviiQBU0kl&I)f7Ww*(A%gxE-UE43gi9@ zn=5JAF^Y0$W);SdlEHr0?Bd{rSkSpJI3XTuKQ0!G^l$Jf9e-hI(1Wb&e11@LP0;!N zphtO7R6)G8dyw;;pc`fJc(r5f0@J*lcq>=t|Ho$DM}k5U3F2qRv)?AIRMQXqn19%2 zb@pelNKx2+YCE-?+HBf8+NclW`-7smf7DL~fxmlmrKzpAziAaEb7lv5e%tM&e;=u) zVR?5@^gBkg39awWJ1Es2^N;v3GKngGeDmA1AH*uilmh=CH88eeRk6)FusO+Dvq|ic zpcs)N5+?GT$)ds0n-Z4?{i!8|#xH|r2Pagr2fK^=*jW)sKIPUI_}8;fxj+2e+o{?- z|HqrNpD&@TQ{w*j{X;=eM6rS(JG;oZl}8IT#QG=I!^i)M=uy+zxqj}>ptJv-E$!rv zm%U1g-?25Blk%y+~39yix*Pwb**GW-`|pbDCkR#=o){A?8&2n z*M}5ewUw>mQdHhSKeAKn<``>)u>7n%9A6M3aI=yV#%(Ol}^XbKjxr(XABL7{*1 zR`&2FI}iFBXWt(5`7jtojW6Xfkk3QX&PSc&bIr&spjjmTfT=pyZ>_kGt^Of(ustF? zfl(dApOyXc1=9(gX=><6<`!`;oz9xF&7tAitu*=P`Og@eDXULV#BS@ffNXnmO9iDK zCOc>z;$dAxQ>_0z+q_;dxqVe;lP^nW@=)b1XT%}yg8%Sig@x3;1wo(nLDzGFzW$~I zL7z6tT3r|npkdIbnc{5}y{*W5D*b+#4*V{35c|{ScB;wGrIAUKJ{@Y4wB5&3 zUS)Rjc~)5#qv~l~?5CZP#swc~sX?9TP(0)d6raQ8f;{g38;xludbf-dKW7z-)uH+So^0dP1R0HBegqbetPYpncSXZul>`Nrma1llP*X(X{mM6 zY}5S8pkI5yZjJbVURWYt5zm%FQnMU~`9&aOKd;q7;E$hWyIGc7D|BP5L zJWeM9lzrD08ILc~l*jW_4$YZnG|>p46Sts{^RxY-oU@BG@PPL7cN$*}s0@1YlxIdF zpV^G%Dmb#q43}JgCQp*l@pUwP;~c-Gx;LHQ!e09a2G=n<*irrIHl#H+-B=7Yp51Xz zhz#0L@N|sD17??r2>#<$AG4oMx5Em10*x%*51*$_zjJ#bO*maCmOaUw;L|A|9jQuq z6kV}3<0vwx{}@F#(xk`3$jos(PHv=mswn98g&?mj=vx_dn@NnXR9NgrjJD2v@(~LL z>P?T%_wXvX(j`TEf@jQ7A*-gX#@E5bYnM!-^#S#APdt5FWkVjXR!BSY89_$n4D<#U-&Y12^ud3!9khw}Iiamrfk|KWT^`%=1T zwZmY-M4e918BCu(t98(528bP=kvYoInA(NXRqbf}^r}-D;|Jm|7|->~PZ>O1^Q}cPeVs<=xpnKq}FhgS_4H)WoIw^=hALR9-NXGrD zr++gIyY6Kqv%=Jx>p#7PcN&a^v5~Pr$89=t%5gi>;rP@0B<1R8TQg~t&ZDZ+^>RvM zhaQom+cE3xAQbz{haJ>Z&PA&jBnof4`;=)3u$(tv$_^a?=u(HSE&o@qjaT|=kGC-mNUE@ z_1%J=bpB4G>x@Gr`9E7??d>$g{9n?X6JFvKyx_#oOT}||Dy91?l{EL$rGC89UM|!1 z7me%+dnNrguCH(0e1NZ%shuljTg%tdl)jMDmFAkxZ%kE7lP)#$M!IUEljPrQ&KefW z?v_29b~gW^7+aZh$?e(C)8*dbEwNSRMg`qaGN;!&%|+o4>B^RW~OZl63REwytGiqPjNGJfk_0 zpmbCHMwd>bJLbv6xpm1kGg=#Jl68#@EnZcXQ*2QpIlZ~LvDvF?S<~2@@mdmz zwR02e>6?axDYCw~E}1ZeS{qvGRyQQf3z)pBRb+Z|qNS>yz8|2JDO{zrY5e;xTLyf zZEI82%IX%Xr*YM)mIO6t)}s2x^$GIXsydQuOm)uU>Xx;}CbH1BW>K=au3@!T!_A~} z8*1xT*Rh6q)M3@NRxf`U(%`M!n56Gs*l*;2He|v$*0QEKN$+J_*VvX=+&DL}A!)0q zZK@rQA-961U81NG4XZ2gwnp z>#T!kEvjiqHrI3K)$ur-waEI5R43LoC22RPtKGo3rK!4x{De`))vv4GV4PglR9!pX z_|bYq>>4}9t7=PDudGj?8@U6x6&d!PdGpR;JF1(h_sqbYOKv=C?vmnZ6DJmzmy9hb zD;`r?HnDVk=_$p-7t*+&S)H_e)VPz1N3Bb?HY848ooGlj*VRz6y18b}>GXBos0rhW zN3Ev+t7}&lkD52OcocR2={2Nt)T;Tjrg_bcjpWaUChDA|88S`0lN(2w5o7kxS&K}* zXZIVkm-BniFdBI7I4hA{Xl4%Me$E`drg2?j^lBRG$M`k+1&Ti&Bqu2IBSQq=es%rki>5CUHt(vi9?zF|T=FP3D!qhgkwSKLc z+N!vHGT)gu?4@!@EzJzn-qxljYPfNYolI#o)9WzFuKLz>4Ia&O{N}>8>iSlmJ;+AW zMKnm-Os7?~Hng@RYN-&lm-Z4n??|1-2=A3dl$LIGtGrwR;e)eoy z34qtJ#PTY$SawE!!S<}SALP^X0plpSff)t!j%1@}iq%uf4{OVvze(7cLDf#8wJDrt(B<3F?W#!ZI zOQ+-yCmE8ZGE?)j&z8jsL|b%2E}$>E|NKcbhaWfP+-UI4!=dST^kG4A1AXnD(t}49 zxwIcyhsNskBkQN}@ABwL0^$d)i0Lk4+3X+GkJyJ$;3CnZEou`!4T7@0*le@I{SMjN zOeF9I0?77Kv(1Uf+edM8yva&_m&o(J<%XL~B8T2>)G^pczH_|dj@Y})q;tF#iho^r zf#UZISJ<;pj|bieok3~elZOSJyhkbCjYc%jSsbk2J?}+|>pD6Aj~V!T8F*LHn@-Qi zB+vEA!^GhmwevH`_aM&l`0<;W_ejUE4DzKJ_$1M@SEdv*50ajR8RVB`;B^_eIn>g1 zg>zCFJ@S=|9Y28%L1{C_m8Z`bH*um@GG|&Tf0XgZc>Wm6A7l8VoIfV;$2k5dGqB9$ zmsw&m%S_oaQ@G41Gipz95BX`YtInD;Z|ameRr6-dSTucc)#52r=S;7{^-AijR9&*+ zyhNW*5SP>Tsw(%4#gPk7+ft{19WKU5g}qpz&ZBTQ^#=#;Rv!C*|HOtz9L{q$_+K1; zvct#86I86H#Nj{6z@K%vt3O81fpK6xrSyk-hY9Cm{KzHvMUK2%Z>x+`$UjbHI9%dz zo(rMp3WxLT41SGp-jq4~BS)U?!M=KfOyOKFpNl}xSA=u1u@3*a!(IF7fhQASKl_@) z{lZxfpU*)5vyMDJ0t@~dN8YV>i99FEdd55QTZNbe2NAA-*NQ2{vXUj6kz9WoAgFI+|@t9;e2d_{?mlB{jUDij(mSd zzR{6){rQN)-F`ep4#ceA<;#S#{UgvA;<4(ab^bj*JYl{v&BOB zp9{zQ0r_H4jO!$D{9b_P77pN>*%=gMIE4Ib_#KAL4*79n;1IKeE;&~#Ec?k95 z`E8!7Ie>4Fd57mH4&eBmLb=5upDgoWh2m!lpR72&GuebQ6`vz~rsD9!9L1Aj=X}L0 zMbBcz&lmYh#aD>@`HI&HU!nLK;kAm_3tyvnlkj@Qlfs)6$I8}8#W#!m2F14t->mo! z;oB6yLii5FuNHoV;!WbWs};v{?mHFVA>;6R#oLA7toU`pcPkD(vKyEy$9$3DO`gR0 zin5UY?w0+rtKtbs<4OSXD~_`na@gcEb2Fwz+&f7kEH6I^Focf<9H8froL6D|ga1zS z&$i;B{JFvxDE=bvXcRC$p=X)&OO?$I^?XnGD#f3W^g6{K7Wrny9~FDHDLzs7rHWr7 z?cJq#o#?+!@#CdkUswEYk$+h6nbP4;D_$#lUQoPR?0Hl1`^ElG6#ue}6Ml(22lzQx zcu&RWN_w#37{{k8-dpTHQ}M4$`fSBd5wTuV+-Wly(D0c2q@-K`2`xL)J?0i)5 zTVW@5dE{H9QXxd=NA+oBJwy7g*@Nm;ILK6!_N;X4m%Gjj@6rSJ8-@`OL1|VH`n2O zK8$g4p2JxW&cl`~j`O+I!eI}__eG9;SJHz;INBY~`d^TKzf5r)zrW;gSI_khXFX?1 zf8DJ32;p}qUM2l%x<#4uVzQ`X|yj=KC9q#IR$>FRA zet%i@npO!nE^?#KsqEMmuUBa;zFzorg@L5X!HQ{p|?$&#*!@1s}xu#lgnc@S5*D8L2 zaI85Dd+-K^Hj#%PuwKSCM-SVxU;J>j!`YrIMgLC4FBN`^;y)37o8pIs-|29--g_O+ z^>&qs<9@|E34cWKD}_I<_@%<15)MCL{g0nH@@&sr;)kOSXM3I!J+CYNgz!H&+|~0J zhqInq`D*w>#mj~JGJesIhYF|=g-(ix>&!Zw>&5vQ_5;@A@==aF+f&SwE`>71-<6vO zrz+mgH#;d{|AU>YgwGOr_!;YaEXu%fp9Xra?q&7kJ{dUPFZ;y|dM?kv_Xvlc2Soo} zir+8%KE+=WzF+ZQ3V&4bnB188j^dw){P%@x|Gc2&hl!q-6dxk|h|=@8d>`hC z#~FBEb_@mhXO8F}p!jUz!xe86ezM|8;o}wGEqtQlUlBe@IQ#?q7b*GgiTt^WKOy{l zrRTJMww;ZNUgeyr2+6~$kbdU1Te0QJVN&O?)9P4+T>~L-u>>TfK_U9|ozY`Vz ziSS9n;fHU@e0sLxc$?>1hx4hnnD1Tea6Z+*etN6JSzZpO-n|ZIdAzmrzZ}l;1L=>$ z5r?xp*3o)HIL6gZ>8}qR&VIOU0BiBQj}_k~ypx=#pnpdd8*wjJ@u9+t6u&`uFU7AB z-rwQeU$AqS!`aRcM1F+ge-=JkIQk3s1tuvD|15L3bS>55c^5gH{fTwNE*1`d9ua?D z?QphpwRFr*#g_=b!QtFq=(*kDtY_RH`k-*9;)8_WtN16v?^pa!!XHumfx%Y)`guf>o{fqU`K5^vPpL^vxy1RS{ zhjBZ8nAP7~@iO5jINa59qQkjgE)w~Ximw$uPVpy%mn;65@M#V=<3a3Sl7TOGINQ_z zMBA>FioYlN*DBt9gq6oTK;WN`PO^NH$ivTA$8JXkeuvWk!bq#<9>sql9PbrDy|I(6 z{DVsV6On&R@e@V<3B`vBe^R)%|CdUBj>!L7@!7(EtMuF>#~r-&2KuqC-zQ2QydQTG z1+=$W^cO4MB>W`BcMBh-_*aDE{VLG^ec`7n`GdmG5U%ZCtmI!4`AWrqC;S4X=SOnf ztXKSaHjKhmisQ|qcPoxJi5^hAvs^zvDV){v{xUhv+CA?V4(Dk9Q3iXzR6JMsZyfIG zdClP*eM98&<{|j`Md9x%`Fl%jz3(f2kMNjW-$T#G!f6dN6TsgUUML*>g>?)2JMw1U z5I>YSoK3iBwADLC@pZyaQ~Y7!XDI%F@G~9m)_ab_yHJ&X68Qy+|6cfcil10&?Od+- zP~r8$wIA9XdA6ri?k8UEaJFZW==qZ3^MvnoxU1(DhqIn9i~MbhUn%_G70)fR?ZW*V z^lvBO-*)7=-X^jCsSNz54rhCoik{~cpCbHa#ZTdf3Mu>_#d`~XQ#kyLw+Q_u1MkL0 zQ$V{C{IDm59*Wlp?<-vEpP)F_4?fG`Jj6#B?Vh(-alzhdhqEj9N(QdaP%qXM-Qmdd zd0?r??{c{8S|;aihr9Y863%|$=t1enA35?_#Ia82&ol5pJ9@Z(uM)q#r}!1ZKUVx9 z;aPIsiGF!dc&_5V65d7e7lq@UgYX;dKS{}dBJ!gY|48^4;n33{*B4V1A1~>pisKE7 z7b=dIF>X^F>v3O|fqzvv{4;a{Ih(@0iVqh4km6?xe?;+F!oMRN?S(x*Rq{7w0g`PPMXFc&#=!3$1#s4mP&J_-SE|vRl8ytC#w#)hR4keG@r`+Sn zbG?^IyE|IPJgfNg!hfdtkA%PIaE`uX)p$o8&UV&Mv>C4} zzC!pP9L`ZZ_y1Sn==XzGjdxs;jliFHJ|DF;SQH6%BU)H zIO`dEs;yzX;-iI65)M1@Jixh1ex1lKQ+%!PgwiuyuHUyP`Rhf#UGeLLU#;{^7CrYU z`Nu^5>xw@r{98&-rRX`Nlyds1C8IC;b z$Go@D;jI5I(enkx?+{+4_+jBSia#y9Uh#K?H!1#S;jIp5JCD#Ghb<0gJA0jOu-C45 z58-$Z0sP$RTlt$r9{k5V*;BY%aXhc~fZ}+K+;*!&7 z`qLkW^-3PU)4auzXL}Axy|*d;i17OqKXH;#@9kH7fbfTf!w+~4^=FDd&H@yUDE^`F zKRWukT^Gqo?qGQ!2mZ%#WR!3&&V3T@M@s%9IsRU+_#0G)!ySspW!`&S@z+I9k6yMM z?CCCiu;R~%o-)NdOM99N+iC4_Ax-zpCVKnPTEs`v2yE!u_t?cc`=fH%o}i|=*8KM_C7Q}UZcezoGevaH@M ziqDjBb(P|HUi?PI@utnY6z?wj4=O%R?0iOX)cZTdJf4C7 zO7RWS-rr>4uPWYG#t*(ng`MDUEBTS)|G#A5_`N6e1R{^;1vJl<10wi`;?FJ__yHEA zz?;tWS19*&-RBlu{-iVCGCw5!>duqQUlsm0Xa8kBNZRS{7tE&%e?z`!fIS<8Un=*x z!FLPaF`5cf0M99~>D?LlZR2e|idS)n*8*{nFOqaRXyuk06INz2A{w2BpNlg)O!2C?QueRWBaR&w%6%%VRf zD`^3ylIBKEuy`3Q>QrKcEbEv@3n_?bO$#j*Cz7>^m949*>Kaxxl2Q||Ub(V4(bgfG z*KV_lMZ~O7Ky}+BQl@H)%<^%PO_q5jHI3_dML4gdp)r{#p;d@zRV-ew%&JYSp_RU> z*CoU${|}pDD$9L|aR615C8FQQBf}439`6R+6_Z0^Bdl{OWZb1DrT}W}%kL`3}?wIEyJB#_#^PaPt z@KgJ5GUcT6U%_Lx$U$is`;Yrb`|liL>Fi%I(3YQPH{mDB!~XN7yxhhM<@QVYZ6UD{ z*pF=^Vd!#2O9$ChFPWE-r)4jsjCAdP?z^_caGB4z{XD0^ewn7di-~ESTymzIXFiO1 zf*}PhduB5wl)8s2knQK=fVTg3V%jDyIsbD0Ox;JZ zsi^ENl##CfUhmlwrBaaV??QjN{(Z#K)xS;ZpNs;cN6Q|}Q2yY**#hs%b(R#5)WyR* zo&7V#e)Kcj&tnwkfImZwZ9+RKYQjTbwc9VMi4FE+`vQrjD_{0aTYi+?gr6vf?GegB zJQSkHaw+dJj%!(NCNn*MtU!5H0PSa89Nwb8bpBf*{@Y-rJdgdyU4ioOU%I-v$cp>< zlg(o*Mh0xdLIJh8l-7>5N3D2{#E&=O7*du#t#nz>LAmeJQGjzVaC~U zFZLWyd44wES@DiLF5s0J{cO|K*u+dv`?L@*OCD!8F|#-MSw@oH%8|{dYrdtOOx&t8 zWn-sxYU9EbV!Pj^&m2CpiJjJ;;|M&bd$EdKNOCflKR8s8wXf1PFSf*gC$=QD?49|Q zZajNC<=Lvnc1m&q3bEar$OAdNdSz^EFHp|OH`!x{$dgB$GKUl|HZIqd3#;ef{MM5) zsXi~Zn5*wDVzj(ZP0}%o%!&Fr8*7sc#~ZcJEJ#B zpV)g=;gX({d)+j(cZ~9K0vgKDo7MB%Q>m`w$2oNg%e}HaMrM^2a-qDd+GAc;uU%7V zUhGU69%qmnNmpp2lF-mn=PN!*58kDXim;I-^{C`6m z)A%%*9h6sh$8)?_c5;)co|Xw(aop+GBgqtz8G3mY<|R z2VGj$oZbyf)r9YfwQ>6bTkb1*p=XZmGfMb__~jJzb}o9=+}ZT1f~DsDTe0hdljARP z#>tV45jJB4zrUbEi9t4Fkj|hp2ztp!j$7%_SiCacC-q0>#9|$nO6SGxX|3rsb-Y%* zSs_2Vczvowhjpi^3^}5TUlp@F-!I?*&T&8d zhMZHW@XuS@+MK$k6idtxS0wG2^^dP%-MyoNP(PjSsW6w)W^H2OX6#VBlK#RoV#(vp zf(*PN1Lv{F`ip7H0s7ZdJe~e6#94kaZ8<>x5{jpjzmho1ub?dl$n(CCPCh(pgi|El zhOVzIDNW6g7L++tuq9)d*vZ0zu?%F|s7kwLu$_NWb1%g(tB1Ob+2Q!(3tWDT0Bc?j zwb|yvm+x3V z<|Fun0`zbh4&`udVFu21N7JwJ&P?7a6Wb7u*_~kdEDArsd$UDt4{GE z;Z2HH3*V}EtE9iAIKE5RsrW2O-|BGo4dfnhIN!iQzdo$EB)tO;=l;D}(m!-K>sc!4 zrxafz=^x9Mo5^DretFH|0mb<^%HeNz6Z#qBCN6&Be&Kel5V?L1XM1iCUaUC!eW=5^ zU68|fkF1~dydiq<3<3C2;aD?{IqSJXxVr`+>%m%uGo5;wqx?C-dBgreKdy5)`v?1g zyG9__o1i}qmpS^`Kc$9x9@e~rosGhGJMwJLMoI5g9OL;Ohr52;?{L=hV@W@x_#sI@ zsrW!{GzH|t&se+fu*ma% zUncTR893I+gPye_|3xJaewpIfudd3#zpOacuDmG&$NU8Utf2OBK;MC{vDkbE!BNcz zNH%6X)jQ#5r#W62oo`W9DW7Up4HwF6Z9q#Jq^D+*shdIs+F>gWtWXj`k zo85%%!u7}3GVuM1pDStk$}_B&`o?5P(1UsS zBsPKqIP_!QgC4ZE!jWf&c@Og|^cbb|k#OWWnk^Za#~=@mwN$}-iah2k*dy4x*3s|! z0rNNXz|Kb;d5%K=4;+rRave`A&ga)0Fu!qsqtBW19L@pt+El9lwf)G~^6&>Z>~!_J zcJ>lQ(2u-QhjUYkC5`iK=tsX#mVB*ers8Px3Wu})$&y~9__>m9ayZ)vJsT9qys^{a ztbc{1aXt(C*9+e(Ti6dhUsD{%g@X=f{RoF7qV+%LaQK+fi;6@4l@53Hf9!BqPqA>8 zb>-(f+?B6&ILjAHn!j-6z>MWl2L6Qp$&|+d{((ID<#C&B^l;t^N&np8tQ&s*9M9b0 zNxYKQhWfg-33`94`+VHzeVopDfbRdNXX-GH#l7Ktf;8W=;5leAfNZ}e9dJ<6J!#8h zH(S!ZWIIf_FKKMPjfmQ^4mX@k3D)^}%TJ)PtP}GmMNL5c*l)mf{biJquKjBYY>5?8 zklWAWQn!CLF|Ct}Jk1{z_VOTif|i|5dFkrMT8SH^VO&2y7oqF_0x_+VkhfMGitA)% z9JFj*8pd)Lu~8JThOMxd?_%m4<1+Jg3&vgCQ5Ysvdc{fS@Z*js2TJ{RcOIQCIssD%+;QIO8QrEwinASuG5o4XD^ydbwDT#LnAP@Cp`)$fdSH4Vc z4t~}%Z3m@1^kci+y}1aOM)nuN)Nbajkn%^IvK&SGfuEyDI{$4D{~Z)T_8;GSLV3)8 z+;&|z7n#h1jly%1$?`lG>GFIYspmdIUV+TNU*?1p;CCRtznZRm`2Z{NG6ZF-%l}_A Cl30!a literal 0 HcmV?d00001 diff --git a/ext/hiredis-0.14.1/lib/macos/libhiredis.a b/ext/hiredis-0.14.1/lib/macos/libhiredis.a new file mode 100644 index 0000000000000000000000000000000000000000..02bdb8808d71eb69804a59bf18a0bd1a867ce5bf GIT binary patch literal 532024 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%0Dg7;STBx$*+{+#U0)GRKs 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
j-cRb6oG3>X_?T?s(Yoj3eD~$nkqegWrWV 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